MVVM - 用户控制相互通信的理想方式是什么

San*_*box 14 c# wpf user-controls mvvm

我有一个用户控件,其中包含其他几个用户控件.我正在使用MVVM.每个用户控件都有一个相应的VM.这些用户控件如何相互发送信息?我想避免在后面的xaml代码中编写任何代码.特别是我对控件(主用户控件内部)如何相互通信以及如何与容器用户控件进行通信感兴趣.

编辑:我知道使用事件代表将帮助我解决这个问题.但是,我想避免在xaml代码隐藏中编写任何代码.

Ree*_*sey 14

通常,最好尝试减少部件之间的通信量,因为每次两个用户控件彼此"对话"时,您就会在它们之间引入依赖关系.

话虽如此,有几件事需要考虑:

  • UserControls可以通过公开属性和使用DataBinding始终与其包含的控件"对话".这非常好,因为它在所有方面都保留了MVVM风格.
  • 包含控件可以使用属性将两个用户控件上的两个属性"链接"在一起,同样保留干净的边界

如果您确实需要更明确的沟通,有两种主要方法.

  1. 实现两个元素共有的服务,并使用依赖注入在运行时提供实现.这使得控件可以与服务进行通信,从而可以使控件保持同步,但也可以将依赖性保持在最低限度.
  2. 使用某种形式的消息传递在控件之间传递消息.许多MVVM框架采用这种方法,因为它将发送消息与接收消息分离,同样,将依赖性保持在最低限度.

  • 对于第2点:Josh Smith的MvvmFoundation有一个'Messenger'类,它使用Register/Notify机制在VM之间传递消息.它们存储为弱引用以避免内存泄漏,并且工作得非常好! (3认同)

Ray*_*rns 8

你的概念问题在这里:

每个用户控件都有一个相应的VM.

为每个视图设置一个单独的ViewModel几乎违背了ViewModel的概念.ViewModels不应该与视图一对一,否则它们只不过是美化的代码隐藏.

ViewModel捕获"当前用户界面状态"的概念 - 例如您所在的页面以及是否正在编辑 - 而不是"当前数据值".

要真正获得MV-VM的好处,请根据需要状态的不同项来确定所使用的ViewModel类的数量.例如,如果您有一个项目列表,每个项目都可以在3种状态下显示,则每个项目需要一个VM.相反,如果您有三个视图,所有视图都根据常见设置以3种不同方式显示数据,则应在单个VM中捕获常用设置.

一旦您构建了ViewModel以反映手头任务的要求,您通常会发现不需要也不希望在视图之间传递状态.如果有这样的需求,最好的办法是重新评估您的ViewModel设计,看看共享的ViewModel是否可以从少量额外的状态信息中受益.

有时,应用程序的复杂性决定了对同一个模型对象使用多个ViewModel.在这种情况下,ViewModel可以保持对公共状态对象的引用.


Pan*_*nek 1

我认为最好的解决方案是使用发布者/订阅者模式。每个控件注册一些事件并将委托附加到其他控件公开的事件。

为了公开事件并附加到它们,您需要使用某种 Mediator/EventBroker 服务。我在这里找到了一个很好的例子