【问题标题】:silverlight - communicate between 2 view models in MVVM using commandssilverlight - 使用命令在 MVVM 中的 2 个视图模型之间进行通信
【发布时间】:2010-12-18 17:52:33
【问题描述】:

我正在研究 MVVM 并在 silverlight 中使用命令(DelegateEvent 和 ICommand)

我想要这样的东西,(比如说)我有 2 个用户控件,父级和子级。

父母托管孩子,他们都有自己的视图模型。

在父级上,我有一个按钮,它执行一个简单的命令,在执行该命令时,我想更新子控件文本框中的文本。我们也应该能够改变孩子中可以传播给父母的东西。

事件是最好的答案,或者我可以有命令以某种方式更新孩子/通知父母。

【问题讨论】:

    标签: wpf silverlight silverlight-3.0 mvvm


    【解决方案1】:

    有几种方法可以解决这个问题。

    首先,拥有由其他 ViewModel 组成的 ViewModel 是完全合适的,只要您同意它们以这种方式耦合即可。当您这样做时,他们可以使用常规方法调用相互交谈。

    接下来,您可以稍微解耦并使用事件。没有错。仍然存在 Observer -> Observable 耦合,但它们之间的依赖关系较小。

    接下来,您可以完全解耦并使用 EventAggregator 之类的东西(Prism 有一个很好的可以使用)。拍摄发布消息。另一个订阅。他们根本不认识对方。

    我也为此使用过命令...但是对于 ViewModel 到 ViewModel 的通信,我觉得这有点尴尬。

    【讨论】:

      【解决方案2】:

      您可能应该从最明显的实现开始,其中父视图模型仅包含对子视图模型的引用,而子视图模型包含对父视图模型的引用。然后,当在父视图模型上执行命令时,它只需在文本框绑定到的子视图模型上设置一个值。

      在父子节点(例如事件)之间添加一个抽象层会增加一定程度的复杂性,因此它应该是合理的。如果此间接提供的值高于代码复杂性增加的成本(例如,现在不太清楚在执行父级命令时会发生什么,您将必须解决一个问题,即子级如何订阅父级事件而没有获得对它的实际引用,反之亦然,在父子之间添加额外的依赖项将需要添加额外的事件,这会污染所有管道等的实际逻辑)然后当然事件(或类似PropertyObserver)可能是下一个逻辑步骤。

      【讨论】:

      • 我同意最好从简单开始,然后根据需要引入复杂性。记住不同的模式和技术很重要,这样如果你在简单的实现中遇到限制,你就有一个行动计划来转移到另一种模式。我倾向于相应地注释我的代码,以帮助明确某些设计决策是在哪里做出的并且可能会改变。
      【解决方案3】:

      这似乎是使用诸如复合应用程序指南/棱镜中的 EventAggregator 的理想情况。

      在此模型中,您可以在应用程序的根目录(或其他公共区域)中设置 MessageBus。

      // 在 App.xaml.cs 中

      public static IEventAggregator MessageBus = new EventAggregator();

      然后建立一个通用的Messages库

      // in Messages.cs
      
          public class SimpleCommand: CompositePresentationEvent<SimpleObject> { }
      

      其中 SimpleObject 是一个类或变量,其中包含处理此事件所需的所有信息。

      // in control with button
      
          App.MessageBus.GetEvent<Messages.SimpleCommand>().Publish(SimpleObject);
      
      // anywhere in your app that you "care" about this 
      
          App.MessageBus.GetEvent<Messages.SimpleCommand>().Subscribe(ProcessingMethod);
      

      其中 ProcessingMethod 是一个将 SimpleObject 作为参数的方法。

      然后,您可以从任何地方发出消息并在任何地方处理它们 - 跨视图模型、控件等。如果您正在动态加载应用程序的某些部分,您甚至可以在组件之间传递 MessageBus。效果很好。

      【讨论】:

      • 我让自己搞砸了这种事件设置的地方是嵌套控件存在于多个视图中。由于它是一个嵌套控件(视图和视图模型),因此可以合理地假设它是嵌套的,因为它旨在成为可重用的功能。如果使用简单的事件,似乎没有一个好方法可以只针对“我的​​子视图模型”而不是其他视图上的。如果嵌套视图和 vm 最终嵌套到多个视图中,您可能会遇到单击 1 个视图中的按钮导致多个其他视图错误更新的情况。
      猜你喜欢
      • 1970-01-01
      • 2011-03-01
      • 2012-06-28
      • 2014-10-11
      • 1970-01-01
      • 1970-01-01
      • 2011-10-12
      • 1970-01-01
      • 2020-01-09
      相关资源
      最近更新 更多