在Prism(CAL)中,我如何使用RegisterPresenterWithRegion而不是RegisterViewWithRegion

时间:2009-09-04 15:34:44

标签: mvvm prism composite mvp

我在Prism应用程序中有一个模块,在初始化方法中,我想用区域注册一个演示者而不是一个视图,即我想这样做:

伪码:

regionManager.RegisterPresenterWithRegion(
        "MainRegion", typeof(Presenters.EditCustomerPresenter));

而不是加载这样的视图:

regionManager.RegisterViewWithRegion(
        "MainRegion", typeof(Views.EditCustomerView));

演示者当然会带来自己的视图并最终在该区域中注册此视图,但它允许我将演示者绑定到演示者的构造函数中的视图,而不是在XAML中将两者绑定在一起(这是更多我想在这里避免的解耦MVVM模式。)

如何将Presenter添加到区域而不是视图?

namespace Client.Modules.CustomerModule
{
    [Module(ModuleName = "CustomerModule")]
    public class CustomerModule : IModule
    {
        private readonly IRegionManager regionManager;

        public CustomerModule(IRegionManager regionManager)
        {
            this.regionManager = regionManager;
        }


        public void Initialize()
        {
            regionManager.RegisterViewWithRegion("MainRegion", typeof(Views.EditCustomerView));
        }
    }
}

4 个答案:

答案 0 :(得分:2)

我认为您的演示者应该负责在激活时将它们插入到区域中。我通常会为我的演示者创建一个IViewRegistry,以避免他们知道区域名称并让他们的演示者使用它来显示视图。

public class MyViewPresenter : IPresenter
{
     IViewRegistry _viewReg;
     IUnityContainer _container;
     public MyViewPresenter(IViewRegistry viewRegistry, IUnityContainer container)
     {
          _viewReg = viewRegistry;
          _container = container;
     }

     void IPresenter.Present()
     {
          MyView view = _container.Resolve<MyView>();
          MyViewViewModel vm = _container.Resolve<MyViewViewModel>();
          view.DataContext = vm;

          _viewReg.ShowInMainRegion(view);
     }

}

当然,ShowInMainRegion的实现将是您已经拥有的区域注册码。

public void ShowInMainRegion(object view)
{
     regionManager.RegisterViewWithRegion(
        "MainRegion", view);
}

有可能你可以做一些更像你想要的东西(可能是一个检测IViewFactory的区域适配器),但它可能不实用。

希望这有帮助, 安德森

答案 1 :(得分:1)

我对Prism还是很陌生,但据我所知,这没有意义:区域设计用于保存视图,不是它们。这就是他们存在的全部。您希望从您的区域获得您的演示者可以使用的内容吗?

鉴于您的Presenter了解您的所有视图,您是否可以在RegisterViewWithRegion调用中使用Presenter:

regionManager.RegisterViewWithRegion(
    "MainRegion", typeof(Presenters.EditCustomerPresenter.View));

答案 2 :(得分:1)

您可以尝试使用RegisterViewWithRegion重载来获取委托而不是视图类型。

例如:

regionManager.RegisterViewWithRegion(RegionNames.APPLICATION_MANAGEMENT_REGION, OnGetManagementView);

public object OnGetManagementView()
{
     return m_managementViewModel.View;
}

这将允许您拥有自己的自定义逻辑来创建视图/视图模型(也称为演示者)。找到命名区域时将调用回调。

答案 3 :(得分:0)

我的方法是通过传递已解析的演示者的View属性来向区域注册视图

this.regionManager.RegisterViewWithRegion(
    FoundationToolkitRegionNames.RIBBON_REGION, 
    () => this.container.Resolve<SetupRibbonTabPresenter>().View);

我的演示者构造函数看起来像这样:

public SetupRibbonTabPresenter(ISetupRibbonTabView view)
{
    this.view = view;
}

视图和演示者以前都已在容器中注册。