MVVM Light Toolkit - RelayCommands、DelegateCommands和ObservableObjects

5

我刚刚开始尝试使用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中为什么没有ObservableObject类?其实,ObservableObject基本上就是实现了INotifyPropertyChanged部分的ViewModelBase类,但将其作为单独类非常方便,因为不仅视图模型需要实现INotifyPropertyChanged接口。例如,假设您有一个绑定到Person对象列表的DataGrid。如果用户在查看DataGrid时可以更改Person的任何属性,则Person需要实现INotifyPropertyChanged接口。(我意识到如果Person是使用LinqToSql之类的自动生成的,则它可能已经实现了INotifyPropertyChanged接口,但还有一些情况,我需要创建特定于视图的实体模型对象版本,以支持DataGrid中的按钮列命令等功能。)

谢谢。

P.S. 这是来自MVVM Toolkit的DelegateCommand代码:

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

3个回答

4

看起来第一个问题已经在最新的构建中得到解决:

根据MVVM Light Toolkit Codeplex网站(在“手动引发CanExecuteChanged事件”下),CommandManager已被完全取消。

至于Observable Object,我已经在Codeplex网站上添加了一个问题跟踪项


现在,ObservableObject已经被实现了。 - devuxer

1

您也可以考虑使用Catel。它支持DataObject(通用和非通用),完全支持您所需的内容(实现INotifyPropertyChanged、IDataErrorInfo等)。然后,ViewModelBase派生自非常强大的DataObjectBase类,因此您可以将DataObjectBase用于数据对象,将ViewModelBase用于视图模型。

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


0

你的两个问题强烈表明你更喜欢使用比“视图模型”概念更多的东西来定义业务逻辑。

DelegateCommand 定义了一个与视图模型分离的类。 ObservableObject 是一个与视图模型分离的类的实例。这不是一条规则,而是此时的个人喜好:对于我来说,“视图模型”足以作为业务逻辑的容器,涉及到可视化内容。这可能暴露出我对 MVVM Light 的偏好--- 我目前并不觉得它有什么缺陷。

我不太确定 DataGrid 示例中正在发生什么。我可以说的是,DataGrid 不是非常灵活 --- 然而,在 WPF 中,DataGridTemplateColumn 可以声明性地将视图模型绑定到视图(例如,用户控件)。因此,这也许是有意义的:

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

RelayCommand也是一个独立的类,ViewModelBase也是如此。至于我的DataGrid示例,这可能只是一个术语问题。我认为在MVVM中,view-models是您通过DataContext绑定到视图的内容。但我还认为,您可以为域对象(即实体)创建视图模型。例如,Person可能具有DateOfBirth属性。PersonViewModel可能具有其他属性,如AgeIsSelected(用于DataGrid复选框列)和ToggleSelectionCommand(用于DataGrid按钮列)。 - devuxer
通常我的领域对象是视图模型的一部分。例如,在您的情况下,我会有一个icollection<person>,selectedPerson属性,然后我会将人员的属性作为单独的属性绑定到selectedPerson上。 - ecathell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接