Click here to Skip to main content
15,892,298 members
Articles / Programming Languages / C#
Article

User Action Based Undo/Redo in C#

Rate me:
Please Sign up or sign in to vote.
1.76/5 (11 votes)
2 Aug 20052 min read 42K   849   22   1
Illustrates how to implement Undo/Redo with GUI for Basic User Actions

Introduction

Often we come across situations where we need to undo some action done earlier. For example, you add many tree items to a tree view and then you realize you need to undo that action. In other words, you want to delete the items from the tree view. An Undo/Redo feature comes in handy. This feature could be implemented using many techniques. One useful technique is presented at http://www.dofactory.com/Patterns/PatternCommand.aspx. The feature illustrated here is based on this technique, namely the Command design pattern. For more description of this pattern, please visit the link given. However, the feature I have illustrated below adds much more to this. I have added GUI aspects (enabling menu items based on the current state of where Undo/Redo stack stands), which are not mentioned on that page. I have also added state-based behavior to the pattern. <o:p>

Basics are here:

The classes participating in the design of the feature are:<o:p>

Command: An abstract class that represents a basic user action such as 
adding items to a collection. Contains new (after user performs action) 
and old (before user performed action) object states.

ObjectState: Represents the state of the objects involved in Undo/Redo.

CalculatorCommand: Represents a user action.


UndoRedoManager: Manages the Undo/Redo engine by maintaining the Undo/Redo 
stack of Commands. It also maintains the current Undo and Redo stack pointers.

The Design

When a user adds a calculation by entering integer values in the operands text boxes, this is recognized as a command and a new object of type CalculatorCommand is created as follows.<o:p>

Command command = new CalculatorCommand();

The object states for this command are set appropriately since these are required when we undo or redo this command. The command is added to the stack as below.<o:p>

UndoRedoManager.GetInstance().AddCommandToUndoRedoStack(command);

When user selects Undo from the Edit menu, following code is executed:<o:p>

UndoRedoManager.GetInstance().ExecuteUndo();

In UndoRedoManager.ExecuteUndo(), the UndoRedoManager simply gets the command corresponding to the current undo stack pointer and calls UnExecute() on that command.

public bool ExecuteUndo()
{
    if (m_nCurrentUSP < 0)
    {
        return false;
    }

    Command entry = GetCommandWithLevelID(m_nCurrentUSP);

    if (entry != null)
    {

    entry.UnExecute();

    }

    return true;
}

The same is respectively done when user selects Redo. This is the beauty of the pattern. But you must properly set the object states so that the undo and redo makes the application fall down to proper states.

<o:p> 

In Command.UnExecute() (Undo), the old object state is restored and in Command.Execute() (Redo), the new object state is restored.

<o:p> 

You can unzip the sources and build the application in VS .Net 2003. Run the application and enter the operands, select the operator and click the "=" button to see the results. Do as many calculations as you wish. Simply undo/redo to see the calculations done earlier/later.

<o:p> 

Something about the ObjectState class:

This class can be used to store the object state. It can also store GUI states, such as state of some buttons when the action was performed. You can use this class to store anything related to making the application fall down to proper states. This class is not confined for GUI aspects only.

 

Future:

Here a GUI example is shown only to illustrate. You can use the idea of this feature to virtually undo/redo anything that could be associated with finite object states. Fuzzy object states cannot be used in this basic implementation. Please feel free to customize this feature.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
India India
I have been in the field of object-oriented programming for six years now. My areas of interest are discrete mathematics, programming in C++,C#, .Net framework.

Comments and Discussions

 
GeneralMy vote of 4 Pin
jraju1142128-Nov-11 1:52
jraju1142128-Nov-11 1:52 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.