【问题标题】:MVVM - Communication between Separated ViewsMVVM - 分离视图之间的通信
【发布时间】:2011-06-08 15:18:44
【问题描述】:

我正在尝试弄清楚如何执行以下操作:

我有一个CustomerListViewModel,其中包含一个ObservableCollection<Customer>

MainView 持有这些视图的一个实例:

  • CustomerListView - 创建CustomerListViewModel 的实例
  • SearchView - 创建SearchViewModel 的实例

我的问题是,如何将 CustomerListView 和 SearchView 分开。 只有在选择了客户时才应显示 SearchView。 SearchViewModel 的唯一依赖项应该是 Customer 模型。如果没有从 CustomerListViewModel 中选择客户,则不应显示 SearchView。

我是否应该引入一个新的 View/ViewModel,它同时包含 CustomerListViewModel 和 SearchViewModel,可以持有对选定 Customer 的引用并切换 SearchView 的显示?如果没有,我该怎么办?

我知道这个问题的范围很广,但如果有任何建议,我将不胜感激。

【问题讨论】:

  • 这就是我要做的。结合了两个或多个 ViewModel 的 ViewModel。复合 ViewModel 可以订阅事件并切换可见性。

标签: wpf mvvm


【解决方案1】:

不要让 MainView 包含 CustomerListView 和 SearchView 的实例。这三个应该是分开的。

就视图之间的通信而言,这应该通过各自的视图模型使用例如 mvvm-light messenger 来完成。如果您为每个视图注册不同的信使,那么您可以从视图模型向您想要的任何视图发送消息。

只是一个简单的使用 MVVMLight Messenger 的例子:-

查看:

Messenger.Default.Register<NotificationMessage>(this, OpenViewMessageReceived);

private void OpenViewMessageReceived(NotificationMessage msg)
{
    //Logic 
}

视图模型:

Messenger.Default.Send(new NotificationMessage(someStr));

【讨论】:

  • 您能否详细说明为什么不想将实例放在 MainView 中?
  • @Michael G,因为这会在这些视图之间产生强烈的耦合(这与 mvmm 模式相反)。此外,在视图中创建 vm 实例也不好,这应该在集中位置完成,例如viewmodellocator(mvvmlight 工具包)。您必须真正考虑使用 mvvmlight 工具包。我一直在处理一个相当复杂的应用程序,而该工具包确实让我的许多任务变得更简单了。
【解决方案2】:

实际上我最近写了一些关于here 的东西。您可能有兴趣查看它。

基本上,如果您可以从相对源绑定中访问您的值,这可能是最简单的方法

类似{Binding RelativeSource={RelativeSource AncestorType={x:Type local:MainView}}, Path=DataContext.CustomerListViewModel.SelectedCustomer}

或者实现一个消息系统,在 SelectedCustomer 发生变化时广播消息。 MVVM Light Toolkit 有一个非常简单的使用 Messenger 类,或者 Prism 有更高级的 EventAggregator。

【讨论】:

    【解决方案3】:

    这是一篇关于 MVVM 中视图之间通信的好文章:Communication Between Views in MVVM (Pub-Sub Pattern)

    【讨论】:

      【解决方案4】:

      如果不是为了“矫枉过正”,您可以查看PRISM

      这是使用 MVVM 和 MEF 的复合应用程序库的指南。这是一个非常简洁的库,但对于小型项目,它可能会过大。

      【讨论】:

      • 谢谢,我知道 PRISM;但是,我不确定 PRISM 将如何解决这个架构问题。你能指出我正确的方向吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-10
      • 1970-01-01
      • 2014-10-11
      • 1970-01-01
      • 2020-01-09
      • 1970-01-01
      • 2011-10-12
      相关资源
      最近更新 更多