Delay of Adding Event Handlers

RogerSchlueter-7899 1,526 Reputation points
2025-10-22T04:05:53.0666667+00:00

This is follow up to this thread. I use a Dispatcher to delay setting Event Handlers:

Private Delegate Sub ManageHandles()

Private Sub LoadMe(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
....
    Dim d As New ManageHandles(AddressOf HandleEvents)
    Dispatcher.BeginInvoke(DispatcherPriority.Background, d)Dim d As New ManageHandles(AddressOf HandleEvents)
    Dispatcher.BeginInvoke(DispatcherPriority.Background, d)
End Sub

Private Sub HandleEvents()
	AddHandler lbxPeople.SelectionChanged, AddressOf SelectPerson
	AddHandler cvsPeople.Filter, AddressOf PeopleFilter
End Sub

However, the filter event is still happening during the Load event. Specifically, the PeopleFilter event is fired immediately after the AddHandler cvsPeople.Filter is specified. But using the Dispatcher was supposed to prevent that from happening.

Windows development | Windows App SDK
{count} votes

1 answer

Sort by: Most helpful
  1. Danny Nguyen (WICLOUD CORPORATION) 4,985 Reputation points Microsoft External Staff Moderator
    2025-10-22T07:09:41.0633333+00:00

    Hi @RogerSchlueter-7899 ,

    Dispatcher.BeginInvoke delays when you hook the handlers, it does not stop WPF from immediately doing two normal initialization actions:

    1. ListBox SelectionChanged fires because the control sets or synchronizes its selection (e.g. selects the first item) during data binding.
    2. CollectionViewSource.Filter fires because as soon as a filter handler is attached WPF refreshes the view to ensure no unfiltered data is shown.

    So the first calls are inevitable. The practical fix is to make those early invocations harmless until your initialization finishes.

    I suggest using a readiness flag (plus optional DeferRefresh batching) so the first automatic refresh and selection change are ignored, then performing one real refresh once ready.

    
    Private _ready As Boolean = False
    Private Sub LoadMe(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
        cvsPeople = CType(Resources("cvsPeople"), CollectionViewSource)
        cvsPeople.Source = ocPeople
        Using cvsPeople.DeferRefresh()
            AddHandler cvsPeople.Filter, AddressOf PeopleFilter
            AddHandler lbxPeople.SelectionChanged, AddressOf SelectPerson
        End Using          ' Filter + selection may fire; _ready still False
        _ready = True
        cvsPeople.View.Refresh()   ' First real filter pass
    End Sub
     
    Private Sub PeopleFilter(sender As Object, e As FilterEventArgs)
        If Not _ready Then
            e.Accepted = True
            Return
        End If
        Dim p = TryCast(e.Item, Person)
        e.Accepted = (p IsNot Nothing) AndAlso ShouldShowPerson(p)
    End Sub
     
    Private Sub SelectPerson(sender As Object, e As SelectionChangedEventArgs)
        If Not _ready Then Return
        ' Real selection logic here
    End Sub
    
    

    Hope this helps. Feel free to reach out if there's any problem


Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.