A group blog from members of the VB team
While helping some Windows API folks with some sample code this week, I stumbled upon...uh...I mean “carefully researched” an issue that you might find handy.
You may be aware that the RaiseEvent statement automatically checks to verify if an event handler exists before raising the event. If the event is Nothing, then there’s no event handler and RaiseEvent terminates. If the event is not Nothing, then RaiseEvent triggers the event.
However, what if you want to follow a different code path if the event is Nothing? Unfortunately, the RaiseEvent statement doesn’t return a value that could indicate whether the event was fired. So, what’s a developer to do?
The answer? When the VB compiler sets up your event, it creates a private variable for the event in the form of <event name>Event. So, if I set up an event named TriggerMe, the VB compiler creates an event variable named TriggerMeEvent. You can test this variable for Nothing. It’s as simple as that! (Note: You won't see this variable using Intellisense, but you can find it when debugging or through reflection.)
Here’s a quick example:
Public Event SolutionFound As EventHandler
Private Sub OnSolutionFound()
If SolutionFoundEvent IsNot Nothing Then
RaiseEvent SolutionFound(Me, New EventArgs())
' No event handler has been set.
MsgBox("There is no event handler. That makes me sad.")
Is this really a good idea?
I would expect the behaviour to be exactly the same if there is no event handler as if there is one that ends up doing nothing.
The only "safe" use I can imagine is perhaps skipping some checks after the event that you otherwise would have to do in case something was changed during the event.
I was already aware of this, but since the VB compiler already adds the code and checks for you is not like in C# where this is a common practice. So I wonder... when is this actually needed? never found a situation where the event variable is nothing.
"...it creates a public variable for the event.."
Not really. It creates a private member in the class.
Changed "public" to "private". Thanks for the catch.
It was really useful to me.
I might be missing the point here, but why not use a custom event. A RaiseEvent accessor is used in a custom event to specify the statements to execute when the event is raised using the RaiseEvent statement. Typically, this invokes a list of delegates maintained by the AddHandler and RemoveHandler accessors. But this can also be used to check for Nothing.
Any idea what to do if you assigned an eventhandler and it is still nothing?
I had four event handlers assigned that work, then added a fifth in the same location that always shows up as Nothing. The others still work properly and keep their pointers.
(using ASP.NET 3.5 sp1 with VB, by the way)
it is really useful for me.
SolutionFoundEvent is a hiden member, haha!
could not help me get a code snippet immediately thanks
This code really doesn't even compile???? What is going on here?
Like Help was saying above, I am having issues with the '<event name>Event' member coming up as nothing (but with a twist).
I have a test project that tests a custom control (treeview). The control's code is in the same solution (but different project), and the test project uses control's compiled dll to run the control in the test project.
when I insert a node with 'InsertNode' code line everything works as it should. However, if I reference the dll in a different project in another solution, the same exact 'InsertNode' code line will trigger the event, but the 'NodesInsertedEvent' will always be nothing. I have checked for scope issues and there doesn't seem to be any grounds to believe that this is the problem. Any suggestions as to what might be causing this behavior?