2

我有一个小应用程序,其中概述了一些项目(条目)。概览列表中的条目标题是条目的属性。当我单击一个条目时,应该会打开一种选项卡,我可以在其中编辑该条目。当我编辑并保存条目时,概述选项卡应在下次更新。

是一个模型以便更好地理解。

应用程序基于 MVVM 模式。每个 View 都有一个 ViewModel 作为 DataContext。每个 ViewModel 使用一个 Model并且每个 Model 都有一个Database
概览选项卡有它自己的视图、视图模型和模型(对)。还有标签。条目的每个选项卡都使用相同的对(单例实例)。如果选择了其他选项卡,则仅更新少数绑定。

我的问题是如何在选项卡之间进行通信。

我有两种方法

  • 中介者模式(Bootstrapper 结合了两个 ViewModel 和一个中介者)
  • 每个模型使用相同的数据库(模型监听数据库,视图模型监听模型)

但我对这些方法感觉不太好。
我应该在模型之间还是视图模型之间进行通信?或者这是错误的方式?

更新

我非常感谢您的所有回答。在我看来,它们都没有错或对。我认为哪种解决方案适合一个人是一个品味问题。我真的很喜欢 EventAggregator 模式。Karl Shifflett关于在PRISM中实现EventAggregator 模式的精彩视频。但它也解释了模式本身。

@Thomas 在我看来,在一个 ViewModel 中执行此操作是一个糟糕的解决方案。ViewModel 必须分开。基于关注点分离的MVVM 。

4

4 回答 4

2

如果功能与格式化模型数据以供显示有关,您应该在 ViewModel 之间进行通信。如果您将数据从一个模型传递到另一个模型,则在模型之间进行通信。

下面是一个具体示例:Microsoft.Practices.Prism您可以在 Visual Studio 中使用 NuGet 访问的命名空间包括一个名为 的类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 框架具有类似的方法来解决相同的问题。

于 2013-08-06T21:17:35.670 回答
2

调解器是朝着正确方向迈出的一步,但事件聚合器要灵活得多。你可以找到几十个实现。例如,Prism 有一个现成的实现。

通信是在 ViewModel 之间进行的。ViewModels 在聚合器中注册自己的通知并在聚合器上发出通知。

于 2013-08-06T20:02:55.350 回答
2

对我来说,当我必须为视图模型之间的通信进行编程时,这通常是一个不好的迹象。有时,您必须在视图和视图模型之间进行通信,但连接两个视图模型的需求似乎总是导致尽可能组合两个视图模型。

有了你的模型,我也有同样的不好的感觉。为什么您必须首先为选项卡设置单独的视图模型?在您的情况下,视图可以是分开的,但我认为分离视图模型没有任何好处。因此,我建议将两种视图模型合二为一。

于 2013-08-06T22:35:14.363 回答
1

也许这篇文章对你来说很有趣,它描述了一种基于类型的通信模式。它使您可以在所需的一切之间进行通信,而无需它们之间的依赖

于 2013-08-06T20:32:41.293 回答