Prism 4: RequestNavigate () не работает - PullRequest
19 голосов
/ 26 февраля 2011

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

  • UserControl с текстовым блоком («Добро пожаловать в модуль A»)
  • RibbonTab (с использованием адаптера региона) и
  • Кнопка задач в стиле Outlook (например, почта, календарь и т. Д.)

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

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

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. Но я не могу определить проблему.

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

1 Ответ

28 голосов
/ 01 марта 2011

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

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

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

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

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

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

...