I have successfully used the UndoManager framework before in a PivotGrid which I thought would be very difficult. So, I am pretty familiar with the UndoManager already. However, I am having trouble undoing all. I cannot use transactions to log these changes so I am just relying on the following loop to do this for me:
UndoMgr.Suspend();
while (UndoMgr.CanUndo)
{ //UndoMgr.PreventMerge(); UndoMgr.Undo(); } UndoMgr.ClearHistory(); UndoMgr.Resume();
I tried this both with the suspend call at the beginning and without. The PreventMerge() sounded promising but also didn't work. If I have Suspend in there, I get an System.InvalidOperationException. I guess I can't Undo while suspended. If I take out the call to Suspend, then each Undo operation is logged as an undoable transaction and I get double the number of undos that I want and I end up right back where I was with the undos having no effect.
What I really want is a function UndoManager.UndoAll() that just undoes everything on the Undo list and nothing more. Is that possible? It seems like I've seen samples where you can undo N operations at once (not using transactions). Is there a way to undo all on the list and the just clear the history in a clean way.
Thanks!
Undo/redo are not allowed while suspended. I'm not sure what you mean by double the items.
To undo all and clear the history you could do something like but your while loop would essentially do the same thing:
if (mgr.TopUndoHistoryItem != null) { mgr.UndoHistory.Last().Execute(); mgr.ClearHistory(); }
{
mgr.UndoHistory.Last().Execute();
mgr.ClearHistory();
}
What I mean by getting double undos is that my Undo actions are getting logged with the Undo manager again my undo actually gets added back to the list. Here's what I mean. When a property changes that I want to undo, I log changes to the property with a call to AddPropertyChange(). Great. This adds the change to the list of undo actions. However, when I call Undo() again my property setter gets called and again calls AddPropertyChange() this time logging the undo.
Then the second time through my loop above, the undo manager still has pending undo actions (the last being the undo that was just applied) and then will undo my undo. Does any of that make sense?
Am I doing something fundamentally wrong when logging the undo actions in the first place?
This would be a whole lot easier if there was an API on Undo that could just UndoAll() and not log any of those undos in the undo history. Or at least support Undo operations while in suspended mode.