> For the complete documentation index, see [llms.txt](https://docs.apryse.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.apryse.com/xamarin/get-started/samples/undoredotest.md).

# UndoRedoTest

Sample C# code for using Apryse SDK to take snapshots of edits and move between them using the API.

The Apryse SDK has a low-level facility for undo and redo operations. It is a API that applies to any edits made to a particular document (not just annotations). This sample C# code shows how to use Apryse SDK to walk back and forth on a fully general, bit-exact list of document states. Saving changes in a mode that is not 'incremental' will wipe out the undo-redo state list; the API will not be able to access old snapshots anymore. See the [undoing and redoing guide](/core/pdf-editing/undoredo.md) for more information. Learn more about our [Xamarin SDK](/core/get-started/frameworks/dotnet.md).

{% tabs %}
{% tab title="C#" %}
{% code lineNumbers="true" %}

```csharp
//---------------------------------------------------------------------------------------
// Copyright (c) 2001-2021 by PDFTron Systems Inc. All Rights Reserved.
// Consult legal.txt regarding legal and license information.     
//---------------------------------------------------------------------------------------

using System;
using pdftron;
using pdftron.Common;
using pdftron.PDF;
using pdftron.SDF;

using NUnit.Framework;

namespace MiscellaneousSamples
{
	/// <summary>
	//---------------------------------------------------------------------------------------
	// The following sample illustrates how to use the UndoRedo API.
	//---------------------------------------------------------------------------------------
	/// </summary>
	[TestFixture]
	public class UndoRedoTest
	{
		
		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[Test]
		public static void Sample()
		{
			// The first step in every application using PDFNet is to initialize the 
			// library and set the path to common PDF resources. The library is usually 
			// initialized only once, but calling Initialize() multiple times is also fine.

			// Relative path to the folder containing test files.
			const string input_path =  "TestFiles/";

			try  
			{
				// Open the PDF document.
                using (PDFDoc doc = new PDFDoc(Utils.GetAssetTempFile(input_path + "newsletter.pdf")))
                using (ElementBuilder bld = new ElementBuilder())	// Used to build new Element objects
                using (ElementWriter writer = new ElementWriter())	// Used to write Elements to the page	
                {
                    UndoManager undo_manager = doc.GetUndoManager();

					// Take a snapshot to which we can undo after making changes.
                    ResultSnapshot snap0 = undo_manager.TakeSnapshot();

                    DocSnapshot snap0_state = snap0.CurrentState();

                    Page page = doc.PageCreate();	// Start a new page

                        writer.Begin(page);		// Begin writing to this page

                    // ----------------------------------------------------------
                    // Add JPEG image to the file
                    Image img = Image.Create(doc, Utils.GetAssetTempFile(input_path + "peppers.jpg"));
                    Element element = bld.CreateImage(img, new Matrix2D(200, 0, 0, 250, 50, 500));
                    writer.WritePlacedElement(element);

                    writer.End();	// Finish writing to the page
                    doc.PagePushFront(page);

					// Take a snapshot after making changes, so that we can redo later (after undoing first).
                    ResultSnapshot snap1 = undo_manager.TakeSnapshot();

                    if (snap1.PreviousState().Equals(snap0_state))
                    {
                        Console.WriteLine("snap1 previous state equals snap0_state; previous state is correct");
                    }

                    DocSnapshot snap1_state = snap1.CurrentState();

                    doc.Save(Utils.CreateExternalFile("addimage.pdf"), SDFDoc.SaveOptions.e_incremental);

					if (undo_manager.CanUndo())
					{
						ResultSnapshot undo_snap = undo_manager.Undo();

						doc.Save(Utils.CreateExternalFile("addimage_undone.pdf"), SDFDoc.SaveOptions.e_incremental);

						DocSnapshot undo_snap_state = undo_snap.CurrentState();

						if (undo_snap_state.Equals(snap0_state))
						{
							Console.WriteLine("undo_snap_state equals snap0_state; undo was successful");
						}

						if (undo_manager.CanRedo())
						{
							ResultSnapshot redo_snap = undo_manager.Redo();
							
							doc.Save(Utils.CreateExternalFile("addimage_redone.pdf"), SDFDoc.SaveOptions.e_incremental);

							if (redo_snap.PreviousState().Equals(undo_snap_state))
							{
								Console.WriteLine("redo_snap previous state equals undo_snap_state; previous state is correct");
							}

							DocSnapshot redo_snap_state = redo_snap.CurrentState();

							if (redo_snap_state.Equals(snap1_state))
							{
								Console.WriteLine("Snap1 and redo_snap are equal; redo was successful");
							}
						}
						else
						{
							Console.WriteLine("Problem encountered - cannot redo.");
						}
					}
					else
					{
						Console.WriteLine("Problem encountered - cannot undo.");
					}
                }
			}
			catch (PDFNetException e) 
			{
				Console.WriteLine(e.Message);
				Assert.True(false);
			}
		}
    }
}
```

{% endcode %}
{% endtab %}
{% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.apryse.com/xamarin/get-started/samples/undoredotest.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
