如何在两个MVVM对之间进行通信
本文关键字:MVVM 之间 通信 两个 | 更新日期: 2023-09-27 18:26:47
我有一个小应用程序,它概述了一些项目(条目)。概述中列表中条目的标题是该条目的属性。当我点击一个条目时,应该会打开一种选项卡,我可以在其中编辑条目。当我编辑并保存条目时,概览选项卡应在下次更新。
为了更好地理解,这里有一个模型。
应用程序基于MVVM模式。每个视图都有一个作为DataContext的ViewModel。每个ViewModel都使用一个模型,每个模型都有一个数据库
概览选项卡有自己的视图、视图模型和模型(对)。还有选项卡。条目的每个选项卡都使用相同的对(singleton实例)。如果选择了其他选项卡,则只更新少数绑定。
我的问题是如何在选项卡之间进行通信
我有两种方法
- 中介器模式(引导程序将两个ViewModel与中介器组合在一起)
- 每个模型使用相同的数据库(模型听数据库,ViewModel听模型)
但是我对这些方法感觉不太好
我应该在模型之间通信还是在ViewModels之间通信或者这是错误的方式?
更新
我真的很感激你的回答。在我看来,他们都没有错或对。我认为这是一个品味问题,哪种解决方案是合适的。我真的很喜欢EventAggregator模式。这是Karl Shifflett关于PRISM中EventAggregator模式实现的一个很好的视频。但它也解释了这种模式本身。
@Thomas在我看来,在一个ViewModel中这样做是一个糟糕的解决方案。ViewModels必须分开。基于关注点分离的MVVM。
Mediator是朝着正确方向迈出的一步,但事件聚合器要灵活得多。您可以找到十几种实现。例如,Prism有一个现成的实现。
ViewModels之间进行通信。ViewModel在聚合器中注册自己的通知,并在聚合器上引发通知。
如果功能与格式化要显示的模型数据有关,则应在ViewModels之间进行通信。如果您正在将数据从一个模型通信到另一个模型,则在模型之间进行通信。
下面是一个具体的例子:可以在Visual Studio中使用NuGet权限访问的Microsoft.Practices.Prism
命名空间包括一个名为CompositePresentationEvent<T>
的类,以及一个执行实际通信的EventAggregator
类。
在整个应用程序通用的地方(我选择了App.xaml.vb,但它可以是任何公共范围的代码文件,它对C#和vb都很有效),您可以通过从该类继承并提供与您发送的数据相对应的类型T来定义事件。例如,如果您想要发送包含一个简单字符串的消息,那么声明:
Public Class MyEvent: Inherits CompositePresentationEvent(Of String) : End Class
在Application类中,您定义了一个事件聚合器:
Public Shared ReadOnly AppEventAggregator As IEventAggregator = New EventAggregator()
这两个项目一起为您提供了在应用程序中任意两个对象之间交换事件的方法。
这使您的整个应用程序都可以访问一个名为MyEvent
的事件。无论您想在哪里发送MyEvent
消息,都可以调用其共享的Publish(String)
方法:
Application.AppEventAggregator.GetEvent(Of MyEvent).Publish("This is my event message")
然后,为了接收事件,您在事件应该降落的类中实现了一个私有只读字段,类似于:
Private ReadOnly MyEventToken As SubscriptionToken =
Application.AppEventAggregator.GetEvent(Of MyEvent).Subscribe(Sub(eventMessage) DoSomethingWithTheString(EventMessage))
其中DoSomethingWithTheString(eventMessage As String)
将是您处理事件的地方。
当然,Prism还有(很多)功能,但永远不需要使用比您需要的更多的功能,而且,正如其他人所指出的,许多其他MVVM框架都有类似的方法来解决相同的问题。
对我来说,当我必须为视图模型之间的通信进行编程时,这通常是一个坏兆头。有时,您必须在视图和视图模型之间进行通信,但连接两个视图模型的需要似乎总是导致在可能的情况下组合两个视图模式。
有了你的模型,我也有同样的感觉。为什么首先要为选项卡创建单独的视图模型?在您的情况下,视图可以是分离的,但我认为分离视图模型没有任何好处。因此,我建议将这两个视图模型合并为一个视图模型。
也许这篇文章对你来说很有趣,它描述了基于类型的通信模式。它允许您在所有想要的东西之间进行通信,而不依赖于它们之间的