【问题标题】:How to have multiple pairs "View-ViewModel"?如何拥有多对“View-ViewModel”?
【发布时间】:2011-02-19 07:20:45
【问题描述】:

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

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

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

因此,有没有简单易行的方法来实现这一点?或者您有什么最佳实践建议我遵循?

提前感谢您的宝贵帮助。

干杯,
詹卢卡。

【问题讨论】:

  • 好的,我不确定我是否走在正确的道路上,但我发现了一篇有趣的文章(John Papa - johnpapa.net/silverlight/…),我正在尝试以这种方式实现 ViewModelLocator。不过,我仍然不确定如何处理我可能创建的众多视图中的特定视图...

标签: c# wpf mvvm mvvm-light


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

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

    见“How to distinguish multiple view/view model pairs using unity container”。

    【讨论】:

      【解决方案3】:

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

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

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

      希望对您有所帮助, 洛朗

      【讨论】:

      • 感谢 Laurent 的回复。当然,我需要更深入地挖掘这一点。顺便说一句,我已经看到许多人使用 MEF 而不是适当的 ViewModel Locator ......所以,我也在试验这个解决方案。关于“窗口处理程序”,我尝试了不同的方法,但我还没有找到最适合我的情况的方法;)感谢您的所有帮助。詹卢卡。
      • 我有一个使用 mef 的具有多个模块的应用程序,从一个模块我需要在另一个模块中显示一个视图,调用视图侦听另一个模块中显示的视图的消息,从视图显示它可能会创建同一个视图的另一个实例,现在公共消息变成了一个问题,两个视图实例发送相同的消息,我怎样才能以正确的方式解决这个问题,分配每个视图实例和 id 一些东西?
      • @Gianluca:根据我的经验,最好的方法是将 ViewModelLocator 与 MEF 或 IOC 容器(NInject、Unity 或其他)结合起来。
      • @Priyan:最好的方法可能是 ID 您的视图,并将 ID 与消息一起发送。例如,如果您从 MessageBase 派生消息(不是强制性的,但可能),您可以在消息中设置 sender 属性。这表明谁发送了消息。
      • @LBugnion 所以作为一名程序员,这个答案是有道理的,这甚至正是我在这里的原因。但是,作为 WPF 和 MVVM Light 的新手,我可以实现字典并编写 GetViewModel(string key)。但现在呢?我是否将密钥传递给 View 并在构造函数后面的代码中设置其 VM?或者是否有一种神奇的 MVVM Light 方法可以像 Singletons 一样从 XAML 中执行此操作?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-28
      • 1970-01-01
      • 2013-08-29
      • 1970-01-01
      • 2019-01-03
      • 2012-06-10
      • 1970-01-01
      相关资源
      最近更新 更多