« ObservableCollection » : différence entre les versions
De Banane Atomic
Aller à la navigationAller à la recherche
(7 versions intermédiaires par le même utilisateur non affichées) | |||
Ligne 1 : | Ligne 1 : | ||
[[Category:CSharp]] | |||
= Description = | = Description = | ||
Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed. | Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed. | ||
Ligne 116 : | Ligne 117 : | ||
} | } | ||
</kode> | </kode> | ||
= 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. | |||
<filebox fn='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); | |||
} | |||
} | |||
} | |||
</filebox> |
Dernière version du 12 octobre 2021 à 20:26
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); } } } |