撤消/重做纪念品模式c#

时间:2017-02-10 13:27:20

标签: c# design-patterns undo redo memento

我正在尝试在C#(treeView组件)中为树的节点实现撤消/重做功能。我使用了memento模式,但我遇到了重做部分的问题。我无法看出我的逻辑存在缺陷。以下是代码的一些快照

    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()方法。

我认为我不是在正确的时刻保存状态? 任何意见都非常感谢!

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

也许您应该考虑使用Command模式实现撤消/重做,而使用Memento则需要存储很多状态(实际上问题是您将支持多少撤消操作)然后实施可能很重。