3

在我的应用程序中,我有几个 ViewModel 有一个服务(存储库、DAO 等),我们称它为WidgetService 并注入它们。

假设这些 ViewModel 之一是所有用户小部件的列表。另一个可能是用于编辑/创建其中一个小部件的 ViewModel。

用户可以在WidgetListViewModel支持的WidgetListView中查看小部件列表,然后单击按钮添加新小部件。为了创建这个新的 Widget,创建一个CreateWidgetViewModel并注入到一些 UserControl/Window 的 DataContext 中,因此,通过 DataTemplates 在 CreateWidgetView 中显示CreateWidgetViewModel魔力。此外,CreateWidgetViewModel的更新不一定发生在WidgetListViewModel的范围内。

WidgetListViewModel被注入 WidgetService 的实例CreateWidgetViewModel被注入了同一个WidgetService实例。

现在,当用户在CreateWidgetView中单击保存时,将调用WidgetService上的Save方法,并且小部件将被持久化。现在需要通知WidgetListViewModel有一个新的 Widget 要显示!

长时间的积累导致了这个问题:我如何让WidgetListViewModel知道它需要显示新的 Widget?

我看过一个视频,其中一个来自 Microsoft 的人使用 ViewModel 订阅的服务上的事件来做这种事情。然而,这样做的缺点是,如果服务比视图模型寿命更长,那么视图模型将不会被 GC 处理,直到服务被 GC 处理。我可以将 IDisposable 添加到 ViewModel。但是,当 ViewModel 仅通过 DataTemplates 在 UI 中表示时,何时/如何调用 Dispose?

有人对此有什么建议吗?

为了澄清,我想说我对 MVVM 的解释最接近 Josh Smith 的解释。至少在我的 MVVM 架构上与 Crack.Net 源代码中的架构非常接近。

4

5 回答 5

1

好的,鉴于对此没有任何答案,但我想我会尝试一下,但我不是 MVVM 方面的专家。

事件似乎是解决这个问题的方法。但是,正如您所指出的,如果服务的寿命超过 ViewModel,则可能会发生内存泄漏。处理这个问题的最好方法是使用弱事件侦听器。

弱事件允许您连接到具有弱引用的事件,这样如果源对象被 GC 处理,则源对象不会被事件处理程序保持活动状态。

于 2009-03-14T12:03:55.357 回答
1

使用 Prism 的 ( http://www.codeplex.com/CompositeWPF ) EventAggregator,它使用发布者-订阅者模式,提供目标和源元素之间的丢失耦合。非常适合您描述的场景。

于 2009-03-14T20:01:56.660 回答
0

我使用了观察者模式(又名发布/订阅模式)来解决同样的问题。我创建了一个名为 EventAggregator 的类,其中包含所有共享方法和数据成员。我可以在 WidgetListViewModel 上注册一个事件,并在 CreateWidgetViewModel 中发布一个“Widget Created”事件。您可以让 WidgetListViewModel 实现 IDisposable(更好)来取消注册您的事件,或者您可以在 Finalize 方法中取消注册它。结果非常好,最好的部分是两个视图模型不需要对彼此有任何了解。

对于更复杂的事情,或者如果您需要支持服务和应用程序之间的版本差异,您可以实现一个 ModelView 来处理这种事情,从而使您的应用程序的模式为 M-MV-VM-V。它可能看起来有点矫枉过正,但它可以使某些类别的问题更容易维护。我知道我有几个项目希望我插入一个 MV,因为 VM 和撤消代码之间的串扰变得荒谬。

于 2009-03-14T19:50:11.943 回答
0

有几种选择:

  1. 使用 ObservableCollection - 这可能是最简单的选择,但是你必须在模型中有某种“主”集合,并且让 UI 直接绑定到这个集合,这可能不是“干净”的 MVVM 架构,但它可能是最简单的方法完成工作。

  2. 使用事件并确保您自己清理,这在 MVVM 中并不容易。

  3. 使用一些中间人来自动清理事件(如其他人建议的那样),但不要自己编写,这有很多陷阱,WPF 有一个内置类可以做到这一点,但我忘记了名字(如果有人记得名字请留言)。

  4. 定期刷新,让 ViewModel 类每 X 秒刷新一次列表,这是在没有某种通知机制的情况下获取更新的唯一方法。

于 2009-03-15T10:07:55.657 回答
0

我同意 Cameron 使用 Wea​​kEvent 模式。我已经为支持 WeakEvent 模式的 ViewModel(在我的示例中我使用名称 PresentationModel)创建了一个基类。

您可能会发现我的示例项目很有用:http: //www.codeplex.com/CompositeExtensions

jbe

于 2009-03-24T13:09:36.660 回答