Search code examples
c#.netvb.netinotifypropertychangedbindinglist

INotifyPropertyChanged within child bindinglists


I have a parent class (implementing INotifyPropertyChanged), that has a Property that is a bindinglist of (ChildClass). The ChildClass also implements INotifyPropertyChanged.

If I bind something to the parentclass, it correctly reflects changes to the parentclass properties - with the exception of changes to:

  1. The number of elements in the BindingList(of ChildClass) [as a result of adding or deleting items in the list]. OR
  2. A change in a property of an item in the BindingList(of ChildClass)

If I bind something directly to an item of ChildClass (i.e. an item in the BindingList(Of ChildClass)) - that works too.

How to wire this up so #1 and #2 are appropriately reflected in bound objects?

Here's the vb version of Paul's great answer. Without the List_Changed event, changes to the BindingList were not being correctly propagated up the chain in a nested business object. With it, they are!

Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Private WithEvents m_children As IBindingList

Public Sub NotifyPropertyChanged(<CallerMemberName()> Optional ByVal propertyName As String = Nothing)
    RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub

Public Property Children As IBindingList
    Get
        Return m_children
    End Get
    Set
        m_children = Value
        NotifyPropertyChanged()
    End Set
End Property

Private Sub m_children_ListChanged(sender As Object, e As ListChangedEventArgs) Handles m_children.ListChanged
    NotifyPropertyChanged(NameOf(Children))
End Sub

Solution

  • BindingList<T> proovides the event BindingList<T>.ListChanged that

    Occurs when the list or an item in the list changes.

    You can easily implement an event-handler in your parent class and wire it up to ListChanged. (I've assumed the children property - the BindingList<ChildClass> - to be named Children)

    private void Children_OnListChanged(object sender, EventArgs e)
    {
        OnPropertyChanged(nameof(Children));
    }
    

    With OnPropertyChanged you can notify subscribers, that the Childrenproperty has changed. If there is no implementation in your class, yet, it may look like the following

    private void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    

    where [CallerMemberName] (which lives in System.Runtime.CompilerServices namespace) is a hint for the compiler to use the name of the property that has called OnPropertyChanged if no explicit value is passed.