ViewModel-to-ViewModel通信

时间:2013-04-08 19:40:20

标签: wpf data-binding mvvm

我正在处理由以下部分组成的应用程序区域:

  • 资源管理器 - 包含TreeView
  • PropertyInspector - 包含PropertyGrid
  • 编辑器 - 包含资源管理器和PropertyInspector

如您所见,零件以分层方式组织。我的问题是: 如何在资源管理器使用的树视图中选择属性检查器使用的属性网格的选定对象?

当树视图引发SelectedItemChanged事件时,命令将发送到ExplorerViewModel。 PropertyGrids SelectedObject绑定到PropertyInspectorViewModel上的属性。如何连接两个视图模型?一种方法可能是让EditorViewModel将PropertyInspectorViewModel上的方法附加到ExplorerViewModel在收到命令时引发的事件,但这是可行的方法还是可以通过数据绑定以某种方式解决?

编辑器不直接使用树视图和属性网格的原因是因为资源管理器和属性检查器以及所有撤消/重做功能,验证代码等都可以在其他区域中重用。

2 个答案:

答案 0 :(得分:0)

我强烈建议使用MVVM框架。我有类似的要求,决定采用Tony Sneed's Simple MVVM Toolkit。它非常轻量级,文档齐全且易于理解,提供了非常有用的功能,并且基本上必须为您提供MVVM管道。

在这种情况下,您需要使用消息总线功能:

“的 MessageBus

有时您需要在应用程序中的视图模型之间传递消息。一个很好的例子就是当你想根据一些业务逻辑导航到特定的视图时。直接从另一个视图模型引用主视图模型不是一个好主意。这样做会在难以维护的视图模型之间产生相互依赖关系(这种现象称为意大利面条代码)。这是消息总线(也称为事件调解器或聚合器)派上用场的地方。例如,CustomerViewModel可以使用特定令牌向消息总线发送消息,并且只要有人将具有该相同令牌的消息发送到消息总线,MainPageViewModel就可以订阅接收消息。消息标记只是字符串,可以在类中定义为常量。From the Programming Reference page

除此之外,我还使用Josh Smith's RelayCommand来简化ICommand通知,因为@eran otzap建议

答案 1 :(得分:0)

编辑器VM应协调两个子VM。

将一个选定的项目属性添加到资源管理器VM(如果它已经存在),并确保它触发属性更改通知。

属性检查器VM应具有类似的属性,该属性是显示属性的项目。

然后,编辑器会监视资源管理器VM的所选项目属性以进行更改,并在更改时将新项目传递给属性检查器VM。

此处无需涉及消息总线。消息总线用于松散耦合的ViewModel,以便相互传递消息。例如,已打开文件的应用程序范围通知。

如果你在这里使用了消息总线,那么任何VM的重用也会触发消息,这不是你想要的。