从另一个viewmodel更新viewmodel

我有两个ViewModel,一个连接到主窗口,另一个连接到子窗口,通过单击主窗口上的按钮打开。 子窗口包含一个项目列表,我想选择一个项目,并通过更新主窗口视图模型在主窗口中显示它。 实现这一目标的最佳方法是什么? 谢谢!

有很多方法可以做到这一点。

  • 将对主/父视图模型的引用传递给子项,并让子项调用主视图模型。

  • 让子视图模型触发父订阅的事件。

  • 使用messenger / mediator在两者之间进行通信。 父订阅,孩子发布消息。 这提供了松耦合。

  • 将主视图模型设置为全局服务。 以某种方式注册它。 让孩子查找服务(需要全局服务是一个非常常见的问题),然后在全局/通用接口上调用一些东西。

根据我的经验,最简单的方法是#2。 在子视图模型上定义事件。 父母将不得不查找孩子(我不知道它是否包含它或者你的视图模型是如何构建的)并订阅该事件。

ViewModels之间通信的标准方法是使用某种类型的消息。 一个很好的实现是MVVM Light Toolkit

这是使用默认信使的一些(随机)代码:

//Registering: Messenger.Default.Register>(this, true, fillSourceWith); Messenger.Default.Register(this, ChangeMainTemplates); //with a specific "token" Messenger.Default.Register(this, MessageTokens.ClearList, o => BookSource.Clear()); //Sending Messenger.Default.Send>(newBooks); Messenger.Default.Send(DisplayModeEnum.MediumLayout); Messenger.Default.Send(null, MessageTokens.ClearList); 

最好的方法是从子级到父级进行某种引用,并在关闭子级时更新此父级。

或者你可以在孩子身上发生某种事件,让父母听这个事件。 然后,当孩子关闭时,你举起这个事件。

当两个ViewModel逻辑上不相关时,使用消息传递。

[咆哮]人们甚至不知道OOP的基本原理或者什么? [/咆哮]

前几天我遇到了同样的问题;-)

最后,我使用了一个中介来传达两个视图模型。 事实上我使用了MVVM Light中的Messenger。

 public void Search(object parameter) { ChildWindow window = new ChildWindow(); SearchWindow pageSearch = new SearchWindow(); window.Content = pageSearch; window.Show(); Messenger.Default.Register(this, action => this.closeWindow(action)); } 

之后我用主窗口中需要知道的所有内容定义了Message:

 public class CloseWindowMessage : MessageBase { public bool Result { get; set; } public Model.Selected Selected { get; set; } } 

最后,从childwindow返回的消息只需要注册带有结果的消息和要返回的对象。

您应该从视图的代码隐藏处注册以关闭窗口。

我认为在两个视图模型之间传递消息的最佳方法是事件编程。