Проблема была в таком месте, что я никогда не ожидал ... Отладка API навигации приводит меня к RegionNavigationContentLoader
public object LoadContent(IRegion region, NavigationContext navigationContext)
Когда я шагнул дальше по коду, я заметил вызов:
protected virtual IEnumerable<object> GetCandidatesFromRegion(
IRegion region,
string candidateNavigationContract)
Я заметил, что наименование здесь является ключом к сопоставлению вида с моделью представления.
В моем примере имя для каждой части было:
public class SiteDetailsViewModel { ... } // ViewModel
public class SiteDetailsView { ... } // View
ViewNames.SiteView = "SiteView" // ViewName constant
Когда я случайно сделал следующее изменение:
ViewName.SiteView = "SiteDetailsView"
Все работает.
Заключение
Имя ViewModel должно начинаться
с тем же именем, которое вы использовали для
определите ваше мнение.
Я проверил это, изменив мой взгляд на:
public class MyView { ... }
и все еще используя то же имя представления для регистрации в контейнере и навигации:
_container.RegisterType<object, MyView>(ViewNames.SiteView);
...
_regionManager.RequestNavigate(RegionNames.DetailRegion,
ViewNames.SiteView + "?ID=" + site.ID);
Кажется, это тоже работает. Таким образом, кажется, что имя View-Model неразрывно связано с именем представления, используемым для перехода к этому представлению.
Примечание
Это только когда вы используете IoC и Unity с PRISM 4 Navigation API. Похоже, этого не происходит при использовании MEF.
Дальнейшее расследование
Мне также известно, что некоторые направляющие говорят нам использовать typeof(MyView).FullName
при регистрации представления с Контейнером ...
_container.RegisterType<object, MyView>(typeof(MyView).FullName);
Лично я считаю, что это ошибка. Используя полное имя представления, вы создаете зависимость между представлением и любым, кто хочет перейти к этому представлению ...
_regionManager.RequestNavigate(RegionNames.DetailRegion,
typeof(MyView).FullName + "?ID=" + site.ID);