1

我正在尝试在 C#(treeView 组件)中为树的节点实现撤消/重做功能。我使用了纪念品模式,但我在重做部分遇到了麻烦。我看不出我的逻辑在哪里有缺陷。这是代码的一些快照

    private List<Memento> _mementoStateList= new List<Memento>();
    private List<Memento> _undoStateList= new List<Memento>();
    public Memento Memento { get{return null;}
        set{_mementoStateList.Add(value);} }

    public Memento Undo()
    {
        if (!_mementoStateList.Any()) return null;
        Memento m = _mementoStateList.Last();
        _undoStateList.Add(m);
        _mementoStateList.Remove(m);
        return m;
    }

    public Memento Redo()
    {
        if (!_undoStateList.Any()) return null;
        Memento m = _undoStateList.Last();
        _mementoStateList.Add(m);
        _undoStateList.Remove(m);
        return m;
    }

在我的表单中,在删除节点之前,我调用了 SaveMemento() 方法,该方法创建了一个表示当前状态的新 Memento 对象。该对象被添加到 _mementoStateList。

当撤消和重做一个动作时,我调用上面的 Undo() 和 Redo() 方法。

我假设我没有在正确的时刻保存状态?任何输入都非常感谢!

4

2 回答 2

0

也许您应该考虑使用命令模式来实现撤消/重做,而使用Memento如果您需要存储大量状态(实际上问题是您将支持多少撤消操作),那么实现可能会很繁重。

于 2017-02-11T14:21:31.737 回答
0

当您创建备忘录时,您必须对对象树进行深度克隆,否则备忘录将只是对当前状态的引用。在这种情况下,对状态的任何更改都将反映到所有的纪念品上,从而破坏任何保留先前(或潜在的未来)状态历史的尝试。

于 2017-02-10T13:37:20.950 回答