После небольшого исследования я не нашел ни одного метода, который бы возвращал базовый тип из URI.
Все, что делает URI - это указывает на ресурс, встроенный в определенную сборку, и я получил то, что мне нужно, извлекая ресурс вручную:
public static Type GetTypeFromUri(Uri uri)
{
Type type = null;
using (var stream = Application.GetResourceStream(uri).Stream)
using (var reader = new Baml2006Reader(stream))
{
while (reader.Read())
{
if (reader.Type != null)
{
type = reader.Type.UnderlyingType;
break;
}
}
}
return type;
}
Следующий код работает на нескольких предположениях:
- Для действия по созданию ресурса XAML задано значение Page (оно компилируется в BAML).

- Первый тип, найденный Baml2006Reader, - это тип Code-Behind (например, если класс не имеет типа Code-Behind, такого как ResourceDictionary, вы получите ResourceDictionary в качестве Типа). Я не очень хорошо знаком с тем, как устроен BAML, но несколько тестов показали, что это так.
Тесты показали, что читатель сначала анализирует включенные пространства имен, а затем тип кода с выделенным кодом, поэтому вызываются несколько итераций reader.Read()
(у которых есть reader.Type пустой, но reader.Namespace заполнен - который мы не нужно), а затем часть, которая нам нужна.
Если бы мы продолжали читать поток, он проходил бы по визуальному дереву и анализировал дочерние типы.
Так как Википедия говорит так:
Во время выполнения механизм платформы извлекает файл .BAML из ресурсов сборки, анализирует его и создает соответствующее визуальное дерево WPF или рабочий процесс.
Я считаю, что это правильный путь.
Если вы считаете, что это не самый эффективный способ или что-то должно быть сделано лучше, пожалуйста, дайте новый ответ.