# Customizing Undo and Redo Actions

Learn how to customize undo and redo actions in your application using the Undo/Redo feature with specific classes and manager class for tracking user actions.

## Content

With the undo/redo feature, you can add capability to your application to undo various actions in the spreadsheet performed by your end user. You can use the [UndoAction](/spreadnet/api/latest/online-win/FarPoint.Win.Spread/FarPoint.Win.Spread.UndoRedo.UndoAction.html) class and several specific classes that correspond with various user actions. There is also a manager class that keeps track of the end user actions that can be undone and re-done.
The [SpreadView](/spreadnet/api/latest/online-win/FarPoint.Win.Spread/FarPoint.Win.Spread.SpreadView.html) class and [FpSpread](/spreadnet/api/latest/online-win/FarPoint.Win.Spread/FarPoint.Win.Spread.FpSpread.html) class have properties, **AllowUndo** and **UndoManager**, which turn on and off the undo/redo feature and return the **UndoManager** for that **SpreadView** instance, respectively. Each **SpreadView** has its own **UndoManager**.

## Assigning the Actions

The [UndoAction](/spreadnet/api/latest/online-win/FarPoint.Win.Spread/FarPoint.Win.Spread.UndoRedo.UndoAction.html) class is an abstract class that inherits from **Action** and adds new methods to the class: **Undo** and **SaveUndoState**. It also inherits the **PerformAction** method from **Action**.
**SaveUndoState** is used to save undo state information (in fields of the class). **PerformAction** is used to perform the action. **Undo** is used to reverse the action (using the undo state information in the fields).
Each of the classes inheriting from **UndoAction** is designed to do one specific action (for example, edit a cell, resize a column, move a range, and so on), and to undo that action. All relevant information to do that action should be passed into the constructor for the object, and all relevant information to undo that action should be stored in the **SaveUndoState** implementation. Once the **UndoAction** object is created, the variables of that specific action are fixed (specified by the values passed to the constructor). For example, edit cell A1 in sheet1 and change the value to "test", resize column B to 24 pixels, and move the range C4:F6 to A1:D:3. The action can only do that specific action in that specific way.

## Managing the Actions

The [UndoManager](/spreadnet/api/latest/online-win/FarPoint.Win.Spread/FarPoint.Win.Spread.UndoRedo.UndoManager.html) class manages the undo and redo stacks. It keeps track of which actions have been done and undone, and in what order. An **UndoAction** must be passed into the **PerformUndoAction** method of **UndoManager** to do the action in order for it to be undoable by the **UndoManager**. When that happens, the **UndoManager** pushes the **UndoAction** onto the undo stack and calls **PerformAction** on the **UndoAction**, and then the **CanUndo** method returns true (indicating there is something to undo). When **CanUndo** returns false, that means the undo stack is empty, and there is no action ready to undo. You might want to use this to disable the **Undo** menu item in the **Edit** menu, for example, if your application has an **Edit** menu.
When an action is ready to undo, you can call **Undo** on the **UndoManager**, and it moves the last action performed from the undo stack to the redo stack, and calls **Undo** on the action, and then the **CanRedo** method returns True (indicating there is something to redo).
When **CanRedo** returns False, that means the redo stack is empty, and there is no action ready to redo. You might want to use this to disable the Redo menu item in the Edit menu, for example, if your application has Edit menu.
When an action is ready to redo, you can call **Redo** on the **UndoManager**, and it moves the last action undone from the redo stack to the undo stack, and calls **PerformAction** on the action, and the **CanUndo** method returns true.
You can call **PerformAction** on the **UndoManager** with a sequence of **UndoAction** objects, and it performs each action in sequence, and remembers each action and the order in which they are done. Then you can call **Undo** to undo some of those actions, and each can be re-done with **Redo** (and then un-done again with **Undo**).
But, when you call **PerformAction** to perform a new action, if there are any actions pending in the redo stack, those actions are cleared, and **CanRedo** returns False (that is, once you perform a new action, you will not be able to redo any actions that you have undone with **Undo**). That is why the **PushUndo** method in the **UndoManager** class has a flag to indicate whether the redo stack should be cleared when the action is pushed onto the undo stack.
Some of the **UndoAction** classes will be replacing **Action** objects in the action maps, so that those actions are routed through the **UndoManager** and become undoable. Other **UndoAction** classes will not be part of the action maps, but instead are used in the **SheetView** or **SpreadView** code to make the action undoable.

## Other API Updates

The input maps include new items to map the Ctrl+Z and Ctrl+Y keys to the new **UndoAction** and **RedoAction** action objects, respectively. These actions make calls into the **UndoManager** to the **Undo** and **Redo** methods, respectively.

## See Also

[Customizing Interaction in Cells](/spreadnet/docs/latest/online-win/overview/spwin-devguide/spwin-interactcell)
[Using Edit Mode and Focus](/spreadnet/docs/latest/online-win/overview/spwin-devguide/spwin-interactcell/spwin-cell-focus)
[Customizing User Selection and Deselection of Data](/spreadnet/docs/latest/online-win/overview/spwin-devguide/spwin-interactcell/spwin-interactselection)
[Using Drag Operations to Fill Cells](/spreadnet/docs/latest/online-win/overview/spwin-devguide/spwin-interactcell/spwin-cell-dragops)
[Using Validation](/spreadnet/docs/latest/online-win/overview/spwin-devguide/spwin-interactcell/spwin-cellvalid)
[Using Visible Indicators in the Cell](/spreadnet/docs/latest/online-win/overview/spwin-devguide/spwin-interactcell/spwin-cell-indicators)
[Customizing Interaction Based on Events](/spreadnet/docs/latest/online-win/overview/spwin-devguide/spwin-interactcell/spwin-cntrlevents)
[Adding Custom Context Menu to a Component](/spreadnet/docs/latest/online-win/overview/spwin-devguide/spwin-interactcell/spwin-cntrlcontextmenu)
[Using Double Click to Fill Cells](/spreadnet/docs/latest/online-win/overview/spwin-devguide/spwin-interactcell/spwin-cell-clicktofill)