[GIS] How to get the current Undo and Redo item in ArcMap Operation Stack

arcgis-10.0arcmaparcobjects

I just posted this on ESRI forum and found this link so I am trying it here too:

Research ArcGIS Resource Center document – How to work with the operation stack:
http://help.arcgis.com/en/sdk/10.0/a…00000288000000

I found out the following:
"The Undo and Redo methods do not remove operations from the operation stack, but rather move an internal pointer up and down the stack."

Question:
So how do I get access to the operation that ArcMap is getting ready to Undo or Redo?

History and sample code:
I have been working on trying to manage ArcMap operation stack from a custom form. In the custom form we are actively editing data using ArcMap controls (add a sketch, modify feature, etc..) and we are also calling custom edits which are enclosed within StartOperation and StopOperation("EditOperationName").

In my code, I would like to evaluate the actual operation that ArcMap is getting ready to Undo or Redo and then perform a specified action if the Operation is a specified custom edit operation that was added within the edit session. I am able to return the name of all the menu string edit operations in the IOperationStack, I am able to call the mxDoc.OperationStack.Undo and Redo methods but I have not found a way to evaluate the actual Undo or Redo operation that ArcMap is pointing to.

Refer to the code sample below for the Undo button click:

Private Sub btnUndoLastTest_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnUndoLast.Click
'Dim pOperationStack As IOperationStack
'pOperationStack = _mxDocument.OperationStack

If _mxDocument.OperationStack.Count > 0 Then
Debug.Print("Before Undo is Selected")
For i = 0 To _mxDocument.OperationStack.Count - 1
Dim pOper As IOperation = _mxDocument.OperationStack.Item(i)
Debug.Print("operation number: " + i.ToString() + " Name: " + pOper.MenuString)

If pOper.CanUndo Then
Debug.Print("CanUndo Operation")
Else
Debug.Print("Can NOT Undo Operation")
End If
If pOper.CanRedo Then
Debug.Print("CanRedo Operation")
Else
Debug.Print("Can NOT Redo Operation")
End If
Next

'_editor.UndoOperation()
Dim pOperation As IOperation = _mxDocument.OperationStack.Item(_mxDocument.Operat ionStack.Count - 1)
Debug.Print("Operation Name = " + pOperation.MenuString.ToString())

If pOperation.MenuString = "Apply Rules" Then
'reset the IsApplyRules variable
_geoeditWorflow.IsApplyRulesSet = False
End If

pOperation = Nothing

_mxDocument.OperationStack.Undo()

Debug.Print("After Undo is Selected")
For i = 0 To _mxDocument.OperationStack.Count - 1
Dim pOper As IOperation = _mxDocument.OperationStack.Item(i)
Debug.Print("operation number: " + i.ToString() + " Name: " + pOper.MenuString)

If pOper.CanUndo Then
Debug.Print("CanUndo Operation")
Else
Debug.Print("Can NOT Undo Operation")
End If
If pOper.CanRedo Then
Debug.Print("CanRedo Operation")
Else
Debug.Print("Can NOT Redo Operation")
End If
Next
End If
End Sub

NOTE:
1) It is interesting to see that ArcMap acutually sets ALL Operations in its stack to either true or false for CanUndo or CanRedo properties regardless of wether this was the last operation that you applied undo or redo.

2) ArcMap keeps an Internal pointer to the stack and moves this pointer up and down. So, this means that the OperationStack is NOT reorganized (or even a true STACK.POP) based on an Undo and Redo.

Therefore it doesn't appear like there is an easy way to get the operation Item that ArcMap is getting ready to undo or redo. You can see in ArcMap tools what the undo or redo operation name is by either hovering over the undo and redo buttons or in the standard Menu toolbar –> Edit -> Undo "Name" or Redo "Name"

Any Ideas on how I can get the name of the NEXT Undo or Redo operation? I am trying to avoid having to write my own UndoStack and RedoStack if at all possible.

Thanks for any help you can provide.

Best Answer

There are two properties on the IOperationStack COM interface which are marked as hidden: UndoOperation and RedoOperation. In .NET (which you seem to be using), you will be able to use them right away, but in VBA/VB, you will need to tell the IDE to show them - open the VBA/VB Object Browser (press F2), right click in one of its windows to bring up the context menu, and select "Show Hidden Members". Intellisense will show these hidden members in a grayed color.

Also, the ESRI documentation can sometimes be VERY confusing and misleading: On the IOperationStack doc page, the description for UndoOperation property states: "Undoes a specified operation.". If you examine this property more closely, you will find that this is NOT what is does.

The actual documentation for IOperationStack.UndoOperation says:

Returns the 'current' operation on the OperationStack, without executing an undo.

which, if I get your question correctly, is exactly what you want. Similarly, you can examine the IOperationStack.RedoOperation as well.