vb.neteventsevent-handlingraiseevent

VB.NET calling event handlers by reference


Coming from Deplhi I'm used to be able to call event handlers directly from an instance using a simple

Button.OnMouseOver([arguments])

Now I'm on VB.NET and I can't find a way to fire the handlers of an event without the event actually being fired.

A bit of explanation of what I'm doing here: at the creation of a new form I parse its content to set all the colors according to a variable. Depending on whether or not a button is enabled it has different colors, but if a button is disabled at the moment of creation it still needs to go through the handler to have its color corrected.

This is what I'm using

AddHandler ButtonInstance.EnabledChanged, AddressOf Button_EnabledChanged
Button_EnabledChanged(ButtonInstance, New EventArgs)

This works correctly, still I'd like to be able to call that method directly from the object it's handling, simply because I don't always know the name of the handler of an event beforehand.

I keep being pointed towards RaiseEvent but it does not seem to do what I need.

Is there a way to retrieve the handler of an event or fire it without actually interfering with the instance?


Solution

  • The simple answer is no. I'm sure it's technically possible, using reflection, to get the list of delegates that have been added to the event and invoke each one, but it would be an ugly hack that should only be employed in the most desperate of circumstances. If you need to do that, the best way in VB.NET would be to setup a single event handler which always gets called when the event is raised (so that you can directly call it yourself too) and which then contains a list of delegates which it then calls in turn. In other words, use delegates to create your own event-like mechanism which provides the flexibility you need. For instance, something like this:

    Private _clickActions As New List(Of Action)()
    
    Public Sub AddClickAction(action As Action)
        _clickActions.Add(action)
    End Sub
    
    Public Sub PerformClickActions()
        For Each action As Action in _clickActions
            action?.Invoke()
        Next
    End Sub
    
    Private Sub Button1_Click(sender As Object, e As EventArgs)
        PerformClickActions()
    End Sub
    

    If you need to do it in multiple places, with different kinds of events, it seems like it would be pretty easy to create a common generic class for that kind of thing.