4

我正在开发一个 WPF 应用程序,并且正在使用 Model-View-ViewModel 模式。

该应用程序目前由两个模块组成:

  • 左面板浏览树并选择一个节点
  • 主面板显示所选树节点的内容。

我想将这两个模块分开,但是当我在左侧面板中选择一个节点时,我需要触发一个主面板可以订阅的事件。我不想耦合左面板和主面板,所以我不想共享 ViewModel 类的实例。

理想情况下,我很想使用 Prism(WPF 复合应用程序指南),但我目前正在扩展现有应用程序,无法引入更多依赖项。该项目也在 .NET 3.0(不是 3.5)上,所以我必须将 Prism 转换回 .NET 3.0,因为它是为 .NET 3.5 编写的。

在 Prism 中,我会使用松耦合事件基础设施来解决这个问题。它允许您在任何层中的任何类中触发事件,并在任何层中的任何类中侦听任何事件。基本上,事件的发布者和订阅者是分离的。

我使用命令来实现我的视图和我的视图模型之间的这种松散耦合,但我不确定如何进行正确的跨视图通信。

非常感谢任何提示或建议。

我正在专门为 .NET 2.0/3.0(没有 LINQ 的东西)寻找一个真正轻量级的 pub/sub 事件模型,或者在不耦合两个模块的情况下实现跨视图(模块)通信的其他东西。

更新:我最终以与 Glen 建议的方式类似的方式解决了这个问题。我有一个单独的 EventService(我称之为 CommandProxy),并通过我的服务定位器中的构造函数将它传递给每个 ViewModel(目前我使用的是服务定位器而不是 IoC 容器)。CommandProxy 公开了一组 MultiDelegateCommants,它是 Prism(复合 WPF 指导)中 DelegateCommand 的扩展。它基本上允许从可视树中分离出来的命令,并且支持多个订阅者。

4

1 回答 1

7

你有 IoC 容器吗?一种简单的方法是创建一个触发事件的自定义服务。事件聚合器是通用的,但您可以创建一个特定的服务来满足您的需求。

例如,创建一个具有 OnNodeSelected 方法的 EventingService。该方法会触发一个 NodeSelected 事件,该事件会挂起服务。然后在您的 IoC 容器中注册该服务,允许发布者和订阅者访问它。这样,如果说您的 MainPanel 需要订阅,那么您的 MainPanelViewModel 将在其构造函数中注入 EventingServiec。然后它将订阅。如果您使用 WPF,另一种方法是从复合应用程序库代码中提取 CompositeCommand,并让事件服务公开一个 CompositeCommand。然后每个订阅者(视图模型)向服务注册他们的命令。当 OnNodeSelected 被调用时,CompositeCommand 的执行被调用,从而通知所有相关方。

我们在位于 www.microsoft.com/compositewpf 的复合应用程序指南文档中讨论了为此使用您自己的服务,该文档位于通信主题的松散耦合事件部分。(http://msdn.microsoft.com/en-us/library/cc707836.aspx)。Francis Cheung 对此也有帖子。

于 2008-10-22T17:30:35.220 回答