【问题标题】:ViewModel to ViewModel CommunicationViewModel 到 ViewModel 的通信
【发布时间】:2011-01-26 16:31:21
【问题描述】:

鉴于以下情况:

  1. ViewModelA 启动 ViewModelB(当然,通过一个通用控制器,它使用 Ioc 和 DI 来解析所需的类型)。
  2. ViewModelB 需要在 ViewModelA 中设置一个属性值。

简单地通过构造函数注入将 ViewModelA 注入 ViewModelB 并直接设置属性是不是很糟糕?

或者……

是否应该使用像 Prism 的 EventAggregator 这样的消息系统来处理 ViewModel 之间的所有通信?

我喜欢注射方法,因为它很简单,但我的直觉告诉我我错过了一些东西。我呼吁你们的集体智慧来帮助填补我的盲点。

【问题讨论】:

    标签: mvvm dependency-injection inversion-of-control viewmodel eventaggregator


    【解决方案1】:

    如果您需要双向引用,我认为这是一种代码异味。通常您可以将其中一个引用替换为事件

    让 ViewModelB 引发 ViewModelA 订阅的事件。像在 Prism 中找到的那样完整的消息传递系统当然是一种选择,但在您的场景中,它听起来像一个“正常”事件就可以了。

    【讨论】:

    • 我同意,在最简单的情况下,事件选项是要走的路。但是,我的应用程序很大。所以我最终选择了消息传递解决方案,因为整个应用程序的其他地方都不可避免地需要消息传递。
    【解决方案2】:

    我建议您阅读this question (and my answer),因为它很相似,但不完全是您的问题。它确实处理父/子 ViewModel 对象之间的属性通信。

    让我们看一个基本的例子:

    • ViewModelA 是父级,必须提供 B 上某些属性的总和
    • ViewModelB 是孩子,有一个需要求和的属性

    所以用户请求编辑 B 上的属性并且请求成功,所以 B 可能会更改其属性的值并触发 PropertyChanged 事件。

    ViewModelA 可以订阅所有孩子的事件,但是走这条路,我不喜欢它。当添加和删除孩子时,您需要做大量的簿记工作。

    将 A 注入 B 更简洁,但您仍然需要做很多簿记工作。如果您对 A 执行“清除儿童”操作怎么办?您必须记住在所有情况下都正确摆脱从 B 到 A 的父关系。在我看来,它仍然比事件更好,因为它更明确。

    我个人喜欢消息传递的想法。我比 Prism 更熟悉 MVVM Light 的信使,但它的想法是一样的……全局消息总线。在任何时候,任何 B 都可以说“我改变了我的财产!”然后 A 监听通知并自己进行计算。我认为这是您最干净的解决方案,而且簿记要少得多。

    【讨论】:

    • 我最终创建了一个 MessagingService,它包装了 EventAggregator 的发布/订阅/取消订阅操作。 MessagingService 被注入到我正在使用的 ViewModelBase 类中,因此我的应用程序中的任何 ViewModel 都可以使用它。
    • @Chris Swain - 我喜欢。如果我必须让 ViewModel 与 ViewModel 通信,这就是我将来会采用的方法。然而,在我最近的工作中,我通过强制通过模型进行所有通信来避免所有这种情况。当模型中发生任何变化时,我的 Presenter 会知道并告诉顶层 ViewModel 可能发生了变化。然后它向下传递一个通知树和所有子、孙等,ViewModels 检查他们的模型数据,看看是否有任何变化。
    【解决方案3】:

    我建议使用更轻量级的专用Messaging 解决方案,称为“Light Message Bus”。它不是任何另一个 ;-) MVVM 框架的一部分,而是独立的组件。我在不到 3 分钟的时间内就让它工作了。

    【讨论】:

      【解决方案4】:

      您可能会发现 WPF Application Framework (WAF) 的示例应用程序很有用。 ViewModel 彼此不了解。他们之间的调解由Controllers完成。这样可以防止 ViewModel 对象之间的循环依赖。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-14
        • 1970-01-01
        • 1970-01-01
        • 2017-03-14
        • 1970-01-01
        • 2015-07-11
        相关资源
        最近更新 更多