I encountered a situation while developing a WPF application that used the ObservableCollection class. Here is the description:
Problem:
A collection of items that contains several items (which themselves implement the INotifyPropertyChanged interface). I need to perform certain calculations: total items to be completed, total completed items, remaining items, etc. But when one of these items changed status and became completed, it was impossible to push the information (push) to a higher level.
Proposed Solution:
Using a thread that at each interval X, would validate the totals and update the data on the interface, in a pull (pull) manner. Not really liking this idea and trying to minimize pulls to favor pushes, I did a little research on the subject.
Implemented Solution:
I found a solution on StackOverflow, which derived from ObservableCollection and implemented the INotifyPropertyChanged interface, namely the ObservableCollectionEx<T> class. Here is the class itself:
public class ObservableCollectionEx : ObservableCollection where T : INotifyPropertyChanged
{
public ObservableCollectionEx()
: base()
{
}
protected override void OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
Unsubscribe(e.OldItems);
Subscribe(e.NewItems);
base.OnCollectionChanged(e);
}
private void Subscribe(System.Collections.IList iList)
{
if (iList != null)
{
foreach (T element in iList)
element.PropertyChanged += (x, y) => ContainedElementChanged(y);
}
}
private void Unsubscribe(System.Collections.IList iList)
{
if (iList != null)
{
foreach (T element in iList)
element.PropertyChanged -= (x, y) => ContainedElementChanged(y);
}
}
private void ContainedElementChanged(PropertyChangedEventArgs e)
{
OnPropertyChanged(e);
}
}
Very simple and especially generic. For usage, soren.enemaerke (the original author) proposes this small piece of code:
ObservableCollectionEx collection = new ObservableCollectionEx();
((INotifyPropertyChanged)collection).PropertyChanged += (x,y) => ReactToChange();
What I haven’t experimented with yet is extending this class to offer a bit more functionality that would be very useful, that will be for another time.