/// <summary> /// This is invoked when the collection changes. /// </summary> /// <param name="sender">Collection</param> /// <param name="e">Change event</param> void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { if (IgnoreChanges) { return; } var undoList = new List <CollectionChangeUndo>(); IList collection = (IList)sender; switch (e.Action) { case NotifyCollectionChangedAction.Add: undoList.AddRange(e.NewItems.Cast <object>().Select((item, i) => new CollectionChangeUndo(collection, CollectionChangeType.Add, -1, e.NewStartingIndex + i, null, item))); break; case NotifyCollectionChangedAction.Remove: undoList.AddRange(e.OldItems.Cast <object>().Select((item, i) => new CollectionChangeUndo(collection, CollectionChangeType.Remove, e.OldStartingIndex + i, -1, item, null))); break; case NotifyCollectionChangedAction.Replace: undoList.Add(new CollectionChangeUndo(collection, CollectionChangeType.Replace, e.OldStartingIndex, e.NewStartingIndex, e.OldItems[0], e.NewItems[0])); break; case NotifyCollectionChangedAction.Move: undoList.Add(new CollectionChangeUndo(collection, CollectionChangeType.Move, e.OldStartingIndex, e.NewStartingIndex, e.NewItems[0], e.NewItems[0])); break; } // If tracking undos, then add them to our list. if (_trackedUndoSet != null) { _trackedUndoSet.AddRange(undoList.Cast <ISupportUndo>()); } // Or add them directly to the undo manager else { var undoService = _undoService; if (undoService != null) { undoList.ForEach(ccu => undoService.Add(ccu)); } } }