【问题标题】:MVVM Light Toolkit - RelayCommands, DelegateCommands, and ObservableObjectsMVVM Light Toolkit - RelayCommands、DelegateCommands 和 ObservableObjects
【发布时间】:2011-06-03 04:25:42
【问题描述】:

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

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

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。如果Person 中的任何属性可以在用户查看DataGrid 时更改,Person 将需要实现INotifyPropertyChanged。 (我意识到如果 Person 是使用 LinqToSql 之类的东西自动生成的,它可能已经实现了 INotifyPropertyChanged,但是在某些情况下,我需要制作实体模型对象的视图特定版本,例如,因为我需要在 DataGrid 中包含一个支持按钮列的命令。)

谢谢。

附:这是 MVVM 工具包中DelegateCommand 的代码:

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

【问题讨论】:

    标签: wpf mvvm mvvm-light mvvm-foundation


    【解决方案1】:

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

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

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

    【讨论】:

    • ObservableObject 现在也已实现。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      您的两个问题都向我强烈建议您更喜欢使用比视图模型概念更多的东西来定义业务逻辑。

      DelegateCommand 定义了一个独立于视图模型的独立 类。 ObservableObject 是视图模型之外的 separate 类的一个实例。这不是规则,而是个人偏好:对于我来说,视图模型足以作为与视觉相关的业务逻辑容器。这可能会暴露我对 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 可能具有其他属性,例如 Age、IsSelected(用于 DataGrid 复选框列)和 ToggleSelectionCommand(用于 DataGrid 按钮列)。
      • @DanM 通常我的域对象是视图模型的一部分。例如,在您的情况下,我将有一个 icollection, selectedPerson 属性,然后我会将人的属性作为绑定到 selectedPerson 的单独属性。
      猜你喜欢
      • 2011-06-19
      • 2011-05-29
      • 1970-01-01
      • 2011-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多