« ObservableCollection » : différence entre les versions
De Banane Atomic
Aller à la navigationAller à la recherche
Aucun résumé des modifications |
|||
(5 versions intermédiaires par le même utilisateur non affichées) | |||
Ligne 118 : | Ligne 118 : | ||
</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'> | <filebox fn='ResettableObservableCollection.cs'> | ||
public sealed class | public sealed class AdvancedObservableCollection<T> : ObservableCollection<T> | ||
{ | { | ||
private bool | 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) | public void Reset(IEnumerable<T> items) | ||
Ligne 128 : | Ligne 147 : | ||
try | try | ||
{ | { | ||
this. | this.raiseCollectionChangedEvent = false; | ||
this.ClearItems(); | this.ClearItems(); | ||
this.AddRange(items); | // 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)); | base.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); | ||
} | } | ||
finally | finally | ||
{ | { | ||
this. | this.raiseCollectionChangedEvent = true; | ||
} | } | ||
} | } | ||
Ligne 144 : | Ligne 170 : | ||
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e) | protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e) | ||
{ | { | ||
if ( | if (this.raiseCollectionChangedEvent) | ||
{ | { | ||
base.OnCollectionChanged(e); | base.OnCollectionChanged(e); |
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); } } } |