在 WPF M-V-VM 中撤消,它如何适应? [英] Undo inside WPF M-V-VM, how does it fit?

查看:44
本文介绍了在 WPF M-V-VM 中撤消,它如何适应?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我之前的项目中,我已经用c++实现了undo系统,我知道它是如何工作的.我也知道命令模式.

In my previous projects, I have already implemented undo system in c++, and I know how it work. I am also aware of the Command pattern.

我将实现一个 C#/WPF 桌面应用程序,并希望将我的设计基于 M-V-VM 模式.

I will be implementing a C#/WPF desktop application and would like to base my design on the M-V-VM pattern.

应用程序将:

  • 是一个相对较小的项目(1 个开发人员的预计工作时间为 2-3 周)
  • 有一个具有持久性的简单数据模型(linq to XML)
  • 支持撤销/重做

我想知道是否有人在遵循 M-V-VM 模式时有实施撤消系统的经验.它如何融入其中?它如何从 INotifyPropertyChanged 和 INotifyCollectionChanged 通知中受益,以便在实现模型(业务对象)时所需的工作最少.

I was wondering if anybody has experience with implementing an undo system when following the M-V-VM pattern. How would it fit in it? How can it benefit from the INotifyPropertyChanged and INotifyCollectionChanged notifications so minimal work is required when implementing the Models (business objects).

我认为撤消系统会以某种方式集成到 ViewModel 层中,因为它是一个 UI 状态.

I would think the undo system would some kind of integrated into the ViewModel layer, as it is a UI state.

有什么想法吗?

推荐答案

这是我用于我的项目的解决方案.事实证明,该解决方案运行良好.

Here is the solution I used for my project. The solution proved to be working perfectly.

系统正在使用撤消事件对象,其中每个撤消事件都知道如何撤消和重做自己.

The system is using undo event objects, where each undo event know how to undo and redo itself.

interface IUndoEvent
{
    void Undo();
    void Redo();
}

我仅通过实现 2 个撤消事件就能够构建系统:一个用于属性更改;一个用于集合更改.

I was able to build the system by implementing only 2 undo events: One for property changes; one for collection changes.

想法是这些事件通过直接修改模型来实现撤消/重做.

The idea is that those events implement the Undo/Redo by modifying the model directly.

class PropertyChangeUndoEvent : IUndoEvent
{
    private ModelBase _target;
    private string _propertyName;
    private object _oldValue;
    private object _newValue;

    public PropertyChangeUndoEvent(ModelBase target, string propertyName, object oldValue, object newValue)
    {
        _target = target;
        _propertyName = propertyName;
        _oldValue = oldValue;
        _newValue = newValue;
    }

    public void Undo()
    {
        SetValue(_oldValue);
    }

    public void Redo()
    {
        SetValue(_newValue);
    }

    private void SetValue(object value)
    {
        // Set Value on the _target using reflection (_propertyName)
    }
}

ViewModel 通过调用 ViewModelBase 函数负责创建撤销事件:

The ViewModel take care of creating undo events by calling ViewModelBase functions:

class MyViewModel : ViewModelBase
{
    public string Name
    {
        get { return _model.Name; }

        // The SetValue will create a undo event, and push it to the UndoManager
        set { SetValue(_model, "Name", value); }
    }
}

最后有一个UndoManager(项目单例),用于存储撤销栈和重做栈.

Finally, there is a UndoManager (project singleton) that stores the undo stack and the redo stack.

这篇关于在 WPF M-V-VM 中撤消,它如何适应?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆