MVVM-用户控件相互通信的理想方式是什么我正在使用MVVM。每个用户控件都有一个对应的VM。这些用户控件如何相互发送信息?我想避免在后面的xaml代码中编写任何代码。我特别感兴趣的是控件(在主用户控件内)如何相互通信以及如何与容器用户控件通信。编辑:我知道使用事件委托会帮助我解决这个问题。但是,我想避免在xaml代码隐藏中编写任何代码。通常,最好尝试减少小部件之间的通信量,因为每当两个用户控件相互“交谈”时,您就会在它们之间引入依赖关系。尽管如此,还有一些事情需要考虑:如果您真的需要更明确的沟通,有两种主要方法。实现两个元素共有的服务,并使用依赖注入在运行时提供实现。这允许控件与服务进行通信,从而使控件保持同步,但也将依赖性保持在最低限度。使用某种形式的消息在控件之间传递消息。许多MVVM框架都采用这种方法,因为它将发送消息与接收消息分离,并且再次将依赖性保持在最低限度。您的概念性问题在这里:每个用户控件都有相应的VM。每个视图都有一个单独的ViewModel几乎违背了ViewModel的概念。ViewModel不应与视图一对一,否则它们只不过是美化的代码隐藏。ViewModel捕获“当前UI状态”的概念——例如您所在的页面以及您是否正在编辑它——而不是“当前数据值”。要真正获得MV-VM的好处,请将您使用的ViewModel类的数量基于需要状态的不同项目。例如,如果您有一个项目列表,每个项目可以以3种状态显示,则每个项目都需要一个VM。相反,如果您有三个视图都基于通用设置以3种不同方式显示数据,则通用设置应该在单个VM中捕获。一旦您构建了ViewModels来反映手头任务的要求,您通常会发现在视图之间传递状态既不需要也不需要。如果有这样的需要,最好的办法是重新评估您的ViewModel设计,看看共享的ViewModel是否可以从少量额外的状态信息中获益。有时,应用程序的复杂性决定了对同一模型对象使用多个ViewModel。在这种情况下,ViewModel可以保留对公共状态对象的引用。对此有许多不同的机制,但您应该首先了解此通信属于架构的哪一层。MVVM框架的一个目的是能够在同一个视图模型上创建不同的视图。这些用户控件是仅在您当前正在实现的视图中相互通信,还是必须在其他可能的视图中相互通信?在后一种情况下,您希望在视图级别下的视图模型或模型本身中实现它。第一种情况的示例可能是您的应用程序在非常小的显示表面上运行。也许您的用户控件必须争夺视觉空间。如果用户单击一个用户控件将其最大化,则其他用户控件必须最小化。这与viewmodel无关,只是对技术的一种改编。或者,您可能有不同的视图模型和不同的用户控件,可以在不更改模型的情况下进行操作。这方面的一个例子可能是导航。您有一个事物列表和一个详细信息窗格,其中包含与列表中所选项目相关的字段和命令按钮。您可能希望对为哪些项目启用哪些按钮的逻辑进行单元测试。只有当您按下按钮命令或更改字段时,模型才会关注您正在查看的项目。这种交流的需要甚至可能在模型本身内。也许您已经更新了非规范化数据,因为其他数据已更改。然后,各种视图模型必须随着模型中的变化而变化。因此,总结一下:“这取决于……”我认为最好的解决方案是使用发布者/订阅者模式。每个控件注册一些事件并将删除操作附加到其他控件公开的事件。为了公开事件并附加到它们,您需要使用某种Mediator/EventBroker服务。我在这里找到了一个很好的例子在我看来,最好的方法是通过命令(路由命令/中继命令等)。我想避免在后面的xaml代码中编写任何代码。虽然这是一个值得称赞的目标,但您必须对此应用一些实用性,作为“您不应该”的规则,不应100%应用它。您可以使用元素绑定在UI上的元素之间进行通信,因此假设您创建的用户控件公开了一个属性,其他用户控件可以绑定到它。您可以配置绑定,使用依赖属性而不是基本属性/实现INotifyPropertyChanged但理论上可行,但确实需要一些预先考虑才能以这种方式进行通信。您可能会发现使用事件、代码和属性的组合比尝试纯粹的声明方式更容易,但这在理论上是可行的。您可以在控件和命令之间共享一些视图模型对象...例如,您有一些包含其他两个控件的主控件。并且您在主控件中有一些过滤功能,但您希望允许用户在第一个子控件中设置过滤器的某些部分(如“完整过滤器”),并在另一个子控件中设置过滤器的某些部分(如“快速过滤器”))。您还希望能够从任何子控件开始过滤。然后您可以使用这样的代码:FilterSettings;publicMainControlViewModel(){//...this.firstControlViewModel=newFirstControlViewModel(this.FilterSettings,this.FilterCommand);this.secondControlViewModel=newSecondControlViewModel(this.FilterSettings,this.FilterCommand);}}公共类FirstControlViewModel:ObservableObject{//...}publicclassSecondControlViewModel:ObservableObject{//...}在主控件XAML中,您将子控件DataContext绑定到适当的视图模型。每当子控件更改过滤器设置或执行命令时,都会通知其他子控件。正如其他人所说,您有几种选择。在大多数情况下,在用户控件上公开DepedencyProperties并绑定到这些属性提供了纯XAML解决方案,但可以引入一些UI依赖项,以便绑定相互看到另一个选项是在ViewModels消息传递模式之间发送消息的解耦。我希望您的用户控件绑定到他们自己的VM上的属性,然后在该VM内的属性更改时,它可以“发布”一条消息,通知其他“订阅者”发生了一些事情,他们可以根据需要响应消息React。如果有帮助,我有一篇关于该主题的博客文章:http://www.bradcunningham.net/2009/11/decoupled-viewmodel-messaging-part-1.html如果您使用严格的MVVM,则用户控件AView是一个View应该只与其ViewModel“交谈”,或者更确切地说,绑定到它。由于您的ViewModel很可能已经实现了INotifyPropertyChanged,只要它们相互引用,它们就可以使用PropertyChanged事件在属性更改时收到通知,或者它们可以调用方法(最好通过接口)以便与彼此。以上是C#学习教程:MVVM-用户控制相互通信的理想方式是什么?全部内容共享。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表侵权,如有侵权,请点击右边联系管理员删除。如需转载请注明出处:
