我刚刚开始尝试 Laurent Bugnion 的 MVVM Light Toolkit。我想我会非常喜欢它,但我有几个问题。
在开始之前,让我先解释一下我来自哪里。我目前使用 Josh Smith 的 MVVM Foundation 和 Codeplex 上另一个名为 MVVM 工具包。我使用 MVVM Foundation 中的 ObservableObject
和 Messenger
以及 MVVM Toolkit 中的 DelegateCommand
和 CommandReference
。
MVVM Foundation 和 MVVM Tookit 之间唯一真正的重叠是它们都有 ICommand 的实现:MVVM Foundation 有 RelayCommand,MVVM Tookit 有 DelegateCommand 。在这两者中,DelegateCommand
似乎更复杂。它采用了 CommandManagerHelper,使用弱引用来避免内存泄漏。
话虽如此,我的问题是:
-
为什么 MVVM Light 使用 RelayCommand
而不是 DelegateCommand
?由于某种原因,在 ICommand
中使用弱引用是否不必要或不建议?
-
为什么 MVVM Light 中没有 ObservableObject
? ObservableObject
基本上只是 ViewModelBase
的一部分,它实现了 INotifyPropertyChanged
,但是作为一个单独的类非常方便,因为视图模型不是仅需要实现 INotifyPropertyChanged 的对象。例如,假设您有一个绑定到 Person
对象列表的 DataGrid。如果在用户查看 DataGrid 时 Person
中的任何属性可以更改,则 Person
需要实现 INotifyPropertyChanged
。 (我意识到,如果 Person
是使用 LinqToSql 之类的东西自动生成的,它可能已经实现了 INotifyPropertyChanged
,但在某些情况下,我需要制作特定于视图的版本例如,因为我需要包含一个命令来支持 DataGrid 中的按钮列。)
谢谢。
PS 以下是 MVVM 工具包中的 DelegateCommand
代码:
https: //docs.google.com/document/pub?id=1ApCx5SbCfHi5fBhv8Ki3zA6j34sp2t80LQZdj89v8cU
I just started experimenting with Laurent Bugnion's MVVM Light Toolkit. I think I'm going to really like it, but I have a couple questions.
Before I get to them, let me explain where I'm coming from. I currently use a combination of Josh Smith's MVVM Foundation and another project on Codeplex called MVVM Toolkit. I use ObservableObject
and Messenger
from MVVM Foundation and DelegateCommand
and CommandReference
from MVVM Toolkit.
The only real overlap between MVVM Foundation and MVVM Tookit is that they both have an implementation for ICommand
: MVVM Foundation has RelayCommand
and MVVM Tookit has DelegateCommand
. Of these two, DelegateCommand
appears to be more sophisticated. It employs a CommandManagerHelper
that uses weak references to avoid memory leaks.
With that said, here are my questions:
-
Why does MVVM Light use RelayCommand
rather than DelegateCommand
? Is the use of weak references in an ICommand
unnecessary or not recommended for some reason?
-
Why is there no ObservableObject
in MVVM Light? ObservableObject
is basically just the part of ViewModelBase
that implements INotifyPropertyChanged
, but it's very convenient to have as a separate class because view-models are not the only objects that need to implement INotifyPropertyChanged
. For example, let's say you have a DataGrid that binds to a list of Person
objects. If any of the properties in Person
can change while the user is viewing the DataGrid, Person
would need to implement INotifyPropertyChanged
. (I realize that if Person
is auto-generated using something like LinqToSql, it will probably already implement INotifyPropertyChanged
, but there are cases where I need to make view-specific versions of entity model objects, say, because I need to include a command to support a button column in a DataGrid.)
Thanks.
P.S. Here is the code for DelegateCommand
from the MVVM Toolkit:
https://docs.google.com/document/pub?id=1ApCx5SbCfHi5fBhv8Ki3zA6j34sp2t80LQZdj89v8cU
发布评论
评论(3)
看起来第一个问题提出的问题已在最新版本中得到解决:
根据The MVVM Light Toolkit Codeplex site(在“手动引发 CanExecuteChanged 事件”下),
CommandManager
已被完全消除。至于
可观察对象
,我已将一个项目添加到问题跟踪器在 Codeplex 网站上。It looks like the issue raised by the first question has been solved in the latest build:
According to The MVVM Light Toolkit Codeplex site (under "Raising the CanExecuteChanged event manually"), the
CommandManager
has been eliminated altogether.As for
Observable Object
, I have added an item to the Issue Tracker on the Codeplex Site.您还可以考虑 Catel。它支持 DataObject(通用和非通用),该对象完全支持您正在寻找的内容(实现 INotifyPropertyChanged、IDataErrorInfo 等的对象)。然后,ViewModelBase 派生自非常强大的 DataObjectBase 类,因此您可以将 DataObjectBase 用于数据对象,将 ViewModelBase 用于视图模型。
它还使您无需创建信使,因为您只需使用视图模型上的 InterestedIn 属性即可接收另一个视图模型的更改通知。
You can also consider Catel. It supports a DataObject (both generic and non-generic) that support exactly what you are looking for (an object implementing INotifyPropertyChanged, IDataErrorInfo, and much more). Then, the ViewModelBase is derived from the very powerful DataObjectBase class, so you can use the DataObjectBase for data objects, and the ViewModelBase for view models.
It also saves you from creating messengers since you can simply use the InterestedIn attribute on a view model to receive change notifications of another view model.
你的两个问题都强烈地表明你更喜欢使用比视图模型概念更多的东西来定义业务逻辑。
DelegateCommand
定义了一个独立于视图模型的单独类。ObservableObject
是一个独立于视图模型的类的实例。这不是规则,而是目前的个人偏好:视图模型对于我来说足以作为与视觉相关的业务逻辑的容器。这可能暴露了我对 MVVM Light 的偏好——我目前不认为缺少它。我不太确定 DataGrid 示例中发生了什么。我可以说的是,DataGrid 不是很灵活——但是,在 WPF 中,
DataGridTemplateColumn
可以以声明方式将视图模型绑定到视图(例如用户控件)。所以也许这是有道理的:Both of your questions strongly suggest to me that you prefer to use something more than the View Model concept to define business logic.
The
DelegateCommand
defines a separate class apart from the View Model. TheObservableObject
is an instance of a separate class apart from the View Model. This is not a rule but personal preference of the moment: the View Model is sufficient for me as a container for business logic, relating to visuals. This may betray my preference for MVVM Light---which I do not find lacking at the moment.I'm not quite certain about what's going on in the DataGrid example. What I can say is that the DataGrid is not very flexible---however, in WPF, the
DataGridTemplateColumn
can declaratively bind a View Model to a View (e.g. a User Control). So perhaps this makes sense: