1
votes

I am trying to implement the Undo/Redo functionality for the nodes of a tree in C# (treeView component). I have used the memento pattern but I am having trouble with the Redo part. I cannot see where my logic is flawed. Here are some snaps of the code

    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;
    }

In my form, before deleting a node I am calling the SaveMemento() method which creates a new Memento object representing the current state. The object is added to the _mementoStateList.

When Undo-ing and Redo-ing an action, I call the above Undo() and Redo() method.

I assume I am not saving the states in the right moment? Any input is highly appreciated!

2
When you set a new memento, you should reset your undo-state-list... Else that list could get a very weird contents is certain use-cases.JHBonarius

2 Answers

0
votes

When you create the memento you must do a deep clone of the object tree, otherwise the memento will just be a reference to the current state. In that case any change to the state will reflect to all mementos, ruining any attempt to keep a history of prior (or potential future) states.

0
votes

Maybe you should consider to implement Undo/redo using Command pattern, while with Memento if you need to store a lot of states(in fact the question is how many undo actions you will support) then implementation can be heavy.