具有撤消/重做的DataGrid和MVVM

时间:2011-11-02 17:25:55

标签: wpf mvvm datagrid undo-redo

我正在玩非常简单的界面,带有按钮和快捷键,用于添加,插入和删除datagrid行(底层绑定集合)。 还需要实现撤消堆栈。 但是......我不知道如何处理这种控制的内部逻辑。 默认情况下,DataGrid可以自动删除或添加新行,并在用户输入(Esc,F2等)上执行许多其他操作,从而隐式更改绑定数据。

由于命令要在VM端执行,因此撤销堆栈是其(甚至是M)业务,但DataGrid包含对DataGrid的内部预定义绑定。命令。我认为没有简单的方法可以“观察”数据的变化。

我对理想的MVVM流程的理解是这样的: 用户操作(查看) - >命令(VM) - > Commmand Excution +撤消堆栈操作。 (VM-M) - > UI分别更改为VM更改。

我很困惑,需要一些关于实施的好建议。

4 个答案:

答案 0 :(得分:2)

2种方法:

  1. 在ViewModel(POCO模型)上拥有所有逻辑。

    您必须让ViewModel包含撤消/重做堆栈。你如何实现它取决于你,但我建议让Undo / Redo堆栈为Tuple<String, Object>。存储属性名称和属性的值。它比管理克隆更容易。通过查看UndoStack上是否有任何物品,它还可以让你通过糟糕的“肮脏”检查。

  2. 为您的模型提供一些界面,例如IUndoRedo(Rich Models)。

    你必须让你的ViewModel调用接口方法来撤销/重做,但想法是一样的...有一个由Tuple<String, Object>组成的撤销/重做堆栈。

    如果您确实希望采用丰富的模型方法,那么您可以查看现有的框架,例如CSLA.Net,这是为丰富的模型而制作的,尽管它可能比您的内容更多一些。真的需要。如果你想拥有非常丰富的模型,就把它扔掉。


  3. 附注:你的ObservableCollection(ItemsSource)应该是ViewModels,而不是Models。如果您使用的是模型,请将其丢弃。也就是说,不要ObservableCollection<IEmployee>,而是ObservableCollection<EmployeeViewModel>。它使事情变得更容易,更容易,更可重复使用!

    另一方面注意:尽量避免使用DataGrid。它让开发者想要脱掉头发。我只是用ListView推出你自己的“网格”:)

答案 1 :(得分:1)

通常我会将撤消逻辑构建到模型本身中。在你开始思考他们将如何绑定到UI之前,让他们完全按照你想要的方式工作。

答案 2 :(得分:1)

我在MVVM中做了一篇关于undo / redo的文章。它分为两部分:第一部分解释了一般版本中的撤销/重做,第二部分解释了使用列表:

Part 1: Using the Viewmodel pattern to provide Undo / Redo in WPF

Part 2: Viewmodelling lists

流程是:用户操作(查看) - &gt;命令(VM) - &gt; Commmand执行修改模型 - &gt;模型通知VM的更改 - &gt; VM通知对视图的更改。 这样,如果从其他源修改模型,它也会刷新视图。

还有一个github项目here

答案 3 :(得分:0)

由于DataGrid绑定到集合,因此您可以监视Collection本身而不是DataGrid的更改。使用收藏中的CollectionChanged事件来观看已添加或已移除的项目,并在所有收藏品的项目上注册PropertyChanged事件,以便进行监控修改。

另一种想法也是提供RevertChanges命令而不是UndoChanges。它更容易实现,因为您只需要存储原始集合,以便在需要时可以恢复它。