class GenericBindingList<T> : BindingList<T>, IRaiseItemChangedEvents
{
private bool _raisesItemChangedEvents=false;
private PropertyDescriptorCollection _shape=null; public GenericBindingList() : base()
{
if (typeof(INotifyPropertyChanged).IsAssignableFrom(typeof(T)))
{
_raisesItemChangedEvents = true;
_shape = TypeDescriptor.GetProperties(typeof(T));
if (null == _shape)
{
_raisesItemChangedEvents = false;
}
}
}
private void HookPropertyChanged(T item)
{
INotifyPropertyChanged inpc = (item as INotifyPropertyChanged);
if (null != inpc)
{
inpc.PropertyChanged += new PropertyChangedEventHandler(Child_PropertyChanged);
}
}
private void UnhookPropertyChanged(T item)
{
INotifyPropertyChanged inpc = (item as INotifyPropertyChanged);
if (null != inpc)
{
inpc.PropertyChanged -= new PropertyChangedEventHandler(Child_PropertyChanged);
}
}
void Child_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (this.RaiseListChangedEvents)
{
if (string.IsNullOrEmpty(e.PropertyName))
{
ResetBindings();
}
else if (typeof(T).IsAssignableFrom(sender.GetType()))
{
T item = (T)sender;
int pos = this.IndexOf(item);
PropertyDescriptor pd = _shape.Find(e.PropertyName, true);
ListChangedEventArgs args = new ListChangedEventArgs(ListChangedType.ItemChanged, pos, pd);
OnListChanged(args);
}
}
}
#region BindingList<T> overrides
protected override void InsertItem(int index, T item)
{
if (_raisesItemChangedEvents)
{
HookPropertyChanged(item);
}
base.InsertItem(index, item);
}
protected override void RemoveItem(int index)
{
if (_raisesItemChangedEvents)
{
UnhookPropertyChanged(this[index]);
}
base.RemoveItem(index);
}
protected override void SetItem(int index, T item)
{
if (_raisesItemChangedEvents)
{
UnhookPropertyChanged(this[index]);
HookPropertyChanged(item);
}
base.SetItem(index, item);
}
protected override void ClearItems()
{
foreach (T item in this.Items)
{
UnhookPropertyChanged(item);
}
base.ClearItems();
}
#endregion
#region IRaiseItemChangedEvents Members
bool IRaiseItemChangedEvents.RaisesItemChangedEvents
{
get
{
return this._raisesItemChangedEvents;
}
}
#endregion
}