private void IncrementallyChangeList <T>(ObservableCollectionWorkaround <T> oldList, IList <T> newList, IComparer <T> comparer) { if (newList.Count == 0) { oldList.Clear(); } else { IList <T> list; if (oldList.Count == 0) { list = newList; } else { HashSet <T> oldItemsSet = new HashSet <T>((IEnumerable <T>)oldList); list = (IList <T>)Enumerable.ToList <T>(Enumerable.Where <T>((IEnumerable <T>)newList, (Func <T, bool>)(item => !oldItemsSet.Contains(item)))); oldItemsSet.ExceptWith((IEnumerable <T>)newList); EnumerableExtensions.ForEach <T>((IEnumerable <T>)oldItemsSet, (Action <T>)(item => ((Collection <T>)oldList).Remove(item))); } foreach (T obj in (IEnumerable <T>)list) { int index = oldList.BinarySearch(obj, comparer); if (index < 0) { index = ~index; } oldList.Insert(index, obj); } } }
// // Adds the given property to the specified property bucket (use // ModelCategoryEntry.BasicProperties, ModelCategoryEntry.AdvancedProperties, or // ModelCategoryEntry.GetBucket()) sorted using the specified comparer. // private void Add( PropertyEntry property, ObservableCollection <PropertyEntry> bucket, IComparer <PropertyEntry> comparer, bool fireCollectionChangedEvent) { if (property == null) { throw FxTrace.Exception.ArgumentNull("property"); } if (bucket == null) { throw FxTrace.Exception.ArgumentNull("bucket"); } if (comparer == null) { throw FxTrace.Exception.ArgumentNull("comparer"); } ObservableCollectionWorkaround <PropertyEntry> castBucket = bucket as ObservableCollectionWorkaround <PropertyEntry>; int insertionIndex = 0; if (castBucket == null) { Debug.Fail("Invalid property bucket. The property sort order will be broken."); } else { insertionIndex = castBucket.BinarySearch(property, comparer); if (insertionIndex < 0) { insertionIndex = ~insertionIndex; } } bucket.Insert(insertionIndex, property); if (fireCollectionChangedEvent) { FirePropertiesChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, property)); } }