vb.neteventsobservablecollectioninstantiationinotifycollectionchanged

ObservableCollection.CollectionChanged not firing when collection is instantiated first before adding items


The title kind of covers it, I think. Consider:

Public Class DesignItem

    Private _effects As ObservableCollection(Of Effect) = New ObservableCollection(Of Effect)

    Public Property Effects() As ObservableCollection(Of Effect)
        Get
            Return _effects
        End Get
        Set(ByVal value As ObservableCollection(Of Effect))
            _effects = value
            If Effects.Count >= 1 Then ApplyEffects()
        End Set
    End Property
    
    Public Sub New()
        AddHandler Effects.CollectionChanged, AddressOf Effects_CollectionChanged
    End Sub
    
    Private Sub Effects_CollectionChanged(sender As Object, e As NotifyCollectionChangedEventArgs)
        Effects.Count >= 1 Then ApplyEffects()
    End Sub
    
    Public Sub ApplyEffects()
        'Stuff
    End Sub
End Class

When I do this (abrieviated):

Public Class MainApp
        Dim di As New DesignItem
        di.Effects.Add(myDropShadowEffect)      
End Class

The CollectionChanged Event fires and the Method Effects_CollectionChanged is invoked. However, if I do this (abrieviated):

Public Class MainApp
        Dim di As New DesignItem
        di.Effects = New ObservableCollection(Of Effect) From {myGreyScaleEffect}
        di.Effects.Add(myDropShadowEffect)      
End Class

The CollectionChanged Event is not fired and the Effects_CollectionChanged not invoked.

What am I misunderstanding here?


Solution

  • The call to AddHandler in the constructor of DesignItem only runs for the initial value of the Effects property. When you reassign the collection using the property setter, you have to add a new handler for the event to work (and remove the old one)

    I would consider whether having the setter is desirable in the first place. Without it, you arguably get a simpler class with better encapsulation