# Undo and Redo

> Build Undo and Redo menu items with UndoActionName in Windows Forms, group changes with BeginUndoAction, clear the buffer after Load and turn off AllowUndo.

- **Product:** TX Text Control .NET for Windows Forms
- **Section:** Documentation
- **Kind:** Topic
- **Path:** TX Text Control .NET for Windows Forms > Document Editor > Editing Text > Undo and Redo
- **2046 words**
- **Web URL:** https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/editing-text/undo-redo/
- **LLMs URL:** https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/editing-text/undo-redo/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/editing-text/undo-redo/llms-full.txt

---

`TextControl` keeps an undo buffer of the changes made to a document, whether a user typed them or your code made them. Users step back and forward through it with Ctrl+Z and Ctrl+Y. Your code can offer the same commands in its own menus, show the name of the action that will be undone, group several changes into one step and switch the buffer off where it only costs time and memory.

The examples extend the form of [Create Your First Windows Forms Application](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/getting-started/document-editor/first-application/llms-full.txt), with the editor `textControl1`.

### How the Undo Buffer Works

- **Keys.** Ctrl+Z undoes the last action, and Ctrl+Y restores it. Both work without code.
- **Code counts, too.** Changes your code makes through the API are recorded, except changes made with the properties and methods of a header or footer, which [HeaderFooter.AddUndoUnit](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/headerfooter/addundounit-method/llms-full.txt) adds to the buffer. Each property set on the current selection is a step of its own, while a prepared `Selection` object that is assigned once is a single step; see [Selections and Caret Position](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/editing-text/selections/llms-full.txt).
- **Names.** Every step has a name, which [UndoActionName](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/undoactionname-property/llms-full.txt) and [RedoActionName](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/redoactionname-property/llms-full.txt) return. Your menus can show it, as in "Undo Insert Closing" below.

### Add Undo and Redo Commands

| Member | Does |
|---|---|
| [Undo](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/undo-method/llms-full.txt) | Undoes the last action |
| [Redo](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/redo-method/llms-full.txt) | Restores the last undone action |
| [CanUndo](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/canundo-property/llms-full.txt), [CanRedo](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/canredo-property/llms-full.txt) | Whether there is an action to undo or redo |
| `UndoActionName`, `RedoActionName` | The name of that action, or `null` if there is none |

An **Edit** menu calls `Undo` and `Redo` from its items and enables them with `CanUndo` and `CanRedo` each time it opens, as [Integrating Existing Menus and Toolbars](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/integration/menus-toolbars/llms-full.txt) builds it with a `MenuStrip`. With the action names, the items also say what they undo. The following `DropDownOpening` handler of that menu, whose items are named `undoToolStripMenuItem` and `redoToolStripMenuItem`, adds the name of the action to their text:

```csharp
private void EditToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
{
    // Show which action the next click undoes or redoes
    undoToolStripMenuItem.Enabled = textControl1.CanUndo;
    undoToolStripMenuItem.Text = textControl1.CanUndo ? "&Undo " + textControl1.UndoActionName : "&Undo";

    redoToolStripMenuItem.Enabled = textControl1.CanRedo;
    redoToolStripMenuItem.Text = textControl1.CanRedo ? "&Redo " + textControl1.RedoActionName : "&Redo";
}
```

Type a few words, make them bold and open **Edit**: the **Undo** item carries the name of the last step. Click it, and the text is regular again.

### Group Several Changes Into One Step

A command of your application often makes several changes, such as inserting text and formatting part of it. Without grouping, the user has to undo each of them separately. [BeginUndoAction](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/beginundoaction-method/llms-full.txt) starts a named group, and [EndUndoAction](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/endundoaction-method/llms-full.txt) closes it; everything in between is undone and redone in one step.

The following method inserts a closing formula at the input position as one step named "Insert Closing". Call it from a button or menu item of your form:

```csharp
private void InsertClosing()
{
    // Everything until EndUndoAction is undone in one step
    textControl1.BeginUndoAction("Insert Closing");

    try
    {
        textControl1.Selection.Text = "Kind regards,\r\n";

        Selection name = new Selection();
        name.Text = "Tim Typer";
        name.Bold = true;
        textControl1.Selection = name;
    }
    finally
    {
        textControl1.EndUndoAction();
    }
}
```

The code works as follows:

- `BeginUndoAction("Insert Closing")` opens the group. The name is what `UndoActionName` returns afterward; `null` or an empty string are allowed when no name is needed.
- `Selection.Text` inserts the first line, where "\\r\\n" ends the paragraph.
- The prepared `Selection` object inserts the bold name.
- `EndUndoAction` in the `finally` block closes the group even if a statement in between throws an exception.

After a click, **Edit** shows **Undo Insert Closing**, and one click removes both lines. [Search and Replace](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/editing-text/search-replace/llms-full.txt) uses the same pattern to undo all replacements at once.

### Clear the Buffer After Loading a Document

[Load](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/load-method/llms-full.txt) replaces the content of the editor. If the user shouldn't be able to undo their way back to the previous content, clear the buffer with [ClearUndo](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/clearundo-method/llms-full.txt) right after loading:

```csharp
private void LoadTemplate(string path)
{
    textControl1.Load(path, StreamType.WordprocessingML);

    // The user cannot undo the loading of the template
    textControl1.ClearUndo();
}
```

### Switch the Buffer Off

Recording every change costs time and memory. When your code builds a large document in the editor, for example a report, set [AllowUndo](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/allowundo-property/llms-full.txt) to `false` first, and back to `true` when the user takes over:

```csharp
textControl1.AllowUndo = false;

try
{
    // Build the document here
}
finally
{
    // Let the user undo their own changes again
    textControl1.AllowUndo = true;
}
```

The `finally` block switches the buffer on again even if the code in between throws an exception.

Documents that are created without being shown to a user are built with `ServerTextControl` instead; see [Document Processing](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-processing/llms-full.txt).

### Next Steps

- [Search and Replace](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/editing-text/search-replace/llms-full.txt): replace text in one undo step.
- [Clipboard Operations](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/editing-text/clipboard/llms-full.txt): copy, cut and paste.
- [Keyboard Shortcuts](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/editing-text/keyboard-shortcuts/llms-full.txt): all keys of the editor.
- [Track Changes](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/track-changes/llms-full.txt): record changes for review instead of undoing them.

---

## Nearby

- **Previous:** [Clipboard Operations](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/editing-text/clipboard/llms-full.txt)
- **Next:** [Search and Replace](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/editing-text/search-replace/llms-full.txt)
