Disabling Undo/Redo for certain model changes?


Using WPF, I’m trying to prevent a Node Delete to be “undoable” (i.e., if a Node has been deleted, I don’t want it to be recreated on an Undo)

I’m trying to understand how the UndoManager works. My understanding was that for an operation to be “undoable”, it had to be enclosed in StartTransaction/CommitTransaction. So, to this end, I overloaded the CommandHandler.Delete() so it’s not within a Transaction. The end result is that the Delete operation is still there, but not considered as a independant operation (i.e., it will be part of another subsequent operation when doing an Undo).

So I’m wondering what is the best approach. I think I could achieve this by overriding the UndoManager.SkipEvent method, filtering the Delete from there. Is this the only way? Is it possible/desirable to get the same result from the CommandHandler?



It’s easiest to do:

public class CustomCommandHandler : CommandHandler { public override void Delete() { this.Diagram.Model.SkipsUndoManager = true; base.Delete(); this.Diagram.Model.SkipsUndoManager = false; } }
And of course install the CustomCommandHandler by:

<go:Diagram ...> <go:Diagram.CommandHandler> <local:CustomCommandHandler /> </go:Diagram.CommandHandler> </go:Diagram>


Simple and effective!

Thanks you very much!



Any way to do the same thing with the Node addition? Obviously, there is no Command for that, but trying to set the Model.SkipsUndoManager around the node addition does not work, an Undo will actually remove the Node.

<br />myDiagram.Model.SkipsUndoManager = true; <br />myDiagram.Model.AddNode(node); <br />myDiagram.Model.SkipsUndoManager = false; <br />

Looks like the UndoManager.SkipEvent() is not called either in this case, so I’m not sure how to proceed.


I just tried this, and it worked as I think both of us would expect.

Perhaps you forgot to perform the AddNode within a transaction?

Here is what I did:

<br />myDiagram.Model.StartTransaction("AddNode"); <br />myDiagram.Model.SkipsUndoManager = true; <br />myDiagram.Model.AddNode(node); <br />myDiagram.Model.SkipsUndoManager = false; <br />myDiagram.Model.CommitTransaction("AddNode"); <br />

I was not sure about the order, so I also tried this:

<br />myDiagram.Model.SkipsUndoManager = true; <br />myDiagram.Model.StartTransaction("AddNode"); <br />myDiagram.Model.AddNode(node); <br />myDiagram.Model.CommitTransaction("AddNode"); <br />myDiagram.Model.SkipsUndoManager = false; <br />

Same result, doing an Undo will remove the newly added Node. I’m using the default UndoManager (through the “model.HasUndoManager = true;” line)

Not sure what I’m doing different from you. Anything else I should be aware?



Take a look at the …Model.UndoManager.CompoundEdits list, or perhaps at the value of UndoManager.EditToUndo, and see if the ModelChange.AddedNode event is recorded there.

Or, since you may already have a custom UndoManager, see if the UndoManager.HandleModelChanged method is being called even though …Model.SkipsUndoManager is true.

Ok, monitoring the UndoManager.HandleModelChanged() helped my find the problem.

It was related to the (custom) LayoutManager, where I recalculate a Node location. So the Undo was actually applied to the Location, which in turn caused the Node to be Created (looks like the modification of a Node that does not exist forces its creation).

Thanks you for you help, much appreciated!