/// <summary> /// Refreshes all items int list. /// </summary> /// <typeparam name="T">The type of the items</typeparam> /// <param name="this">This BindingList.</param> /// <param name="items">The updated item list.</param> /// <param name="keyGetter">The key getter to compare what items are added/removed/updated.</param> /// <param name="itemUpdateMethod">The item update method; takes the old and new item reference and returns the updated item.</param> public static void RefreshAll <T>(this BindingList <T> @this, IEnumerable <T> items, Func <T, string> keyGetter, Func <T, T, T> itemUpdateMethod) { var oldState = @this.RaiseListChangedEvents; try { @this.RaiseListChangedEvents = false; var oldKeys = @this.ToDictionary(keyGetter); var newKeys = items.ToDictionary(keyGetter); // remove not longer needed items foreach (var key in oldKeys.Keys.Where(k => !newKeys.ContainsKey(k))) { @this.Remove(oldKeys[key]); } foreach (var key in newKeys.Keys) { // add new items if (!oldKeys.ContainsKey(key)) { @this.Add(newKeys[key]); continue; } // update items var oldItem = oldKeys[key]; var newItem = itemUpdateMethod(oldItem, newKeys[key]); if (!ReferenceEquals(oldItem, newItem)) { @this[@this.IndexOf(oldItem)] = newItem; } } } finally { @this.RaiseListChangedEvents = oldState; if (oldState) { @this.ResetBindings(); } } }
/// <summary> /// Moves the given items relative. /// </summary> /// <typeparam name="TItem">The type of the items</typeparam> /// <param name="this">This BindingList.</param> /// <param name="items">The items.</param> /// <param name="delta">The delta.</param> public static void MoveRelative <TItem>(this BindingList <TItem> @this, IEnumerable <TItem> items, int delta) { #if NET40 Contract.Requires(@this != null); Contract.Requires(items != null); #endif if (delta == 0) { return; } var raiseEvents = @this.RaiseListChangedEvents; try { @this.RaiseListChangedEvents = false; var count = @this.Count - 1; if (delta < 0) { var start = 0; foreach (var item in items) { var index = @this.IndexOf(item); if (index < 0) { continue; } @this.RemoveAt(index); var newIndex = index + delta; @this.Insert(newIndex < 0 ? start++ : newIndex, item); } } else { var end = count; foreach (var item in items.Reverse()) { var index = @this.IndexOf(item); if (index < 0) { continue; } @this.RemoveAt(index); var newIndex = index + delta; if (newIndex > end) { #if NET40 Contract.Assume(end >= 0); #endif @this.Insert(end--, item); } else { @this.Insert(newIndex, item); } } } } finally { @this.RaiseListChangedEvents = raiseEvents; @this.ResetBindings(); } }