棱镜4:RequestNavigate()不起作用

时间:2011-02-26 17:52:05

标签: c# prism prism-4

我正在构建一个演示应用程序来学习Prism 4的导航功能。该应用程序有两个模块 - 每个模块有三个视图:

  • 带有文本块的UserControl(“欢迎使用模块A”)
  • RibbonTab(使用区域适配器)和
  • Outlook样式的任务按钮(如Outlook的邮件,日历等)

Shell有三个命名区域:“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());
}

当用户单击任务按钮时,它会调用一个调用IRegionManager.RequestNavigate()的ICommand对象来显示视图:

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 个答案:

答案 0 :(得分:28)

最后想出了这个。答案在 Microsoft Prism开发人员指南(Ver 4),第120-121页。它有两部分:

首先,UserControlRibbonTab对象以System.Object类型从Unity解析。这是Unity的限制和我用来注册视图对象的重载。要让他们解析为正确的类型,您需要为IUnityContainer.RegisterType()使用不同的重载:

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

此重载会将Unity的本机System.Object分辨率映射到所请求视图的正确类型。请参阅第4页的说明。 开发人员指南中的120个。

第二个问题没有在我的问题中明确说明,但是当我修复第一个问题时就出现了问题。我希望在切换到其他模块时删除每个模块的RibbonTab。由于我的Ribbon区域的行为类似于ItemsControl,所以RibbonTabs最终都显示出来了 - 当我切换到模块B时,模块A的RibbonTab没有被卸载。为了解决这个问题,我实施了IRegionMemberLifetime课程RibbonTab。该问题在第4页中介绍。 开发人员指南中的121个。

顺便说一句,我在View对象而不是View Models上实现了IRegionMemberLifetime接口,因为该接口不会影响应用程序的后端,只影响视图对象。