Redo is not possible after using AddCustomUndoEvent with Command

I have created a custom CustomUndoEventArgs Event inside of a command in my Rhino Plugin. The Undo event works fine and I’ve seen in the comment below that the Undo event is also called on Redo. However. My command doesn’t seem to allow for a Redo after Undo is called. My command, as well as my Commands Undo only modifies the UserDictionary of a RhinoObjects Curve Geometry. Do I need to modify the document to qualify for a Redo?

Here is some code, its stripped back and rename, but its the same basic thing.

using System;

using Rhino.Commands;
using Rhino;


namespace myplugin.mycommands
{

	// A custom command in my Plugin 
	public class MyCommand : SuperSpecialCommand
	{
		static MyCommand _instance;
		public MyCommand()
		{
			_instance = this;
			AllowUndoCreate = true;
		}

		public static MyCommand Instance => _instance;

		protected override Result RunSuperSpecialCommand(RhinoDoc doc, RunMode mode,
												SuperSpecialPlugIn plugin)
		{

			// Add data to a UserDictionary object.

			return Result.Success;
		}
	}


	// A wrapper class in the plugin that handles things for every command.
	public abstract class SuperSpecialCommand : Command
	{

		internal bool AllowUndoCreate { get; set; } = false;

		protected override Result RunCommand(RhinoDoc doc, RunMode mode)
		{
			Result runcommand = RunSuperSpecialCommand(doc, mode, plugin);

			if (AllowUndoCreate)
				doc.AddCustomUndoEvent($@"Undo {EnglishName}", OnUndoObjectCreate);

			return runcommand;
		}

		protected abstract Result RunSuperSpecialCommand(RhinoDoc doc, RunMode mode,
												SuperSpecialPlugIn plugin);

		private void OnUndoObjectCreate(object sender, Rhino.Commands.CustomUndoEventArgs e)
		{
			var objs = e.Document.Objects.AllObjectsSince(e.UndoSerialNumber);

			foreach (var obj in objs)
			{
				if (obj.IsSuperSpecialObject())
				{
					// Remove all UserDictionaryData of this object.
				}
			}
		}

	}

}

– cs

From my topic I quote this

they can redo it, so you must add the event handler again during the undo event handling

I don’t see you adding the event handler for redo in the undo code in OnUndoObjectCreate.

I missed that part but I’ve added it in (as below).
This allows me to Undo a Redo and Redo an Undo to my hearts content.
I just have to try and figure out how to put the data back in with the Redo part :slight_smile:.

		private void OnUndoObjectCreate(object sender, Rhino.Commands.CustomUndoEventArgs e)
		{
			var objs = e.Document.Objects.AllObjectsSince(e.UndoSerialNumber);

			foreach (var obj in objs)
			{
				if (obj.IsSuperSpecialObject())
				{
					// Remove all UserDictionaryData of this object.
				}
			}
			e.Document.AddCustomUndoEvent($@"Redo {EnglishName}", OnRedoObjectCreate);
		}

		private void OnRedoObjectCreate(object sender, Rhino.Commands.CustomUndoEventArgs e)
		{
			var objs = e.Document.Objects.AllObjectsSince(e.UndoSerialNumber);

			foreach (var obj in objs)
			{
				if (obj.IsSuperSpecialObject())
				{
					// Re-all UserDictionaryData of this object.
				}
			}
			e.Document.AddCustomUndoEvent($@"Redo {EnglishName}", OnUndoObjectCreate);
		}

1 Like