Подтвердить что ты не робот

Призма 4: RequestNavigate() не работает

Я создаю демонстрационное приложение, чтобы изучить навигационные функции Prism 4. Приложение имеет два модуля: каждый из них имеет три вида:

  • Пользовательский элемент управления с текстовым блоком ( "Добро пожаловать в модуль А" )
  • A RibbonTab (с использованием адаптера области) и
  • Кнопка задачи в стиле Outlook (например, Outlook Mail, Календарь и т.д.)

Оболочка имеет три именованные области: "RibbonRegion", "TaskButtonRegion" и "WorkspaceRegion". Представления загружаются в эти регионы. Чтобы проверить базовую настройку, я зарегистрировал все три представления с помощью диспетчера областей Prism, чтобы они загружались при запуске, и все работало так, как ожидалось.

Затем я изменил настройку так, чтобы при запуске загружались только кнопки задач. Другие виды загружались только по запросу, нажав кнопку "Задача" . Мои инициализаторы модулей выглядят следующим образом:

public void Initialize()
{
    /* We register the Task Button with the Prism Task Button Region because we want it
     * to be displayed immediately when the module is loaded, and for the lifetime of
     * the application. */

    // Register Task Button with Prism Region
    m_RegionManager.RegisterViewWithRegion("TaskButtonRegion", typeof(ModuleATaskButton));

    /* We register these objects with the Unity container because we don't want them
     * instantiated until we navigate to this module. */ 

    // Register View and Ribbon Tab as singletons with Unity container
    m_Container.RegisterType(typeof(ModuleAView), "ModuleAView", new ContainerControlledLifetimeManager());
    m_Container.RegisterType(typeof(ModuleARibbonTab), "ModuleARibbonTab", new ContainerControlledLifetimeManager());
}

Когда пользователь нажимает кнопку "Задача" , он вызывает объект ICommand, который вызывает IRegionManager.RequestNavigate() для отображения представлений:

public void Execute(object parameter)
{
    // Initialize
    var regionManager = m_ViewModel.RegionManager;

    // Show Ribbon Tab
    var moduleARibbonTab = new Uri("ModuleARibbonTab", UriKind.Relative);
    regionManager.RequestNavigate("RibbonRegion", moduleARibbonTab);

    // Show View
    var moduleAView = new Uri("ModuleAView", UriKind.Relative);
    regionManager.RequestNavigate("WorkspaceRegion", moduleAView);
}

Эта команда вызывается при нажатии кнопки "Задача" , но я получаю следующее:

Demo app screen shot

UserControl, по-видимому, загружается как System.Object, и я подозреваю, что RibbonTab загружает то же самое. Я думаю, что проблема связана с моим вызовом RequestNavigate() или моей регистрацией в Unity. Но я не могу определить проблему.

Может ли кто-нибудь пролить свет на то, что происходит? Благодарим за помощь.

4b9b3361

Ответ 1

Наконец, выдумал это. Ответ приведен в Руководстве разработчика по Microsoft Prism (Ver 4), стр. 120-121. Он состоит из двух частей:

Сначала объекты UserControl и RibbonTab решались из Unity как System.Object. Это ограничение Unity и перегрузка, которую я использовал для регистрации объектов view. Чтобы заставить их разрешать правильные типы, вам нужно использовать другую перегрузку для IUnityContainer.RegisterType():

// Register other view objects with DI Container (Unity)
m_Container.RegisterType<Object, ModuleAView>("ModuleAView");
m_Container.RegisterType<Object, ModuleARibbonTab>("ModuleARibbonTab");

Эта перегрузка отображает разрешение Unity native System.Object на правильный тип для запрошенного представления. См. Примечание на стр. 120 Руководства разработчика.

Вторая проблема не была явно указана в моем вопросе, но это произошло, когда я исправил первую проблему. Я хотел, чтобы каждый модуль RibbonTab удалялся, когда я переключался на другой модуль. Так как моя область ленты действует как ItemsControl, то оба RibbonTabs оказались показаны - модуль A RibbonTab не был выгружен, когда я переключился на модуль B. Чтобы решить эту проблему, я внедрил IRegionMemberLifetime в RibbonTab. Эта проблема освещена на стр. 121 Руководства разработчика.

Кстати, я реализовал интерфейс IRegionMemberLifetime в объектах View, а не в их моделях просмотра, потому что интерфейс не влияет на конец приложения, а только на объект вида.