从地区到贝壳的棱镜ICommand

时间:2016-12-15 08:59:27

标签: c# design-patterns prism

我尝试创建一些区域,在其中一个区域中,我有按钮"登录"它必然属于ICommand Login属性。所以我想从shell订阅这个Login

我尝试了PubSubEvent,但我还需要CanExecute方法。

我发现的另一个解决方案是使用带静态命令的静态类。我认为这不是一个好的模式。

如何从模式角度做到这一点?

编辑1

要分配区域,我在shell的视图模型的约束中调用它:

regionManager.RegisterViewWithRegion("MainContent", typeof(LoginArea));

在视图中我使用了这个ViewModelLocator.AutoWireViewModel="True",所以我无法注入我的shell视图模型来订阅它的事件。

1 个答案:

答案 0 :(得分:1)

您可以使用事件聚合器以分离的方式在不同模块之间进行通信。 GitHub上有一个例子:https://github.com/PrismLibrary/Prism-Samples-Wpf/blob/master/EventAggregation/Desktop/ModuleA/AddFundPresenter.cs。如果您想了解事件聚合器模式的基础知识以及它在Prism中的应用方式,您可以参考以下博文:https://blog.magnusmontin.net/2014/02/28/using-the-event-aggregator-pattern-to-communicate-between-view-models/

另一种选择是使用共享服务:https://social.msdn.microsoft.com/Forums/en-US/22907a0f-d805-4195-8272-7c284b72d2ee/example-of-using-shared-services-prism?forum=wpf。共享服务只是一个以分离方式为多个模块提供功能的类。它应该实现一个接口,并在引导程序中将其注册到容器,通常作为单例。

  

在视图中我使用此ViewModelLocator.AutoWireViewModel =“True”,因此我无法注入我的shell视图模型来订阅事件。

好吧,如果您不希望shell的视图模型注入任何依赖项,那么您将不得不使用某种静态类来获取对EventAggregator或共享服务的引用。有一个示例说明如何从这里提供的静态类公开EventAggregator:https://rachel53461.wordpress.com/2011/10/09/simplifying-prisms-eventaggregator/

但是你可以通过覆盖Bootstrapper的InitializeShell()方法轻松地为shell窗口注入你需要的任何依赖项,例如:

class Bootstrapper : UnityBootstrapper
{
    protected override DependencyObject CreateShell()
    {
        return Container.Resolve<MainWindow>();
    }

    protected override void InitializeShell()
    {
        RegisterTypeIfMissing(typeof(IEventAggregator), typeof(EventAggregator), true);
        Application.Current.MainWindow.DataContext = new MainWindowViewModel(Container.Resolve<IEventAggregator>());
        Application.Current.MainWindow.Show();
    }
}

ViewModelLocator.AutoWireViewModel属性无论如何都要用于UserControl视图:

ViewModelLocator.AutoWireViewModel - No DataContext for MainWindow

但是,谈到模式,您应该考虑将shell视图模型类移动到模块,并将shell窗口保持为由子视图组成的真实shell。