我有两个ViewModel,一个连接到主窗口,另一个连接到子窗口,通过单击主窗口上的按钮打开子窗口。子窗口包含项目列表,我想通过更新主窗口视图模型来选择项目并在主窗口中显示它。实现这一目标的最佳方法是什么?谢谢!
答案 0 :(得分:10)
有很多方法可以做到这一点。
将对主视图/父视图模型的引用传递给子视图,让子视图调用主视图模型。
让子视图模型触发父订阅的事件。
使用messenger / mediator在两者之间进行通信。父订阅,孩子发布消息。这提供了松耦合。
将主视图模型设置为全局服务。以某种方式注册它。让孩子查找服务(需要全局服务是一个非常常见的问题)然后在全局/公共接口上调用一些东西。
根据我的经验,最简单的方法是#2。在子视图模型上定义事件。父母将不得不查找孩子(我不知道它是否包含它或你的视图模型是如何构建的)并订阅该事件。
答案 1 :(得分:7)
ViewModels之间通信的标准方法是使用某种类型的消息。一个很好的实现是MVVM Light Toolkit
这是使用默认信使的一些(随机)代码:
//Registering:
Messenger.Default.Register<IEnumerable<BookViewModel>>(this, true, fillSourceWith);
Messenger.Default.Register<DisplayModeEnum>(this, ChangeMainTemplates);
//with a specific "token"
Messenger.Default.Register<object>(this, MessageTokens.ClearList, o => BookSource.Clear());
//Sending
Messenger.Default.Send<List<BookViewModel>>(newBooks);
Messenger.Default.Send<DisplayModeEnum>(DisplayModeEnum.MediumLayout);
Messenger.Default.Send<object>(null, MessageTokens.ClearList);
答案 2 :(得分:1)
最好的方法是从孩子到父母进行某种引用,并在关闭孩子时更新这个父母。
或者你可以在孩子身上发生某种事件,让父母听这个事件。然后,当孩子关闭时,你会举起这个事件。
当两个ViewModel逻辑上不相关时使用消息传递。
[咆哮]人们甚至不知道OOP的基本原则还是什么? [/咆哮]
答案 3 :(得分:1)
前几天我遇到了同样的问题; - )
最后,我使用了一个中介来传达两个视图模型。事实上,我使用了MVVM Light中的Messenger。
public void Search(object parameter)
{
ChildWindow window = new ChildWindow();
SearchWindow pageSearch = new SearchWindow();
window.Content = pageSearch;
window.Show();
Messenger.Default.Register<Messages.CloseWindowMessage>(this, action => this.closeWindow(action));
}
之后我用主窗口中需要知道的所有内容定义了消息:
public class CloseWindowMessage : MessageBase
{
public bool Result { get; set; }
public Model.Selected Selected { get; set; }
}
最后从childwindow返回的消息你只需要注册带有结果的消息和你想要回来的对象。
您应该从视图的代码隐藏处注册以关闭窗口。
答案 4 :(得分:-1)
我认为在两个视图模型之间传递消息的最佳方法是事件编程。