MVVM Light Toolkit - RelayCommands,DelegateCommands和ObservableObjects

时间:2011-01-04 03:12:22

标签: wpf mvvm mvvm-light mvvm-foundation

我刚刚开始尝试Laurent Bugnion的MVVM Light Toolkit。我想我会非常喜欢它,但我有几个问题。

在我找到他们之前,让我解释一下我来自哪里。我目前使用Josh Smith的MVVM Foundation和Codeplex上另一个名为MVVM Toolkit的项目的组合。我使用MVVM Foundation中的ObservableObjectMessenger以及MVVM Toolkit中的DelegateCommandCommandReference

MVVM Foundation和MVVM Tookit之间唯一真正的重叠是它们都有ICommand的实现:MVVM Foundation有RelayCommand,MVVM Tookit有DelegateCommand。在这两个中,DelegateCommand似乎更复杂。它使用CommandManagerHelper使用弱引用来避免内存泄漏。

话虽如此,这是我的问题:

  1. 为什么MVVM Light使用RelayCommand而不是DelegateCommand?是否在ICommand中使用弱引用是不必要的还是由于某种原因不推荐使用?

  2. 为什么MVVM Light中没有ObservableObjectObservableObject基本上只是实现ViewModelBase的{​​{1}}的一部分,但是将它作为一个单独的类非常方便,因为视图模型不是唯一需要实现的对象{{1} }}。例如,假设您有一个绑定到INotifyPropertyChanged对象列表的DataGrid。如果INotifyPropertyChanged中的任何属性可以在用户查看DataGrid时发生更改,则Person需要实现Person。 (我意识到,如果使用像LinqToSql这样的东西自动生成Person,它可能已经实现了INotifyPropertyChanged,但是在某些情况下我需要制作特定于视图的实体模型对象版本,比方说,因为我需要包含一个命令来支持DataGrid中的按钮列。)

  3. 感谢。

    P.S。以下是MVVM Toolkit中Person的代码:

    https://docs.google.com/document/pub?id=1ApCx5SbCfHi5fBhv8Ki3zA6j34sp2t80LQZdj89v8cU

3 个答案:

答案 0 :(得分:4)

看起来第一个问题提出的问题已在最新版本中得到解决:

根据The MVVM Light Toolkit Codeplex site(在“手动提升CanExecuteChanged事件”下),CommandManager已完全取消。

至于Observable Object,我在Codeplex网站上添加了an item to the Issue Tracker

答案 1 :(得分:0)

您的两个问题都强烈建议您更喜欢使用 more 而不是View Model概念来定义业务逻辑。

DelegateCommand除了View Model之外还定义了一个单独的类。 ObservableObject是除了View Model之外的单独类的实例。这不是一个规则,而是当下的个人偏好:视图模型对我来说足以作为业务逻辑的容器,与视觉相关。这可能会背叛我对MVVM Light的偏爱 - 我现在还没有发现它。

我不太确定DataGrid示例中发生了什么。我可以说DataGrid不是很灵活 - 但是,在WPF中,DataGridTemplateColumn可以声明性地将视图模型绑定到视图(例如用户控件)。所以也许这是有道理的:

<DataGridTemplateColumn.CellTemplate>
    <DataTemplate DataView="{x:Type m:YourViewModelForButton}">
        <v:YourViewWithButton/>
    </DataTemplate>
</DataGridTemplateColumn.CellTemplate>

答案 2 :(得分:0)

您还可以考虑Catel。它支持DataObject(通用和非泛型),它们完全支持您正在寻找的内容(实现INotifyPropertyChanged的对象,IDataErrorInfo等等)。然后,ViewModelBase派生自非常强大的DataObjectBase类,因此您可以将DataObjectBase用于数据对象,并将ViewModelBase用于视图模型。

它还可以帮助您避免创建信使,因为您只需在视图模型上使用InterestedIn属性即可接收另一个视图模型的更改通知。