2009-04-28 48 views
20

火上查看事件在我的WPF应用程序,我有2个窗口(包括Windows系统有自己的视图模型):WPF MVVM正确方法从视图模型

  1. 应用程序的主窗口,与一堆话显示表(界到MainViewModel)

  2. 对话窗口,允许用户添加新项目列表(绑定到AddWordViewModel)

MainViewModel有李的文章属性st(此集合由其中一个服务类填充)绑定到主窗口的列表框

AddWordViewModel具有绑定到添加Word对话框的保存按钮的SaveWordCommand。它的任务是获取用户输入的文本并将其传递给服务类。

用户点击保存按钮后,我需要通知MainViewModel重新加载服务中的文章。

我的想法是从AddWordViewModel

在MainViewModel揭露公共命令并执行它

什么是它执行正确的方式?

谢谢!

回答

18

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)); 
    } 
} 

这种模式的好处是,你可以很轻松地扩展您的应用程序具有的创造的话,多的ViewModels有兴趣已添加词语多种方式并且两者之间没有耦合,因此您可以根据需要添加和删除它们。


如果你想避免单(和出于测试目的,我建议你这样做),那么它可能是值得探讨依赖注入,虽然这确实是一个整体的其他问题。


好吧,最后的想法。我从重新阅读您的问题中看到,您已经有了一些处理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 
    } 
} 

要避免做虽然是通过调用命令介绍,您将创建的ViewModels之间的耦合是什么在另一个ViewModel上,这会严重限制你扩展应用程序的选项(如果第二个ViewModel对新单词产生了兴趣,现在是AddWordViewModel的责任告诉那个单词吗?)

+0

谢谢你非常详细回答。将不得不挖掘:) :)很多乐趣:) – 2009-04-28 18:10:32