在ViewModel之间共享状态/更改

3
我有一个应用程序,其中有一个任务选项卡和一个项目选项卡。我决定为每个选项卡制作一个单独的ViewModel,即TasksViewModel和ProjectsViewModel。
任务选项卡具有带有关联项目下拉列表的新任务区域,而项目选项卡(显然)具有项目列表。
我希望在任务选项卡上的下拉列表与项目选项卡列表共享同一集合,以便每当我在项目选项卡上添加或删除项目时,任务选项卡上的列表会自动更新。这在单个ViewModel中效果很好,但开始变得相当混乱。
我是否不应该将其分成两个ViewModel?是否有一种常见的共享数据的方法?也许将相同的ObservableCollection<Project>传递到每个ViewModel中?也许是一些类似于ICollectionChanged的通知返回到TasksViewModel。
感谢任何见解/输入!
2个回答

5
这里最简单的解决方案通常是使用某种形式的消息传递服务在两个ViewModel之间传递信息。
例如,MVVM Light Toolkit 提供了一个 IMessenger接口 用于此类情况。
在这种情况下,使用良好的IoC或DI工具集也可以有所帮助。这将允许你动态地将项目集合注入到两个ViewModel中,从而允许在两个视图中使用共享集合。

我同意,但仅当数据确实是视图模型的一部分,而不是模型的一部分时。如果它实际上是模型的一部分,我会说在视图模型之间来回传递它是一个非常糟糕的想法:更好的方法是在整个应用程序中共享单个模型。我在我的答案中进一步解释了这一点。(是的,我确实意识到DI是实现共享公共模型的好方法,但我认为将其标识为此非常重要。) - Ray Burns
谢谢Reed,我喜欢这个消息传递的想法。我在WebformsMVP框架中使用过类似的功能。 - joshperry

3
在我看来,你对“任务”和“项目”的概念是属于模型的一部分,而不是视图模型的一部分。
考虑这个概念性的例子:假设你的应用程序是这样编写的,两个用户可以在两台独立的机器上使用你的应用程序连接到一个共享数据库,并且一个用户添加了一个项目:
1. 如果该项目立即出现在另一个用户屏幕上的任务标签下拉菜单中,这是好事还是坏事? 2. 如果第一个用户按下“保存”或“提交”或“确定”后,该项目出现在下拉菜单中,这是好事还是坏事?
如果这些问题的答案是“好事”,那么你的数据实际上是你的模型的一部分,而不是你的视图模型的一部分。因此应该将其作为模型对象处理。
你的视图模型应该通过引用整合你的实际模型,并尽可能地共享模型对象。事实上,理想情况下,大多数应用程序都有一个单独的模型对象集合。唯一的例外可能是对话框,你可能想要对其进行一些更改,但然后点击“取消”并不保存更改。在这种情况下,“确定”按钮会将来自对话框维护的模型数据复制到主应用程序模型中。在这种情况下,对话框和主应用程序使用的模型对象是同一类的不同实例。
现在考虑你回答了这两个问题的答案都是“坏事”的情况。这将是一个应用程序,你从来没有将“项目”列表保存回到主数据库/文档/任何其他地方,而它只是用于临时工作的瞬态列表。在这种情况下,它真正属于视图模型,并且我会将其附加到应用程序(或适当的范围)并使两个标签页访问它。

如果这些问题的答案是“是”,那么当问题是“是否好或坏?”时会感到困惑。哪一个是“是”,“好”还是“坏”? - JohnMetta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接