Alex Rivera | Logout

How to implement good and efficient undo/redo functionality for a TextBox

Asked 2009-02-28T09:35:54.007
32

I have a TextBox which I would like to implement undo/redo functionality for. I have read that it might have some slight undo functionality already, but that it is buggy? Anyways, I would like to implement both undo and redo functionality also just to learn how you would go ahead and do that.

I have read about the Memento Pattern and looked some on a Generic Undo/Redo example on CodeProject. And the pattern kiiind of makes sense. I just can't seem to wrap my head around how to implement it. And how to do it effeciently for the contents of a TextBox.

Of course I could just store textbox.Text when TextChanges, but that would hug up quite a lot of memory pretty fast, especially if the TextBox contained a lot of text.

So anyways, I'm looking for some advice on how to implement a good, clear and efficient way of implementing this functionality. Both in general and especially for a TextBox c",)

Edit
Report

2 Answers

2

A good solution can be found here:

Add Undo/Redo or Back/Forward Functionality to your Application

Undo/Redo Capable TextBox (winforms)

The code is in VB.NET, but you can easily convert it to C# without much efforts. Online converters are also available.

answered 2012-04-20T11:56:42.870
0

The smartest way is with immutable persistent objects. Never make a change to an object only make new objects that change slightly from the old version. This can be done somewhat efficiently by only cloning parts of the tree on the hot path.

I have an example of an undo stack written with minimal code

 [Fact]
public void UndoStackSpec()
{
    var stack = new UndoStack<A>(new A(10, null));

    stack.Current().B.Should().Be(null);

    stack.Set(x => x.B, new B(20, null));

    stack.Current().B.Should().NotBe(null);
    stack.Current().B.P.Should().Be(20);

    stack.Undo();

    stack.Current().B.Should().Be(null);

}

where A and B as classes with private setters on all properties ie immutable

class A : Immutable
{
    public int P { get; private set; }
    public B B { get; private set; }
    public A(int p, B b)
    {
        P = p;
        B = b;
    }
}

class B : Immutable
{
    public int P { get; private set; }
    public C C { get; private set; }
    public B(int p, C c)
    {
        P = p;
        C = c;
    }
}

class C : Immutable
{
    public int P { get; private set; }
    public C(int p)
    {
        P = p;
    }
}

you can find the full source here https://gist.github.com/bradphelan/5395652

answered 2013-04-16T13:19:06.163

Your Answer