ObservableCollection
De Banane Atomic
(Redirigé depuis Observablecollection)
Aller à la navigationAller à la recherche
Description
Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed.
OnCollectionChanged
var oc = new ObservableCollection<int>(); oc.CollectionChanged += OnCollectionChanged; oc.Add(1); oc.Add(9); oc[0] = 2; oc.Move(0, 1); // move item at index 0 to index 1 oc.RemoveAt(0); oc.Clear(); private static void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { // sender: ObservableCollection // e.Action : Add // e.NewItems: ReadOnlyList<int>() { 1 } // e.Action : Replace // e.OldItems: ReadOnlyList<int>() { 1 } // e.NewItems: ReadOnlyList<int>() { 2 } // e.Action : Move // e.OldItems: ReadOnlyList<int>() { 2 } // e.NewItems: ReadOnlyList<int>() { 2 } // e.Action : Remove // e.OldItems: ReadOnlyList<int>() { 2 } // Clear // e.Action : Reset } |
Listen of item changes
var oc = new ObservableCollection<Item>(); oc.CollectionChanged += OnCollectionChanged; oc.Add(new Item { Name = "One" }); oc[0].Name = "One+"; private static void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { switch (e.Action) { case NotifyCollectionChangedAction.Add: RegisterItemPropertyChanged(e.NewItems); break; case NotifyCollectionChangedAction.Remove: UnRegisterItemPropertyChanged(e.OldItems); break; case NotifyCollectionChangedAction.Replace: UnRegisterItemPropertyChanged(e.OldItems); RegisterItemPropertyChanged(e.NewItems); break; default: break; } } private static void RegisterItemPropertyChanged(IList newItems) { foreach (INotifyPropertyChanged item in newItems) { if (item != null) { item.PropertyChanged += new PropertyChangedEventHandler(ItemPropertyChanged); } } } private static void UnRegisterItemPropertyChanged(IList oldItems) { foreach (INotifyPropertyChanged item in oldItems) { if (item != null) { item.PropertyChanged -= new PropertyChangedEventHandler(ItemPropertyChanged); } } } private static void ItemPropertyChanged(object sender, PropertyChangedEventArgs e) { // sender: Item // e.PropertyName: Name } class Item : INotifyPropertyChanged { private string _name; public string Name { get { return _name; } set { _name = value; OnPropertyChanged("Name"); } } public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string propertyName) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); } } |
Advanced ObservableCollection
- Send only 1 CollectionChanged event while adding multiple elements at the same time, instead of sending 1 CollectionChanged event per item added.
- Send only 1 CollectionChanged event while resseting the whole collection, instead of sending 1 CollectionChanged event for clear/reset and one for each item added.
ResettableObservableCollection.cs |
public sealed class AdvancedObservableCollection<T> : ObservableCollection<T> { private bool raiseCollectionChangedEvent = true; public void AddRange(IEnumerable<T> items) { try { this.raiseCollectionChangedEvent = false; CollectionExtensions.AddRange(this, items); this.OnPropertyChanged(new PropertyChangedEventArgs("Count")); this.OnPropertyChanged(new PropertyChangedEventArgs("Item[]")); base.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); } finally { this.raiseCollectionChangedEvent = true; } } public void Reset(IEnumerable<T> items) { try { this.raiseCollectionChangedEvent = false; this.ClearItems(); // protected override void ClearItems() // { // this.CheckReentrancy(); // base.ClearItems(); // this.OnPropertyChanged("Count"); // this.OnPropertyChanged("Item[]"); // this.OnCollectionReset(); // } // private void OnCollectionReset() => this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); CollectionExtensions.AddRange(this, items); base.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); } finally { this.raiseCollectionChangedEvent = true; } } protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e) { if (this.raiseCollectionChangedEvent) { base.OnCollectionChanged(e); } } } |