我正在使用MVVM并在silverlight中使用命令(DelegateEvent和ICommand)
我想要这样的东西,(比方说)我有2个用户控制,父母和孩子。
父母正在托管孩子,他们都拥有自己的视图模型。
在父级上我有一个按钮,它执行一个简单的命令,在执行该命令时,我想更新子控件文本框中的文本。我们也应该能够改变孩子的某些东西,这些东西可以传播给父母。
事件是否是最佳答案,或者我可以通过某种方式获得更新子/通知父级的命令。
答案 0 :(得分:12)
有几种方法可以解决这个问题。
首先,拥有由其他ViewModel组成的ViewModel是完全合适的,只要你可以将它们以这种方式耦合即可。当你这样做时,他们可以使用常规方法调用彼此交谈。
接下来,您可以解耦一些并使用事件。没有错。还有观察者 - >可观察到的耦合,但它们彼此较少依赖。
接下来,你可以完全解耦并使用像EventAggregator这样的东西(Prism有一个你可以使用的好的)。拍摄发布消息。其他订阅。他们完全不了解对方。
我也使用过这个命令......但是对于ViewModel到ViewModel的通信,我觉得这有点尴尬。
答案 1 :(得分:4)
这似乎是使用复合应用指南/棱镜中的EventAggregator的理想情况。
在此模型中,您可以在应用程序的根目录(或其他公共区域)中设置MessageBus。
//在App.xaml.cs中
public static IEventAggregator MessageBus = new EventAggregator();
然后设置一个公共消息库
// 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作为参数的方法。
然后,您可以从任何地方发出消息并在任何地方处理它们 - 跨视图模型,控件等。如果您动态加载应用程序的某些部分,您甚至可以在组件之间传递MessageBuses。效果很好。
答案 2 :(得分:4)
您应该从最明显的实现开始,其中parent viewmodel只保存对子视图模型的引用,而child viewmodel保存对父视图模型的引用。然后,当在父视图模型上执行命令时,它只是在文本框绑定到的子视图模型上设置一个值。
在父级和子级之间添加一个抽象层(例如事件)会增加一定程度的复杂性,因此它应该是合理的。如果这个间接提供的值高于增加代码复杂性的代价(例如,现在不太清楚当父命令执行时会发生什么,你将不得不解决一个问题,即如何在没有获得父代的情况下订阅父代的事件实际引用它,反之亦然,在父子之间添加额外的依赖关系将需要添加额外的事件,这会污染所有管道的实际逻辑等等。)然后肯定事件(或类似PropertyObserver)可能是下一个逻辑步骤。