ViewModel到ViewModel通信

时间:2011-01-26 16:31:21

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

鉴于以下情况:

  1. ViewModelA启动ViewModelB(当然,通过一个通用的Controller,使用Ioc和DI来解析所需的类型)。
  2. ViewModelB需要在ViewModelA中设置属性值。
  3. 通过构造函数注入简单地将ViewModelA注入ViewModelB并直接设置属性是不是很糟糕?

    或者...

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

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

4 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

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

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

  • ViewModelA是父母,必须在B
  • 上显示某些属性的总和
  • ViewModelB是孩子,并且有一个需要求和的属性

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

ViewModelA可以订阅所有孩子的活动,但是沿着这条路走下去,我不喜欢它。添加和删​​除子项时,您需要完成大量的簿记。

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

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

我建议使用更轻松的专用Messaging解决方案,名为" Light Message Bus"。它不是任何另一个的一部分;-) MVVM框架,但是独立的组件。我在不到3分钟的时间内就立刻开始工作了。