ObservableCollection
Apparence
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));
}
}
|
Resettable ObservableCollection
Send only 1 CollectionChanged event while resseting the whole collection, instead of sending a CollectionChanged event for each item removed or added.
ResettableObservableCollection.cs |
public sealed class ResettableObservableCollection<T> : ObservableCollection<T>
{
private bool muteEvents;
public void Reset(IEnumerable<T> items)
{
try
{
this.muteEvents = true;
this.ClearItems();
this.AddRange(items);
this.OnPropertyChanged(new PropertyChangedEventArgs("Count"));
this.OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
base.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
finally
{
this.muteEvents = false;
}
}
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (!this.muteEvents)
{
base.OnCollectionChanged(e);
}
}
}
|