我尝试创建一些区域,在其中一个区域中,我有按钮"登录"它必然属于ICommand Login
属性。所以我想从shell订阅这个Login
。
我尝试了PubSubEvent
,但我还需要CanExecute
方法。
我发现的另一个解决方案是使用带静态命令的静态类。我认为这不是一个好的模式。
如何从模式角度做到这一点?
编辑1
要分配区域,我在shell的视图模型的约束中调用它:
regionManager.RegisterViewWithRegion("MainContent", typeof(LoginArea));
在视图中我使用了这个ViewModelLocator.AutoWireViewModel="True"
,所以我无法注入我的shell视图模型来订阅它的事件。
答案 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。