12

我正在构建一个基于 MVVM-Light 的应用程序。我需要创建同一个视图的多个实例,每个实例都应该绑定到自己的 ViewModel。

默认将ViewModelLocatorViewModel 实现为单例,因此同一个 View 的不同实例将绑定到同一个 ViewModel。

我可以在 VMLocator 中将 ViewModel 创建为非静态对象(就像返回 new VM()... 一样简单),但这只会部分帮助我。事实上,我仍然需要跟踪打开的窗口。然而,每个窗口可能会打开其他几个窗口(尽管类型不同)。在这种情况下,我可能需要对父视图及其所有子视图执行一些操作。例如,在关闭视图 P 之前,我可能想要关闭它的所有子视图(视图 C1、视图 C2 等)。

因此,是否有任何简单易行的方法来实现这一目标?或者您有什么最佳实践建议我遵循吗?

提前感谢您的宝贵帮助。

干杯,
吉安卢卡。

4

3 回答 3

11

没有义务将 ViewModels 作为单例存储在 ViewModelLocator 中,但如果视图也是单例,这肯定会使它们更容易找到。显然,如果你有同一个 View 类的多个实例,你就会有同一个 ViewModel 类的多个实例,它不能再是单例了。

要跟踪 ViewModel 的多个实例,您可以在 ViewModelLocator 中实现一个字典,根据键查找 ViewModel。例如,键可以是视图的唯一 ID。获取视图后,检索其键,然后从定位器中检索视图模型。

更新:通常您甚至不需要跟踪多个视图模型。例如,您可以让 Messenger 类使用 Send 重载向给定视图模型类的所有实例发送消息。因此,在使用字典来跟踪 VM 之前,先问问自己是否真的需要它!;)

希望有帮助,劳伦特

于 2010-05-17T09:59:04.513 回答
0

我使用了统一容器的命名系统。

请参阅“如何使用统一容器区分多个视图/视图模型对”。

于 2012-04-03T11:34:59.213 回答
0

我在这个 SO question中发布并解决了一个问题。事实证明,这与 Bugnion 先生在这里的回答非常相关(这对我帮助很大,谢谢!)

我发现您根本不需要将视图模型属性存储在 ViewModelLocator 中。只需使用ServiceLocator密钥创建一个实例,然后在您的“对话服务”中,将密钥传递给ShowDialog<T>(string key = null).

此外,正如该线程中已经提到的,使用方法Messenger.Default.Send并记住在viewModel.Cleanup()之后调用以取消注册视图模型Messenger,从而防止幻像视图模型尝试处理未来发送到视图模型类类型的所有实例的消息。

于 2014-06-05T12:55:28.227 回答