WPF MVVM 从 ViewModel 触发事件的正确方法
Posted
技术标签:
【中文标题】WPF MVVM 从 ViewModel 触发事件的正确方法【英文标题】:WPF MVVM Correct way to fire event on view from ViewModel 【发布时间】:2010-10-22 09:18:44 【问题描述】:在我的 WPF 应用程序中,我有 2 个 Windows(两个 Windows 都有自己的 ViewModel):
应用程序的主窗口,显示带有一堆单词的列表(绑定到 MainViewModel)
允许用户向列表中添加新项目的对话框窗口(绑定到 AddWordViewModel)
MainViewModel 具有 List 的 Articles 属性(此集合由服务类之一填充)绑定到主窗口的 ListBox
AddWordViewModel 有 SaveWordCommand 绑定到 Add Word 对话框的 Save 按钮。它的任务是获取用户输入的文本并将其传递给服务类。
用户点击保存按钮后,我需要通知 MainViewModel 从服务中重新加载文章。
我的想法是在 MainViewModel 中公开公共命令并从 AddWordViewModel 执行它
什么是正确的实现方式?
谢谢!
【问题讨论】:
【参考方案1】:Event Aggregators 是解决此类问题的好方法。基本上有一个集中的类(为了简单起见,假设它是一个单例,并面对可能的反单例家伙的愤怒)负责将事件从一个对象转移到另一个对象。使用您的类名,用法可能如下所示:
public class MainViewModel
public MainViewModel()
WordAddedEvent event = EventAggregator.Instance.GetEvent<WordAddedEvent>();
event.Subscribe(WordAdded);
protected virtual void WordAdded(object sender WordAddedEventArgs e)
// handle event
public class AddWordViewModel
//From the command
public void ExecuteAddWord(string word)
WordAddedEvent event = EventAggregator.Instance.GetEvent<WordAddedEvent>();
event.Publish(this, new WordAddedEventArgs(word));
这种模式的优点是您可以非常轻松地扩展您的应用程序,使其具有多种创建单词的方式和多个对已添加的单词感兴趣的 ViewModel,并且两者之间没有耦合,因此您可以添加和删除根据需要使用它们。
如果您想避免单例(出于测试目的,我建议您这样做),那么可能值得研究依赖注入,尽管这确实是另一个问题。
好的,最后的想法。我从重新阅读您的问题中看到,您已经拥有某种处理 Word 对象的检索和存储的 Word Service 类。添加新词时,服务没有理由不负责引发事件,因为两个 ViewModel 都已经耦合到它。虽然我仍然建议 EventAggregator 更灵活且更好的解决方案,但YAGNI 可能适用于此
public class WordService
public event EventHandler<WordAddedEventArgs> WordAdded;
public List<string> GetAllWords()
//return words
public void SaveWord(string word)
//Save word
if (WordAdded != null) WordAdded(this, new WordAddedEventArgs(word));
//Note that this way you lose the reference to where the word really came from
//probably doesn't matter, but might
public class MainViewModel
public MainViewModel()
//Add eventhandler to the services WordAdded event
您想要避免的是引入 ViewModel 之间的耦合,您将通过在一个 ViewModel 上调用命令与另一个 ViewModel换句话说,现在 AddWordViewModel 也有责任告诉那个人吗?)
【讨论】:
感谢您非常详细的回答。将不得不深入研究它:) 很多乐趣即将到来:) 我为我的 MVVM 实现使用了一个庞大的对象图,完全实现了 OO。两年后进行结构性改变是相当困难的。我希望我已经选择了聚合器/中介器模式,因为它的灵活性很大。注意:内存泄漏。确保您的聚合器使用弱引用。以上是关于WPF MVVM 从 ViewModel 触发事件的正确方法的主要内容,如果未能解决你的问题,请参考以下文章
wpf中mvvm的Command绑定后,如何在点击按钮的时候在viewmodel里面异步执行方法。
WPF MVVM 如何在ViewModel中操作View中的控件事件
使用 MVVM 从 WPF ListView 项触发双击事件