I have ObservableCollection<T>
collection, and I want to replace all elements with a new collection of elements, I could do:
collection.Clear(); // OR: collection.ClearItems(), BTW, what's the difference between these two methods?
Using foreach
to collection.Add
one by one; // but this will fire multiple times
Same when adding a collection of elements.
EDIT:
I found a good library: http://www.codeproject.com/Articles/249311/Enhanced-ObservableCollection But it seems that it does NOT support silverlight.
Answer: 1
You can achieve this by subclassing ObservableCollection
and implementing your own ReplaceAll
method. The implementation of this methods would replace all the items within the internal Items
property, then fire a CollectionChanged
event. Likewise, you can add an AddRange
method. For an implementation of this, see the answer to this question:
The difference between Collection.Clear
and Collection.ClearItems
is that Clear
is a public API method, whereas ClearItems
is protected, it is an extension point that allows your to extend / modify the behaviour of Clear
.
Answer: 2
ColinE is right with all his informations. I only want to add my subclass of ObservableCollection that i use for this specific case.
public class SmartCollection<T> : ObservableCollection<T> { public SmartCollection() : base() { } public SmartCollection(IEnumerable<T> collection) : base(collection) { } public SmartCollection(List<T> list) : base(list) { } public void AddRange(IEnumerable<T> range) { foreach (var item in range) { Items.Add(item); } this.OnPropertyChanged(new PropertyChangedEventArgs("Count")); this.OnPropertyChanged(new PropertyChangedEventArgs("Item[]")); this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); } public void Reset(IEnumerable<T> range) { this.Items.Clear(); AddRange(range); } }
by : Jehofhttp://stackoverflow.com/users/83039Answer: 3
Here is what I implemented for other folks' reference:
// http://stackoverflow.com/questions/13302933/how-to-avoid-firing-observablecollection-collectionchanged-multiple-times-when-r // http://stackoverflow.com/questions/670577/observablecollection-doesnt-support-addrange-method-so-i-get-notified-for-each public class ObservableCollectionFast<T> : ObservableCollection<T> { public ObservableCollectionFast() : base() { } public ObservableCollectionFast(IEnumerable<T> collection) : base(collection) { } public ObservableCollectionFast(List<T> list) : base(list) { } public virtual void AddRange(IEnumerable<T> collection) { if (collection.IsNullOrEmpty()) return; foreach (T item in collection) { this.Items.Add(item); } this.OnPropertyChanged(new PropertyChangedEventArgs("Count")); this.OnPropertyChanged(new PropertyChangedEventArgs("Item[]")); this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); // Cannot use NotifyCollectionChangedAction.Add, because Constructor supports only the 'Reset' action. } public virtual void RemoveRange(IEnumerable<T> collection) { if (collection.IsNullOrEmpty()) return; bool removed = false; foreach (T item in collection) { if (this.Items.Remove(item)) removed = true; } if (removed) { this.OnPropertyChanged(new PropertyChangedEventArgs("Count")); this.OnPropertyChanged(new PropertyChangedEventArgs("Item[]")); this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); // Cannot use NotifyCollectionChangedAction.Remove, because Constructor supports only the 'Reset' action. } } public virtual void Reset(T item) { this.Reset(new List<T>() { item }); } public virtual void Reset(IEnumerable<T> collection) { if (collection.IsNullOrEmpty() && this.Items.IsNullOrEmpty()) return; // Step 0: Check if collection is exactly same as this.Items if (IEnumerableUtils.Equals<T>(collection, this.Items)) return; int count = this.Count; // Step 1: Clear the old items this.Items.Clear(); // Step 2: Add new items if (!collection.IsNullOrEmpty()) { foreach (T item in collection) { this.Items.Add(item); } } // Step 3: Don't forget the event if (this.Count != count) this.OnPropertyChanged(new PropertyChangedEventArgs("Count")); this.OnPropertyChanged(new PropertyChangedEventArgs("Item[]")); this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); } }
by : Peter Leehttp://stackoverflow.com/users/301336
No comments:
Post a Comment
Send us your comment related to the topic mentioned on the blog