I know that in VB .Net it is possible to define your custom Event Handler.
This is a way for a class to know when another one is listening to its events. This example code comes from MSDN :
Private Events As EventHandlerList
Public Custom Event MyEvent As EventHandler
AddHandler(value As EventHandler)
Events.AddHandler("Test", value)
End AddHandler
RemoveHandler(value As EventHandler)
Events.RemoveHandler("Test", value)
End RemoveHandler
RaiseEvent(sender As Object, e As EventArgs)
CType(Events("Test"), EventHandler).Invoke(sender, e)
End RaiseEvent
End Event
Now, this is how you can raise your custom event :
Private Sub MySub()
RaiseEvent MyEvent(Me, EventArgs.Empty)
End Sub
So far so good, no problem at all.
My question is, since in my class I have a direct access to the EventHandlerList, can I call it outside the custom event handler ? And if I do, is there any difference between what this sub does from the one above ?
Private Sub MySub2()
CType(Events("Test"), EventHandler).Invoke(Me, EventArgs.Empty)
End Sub
I know this probably is no good habits at all, I'm just curious as I may have a function that is passed an event name as String
so that way of raising the event might work for me, I would do something like :
Private Sub RaiseCustomEvent(EventName As String, Ev as EventArgs)
CType(Events(EventName), EventHandler).Invoke(Me, Ev)
End Sub
My question is, since in my class I have a direct access to the EventHandlerList, can I call it outside the custom event handler?
Yes.
And if I do, is there any difference between what this sub does from the one above?
No. The RaiseEvent statement simply calls the RaiseEvent part of your event declaration. The VB.NET spec says:
The RaiseEvent declaration takes the same parameters as the event delegate and will be called when a RaiseEvent statement is executed.
Note, though, that the MSDN example is broken---it raises a NullReferenceException
if no event handler is attached (Fiddle):
Public Module Module1
Public Sub Main()
Dim x As New T()
x.RaiseTestEvent()
End Sub
End Module
Public Class T
Private Events As New System.ComponentModel.EventHandlerList()
Public Custom Event MyEvent As EventHandler
AddHandler(value As EventHandler)
Events.AddHandler("Test", value)
End AddHandler
RemoveHandler(value As EventHandler)
Events.RemoveHandler("Test", value)
End RemoveHandler
RaiseEvent(sender As Object, e As EventArgs)
CType(Events("Test"), EventHandler).Invoke(sender, e)
End RaiseEvent
End Event
Public Sub RaiseTestEvent()
' Throws NullReferenceException if no event handler is attached.
RaiseEvent MyEvent(Me, EventArgs.Empty)
End Sub
End Class
For "regular" events, RaiseEvent
is just a NO-OP if no handler is attached (Fiddle). The VB spec says:
The RaiseEvent statement is processed as a call to the Invoke method of the event's delegate, using the supplied parameters, if any. If the delegate’s value is Nothing, no exception is thrown.