Hi Dave,
Internally, "Do" or "DoAync" is called on the OperationManager to execute the given operation - in this case the removing of a layer. Within the context of the Do or DoAsync, the operation is executed - i.e. removal of the layer(s) which, in turn, fires all relevant events - to include "Removing" and "Removed" events - _then_ , assuming completion was successful, the operation is added to the undo stack to allow it to be undone. Do now returns and/or DoAsync completes. An unsuccessful operation, conversely, would not be added (to be undone).
The best u can do, as u r trying to catch the operation "as it/when it" is added to the stack is to try a slight delay. So, something like:
//elsewhere - register for layers removed
ArcGIS.Desktop.Mapping.Events.LayersRemovedEvent.Subscribe((args) => {
DelayedListUndoOperations("LayersRemovedEvent",
args.Layers.Select(x => $"Remove layer: {x.Name}").ToList(),
1000);
});
//delay before reading operations
private async void DelayedListUndoOperations(string when,
List<string> opNames, int milliseconds) {
//non-blocking wait
await Task.Delay(milliseconds);
ListUndoOperations($"delayed {milliseconds}, {when}", opNames);
}
private void ListUndoOperations(string when, List<string> opNames) {
var opManager = MapView.Active?.Map?.OperationManager;
var ops =
opManager?.FindUndoOperations(o => !string.IsNullOrEmpty(o.Name)) ??
new List<Operation>();
System.Diagnostics.Debug.WriteLine(when);
if (ops.Count() == 0) {
System.Diagnostics.Debug.WriteLine("No Undo operations");
}
foreach (var op in ops) {
var match = opNames.Contains(op.Name) ? " (match)" : "";
System.Diagnostics.Debug.WriteLine($"{op.Name}{match}");
}
}
There is still an edge case however, where, depending on the delay, the user still has the opportunity - albeit brief - to execute the undo.