private static void HandleCollectionChanged <T>(IList <T> list, IListMonitor <T> monitor, NotifyCollectionChangedEventArgs e) { int position = 0; switch (e.Action) { case NotifyCollectionChangedAction.Add: position = e.NewStartingIndex; foreach (var item in e.NewItems?.Cast <T>() ?? Array.Empty <T>()) { monitor.NewItem(item, position++); } break; case NotifyCollectionChangedAction.Remove: position = e.OldStartingIndex; foreach (var item in e.OldItems?.Cast <T>() ?? Array.Empty <T>()) { monitor.DestroyItem(item, position++); } break; case NotifyCollectionChangedAction.Replace: if (e.NewItems == null || e.OldItems == null) { break; } for (int i = 0; i < e.NewItems.Count; i++) { if (e.OldItems[i] is T oldItem) { monitor.DestroyItem(oldItem, e.OldStartingIndex + i); } if (e.NewItems[i] is T newItem) { monitor.NewItem(newItem, e.NewStartingIndex + i); } } break; case NotifyCollectionChangedAction.Move: monitor.Move(e.OldStartingIndex, e.NewStartingIndex, e.NewItems?.Count ?? 0); break; case NotifyCollectionChangedAction.Reset: monitor.Reset(); if (e.OldItems != null) { Clearing(e.OldItems.OfType <T>(), monitor); } break; default: throw new ArgumentOutOfRangeException(); } }
private static void Clearing <T>(IEnumerable <T> list, IListMonitor <T> monitor) { int position = 0; foreach (var item in list) { monitor.DestroyItem(item, position++); } }