1. Technology

Shared Events in VB.NET

More use for the Share keyword!

By

Updated April 17, 2012

This article is part three of three about the use of the Share keyword. Part one, Shared and Instance Members in VB.NET, covered the more frequently used shared methods and properties in VB.NET. Part two, Shared Variables in VB.NET, covered shared variables - not a well known technique. Part three, this article, covers the use of shared events. There is a specific case - when parameterized constructors have to be used - when shared events are useful. This article shows how it's done.

Coding events can be confusing too. Of course, events are used constantly in VB.NET but the code for declaring them, handling them, and raising them is generally hidden and they work so well that you just don't find a need to understand how it's all done behind the scenes very often. But if you do have a need, there's a whole series of articles about coding events that starts here: Events Using Your Own Code in VB.NET

To have a starting point, here's the most basic event processing code I can think of:


Public Class Form1
    WithEvents theEventClass As New theClass
    Private Sub Form1_Load(
        sender As System.Object,
        e As System.EventArgs
        ) Handles MyBase.Load
        theEventClass.EventSub()
    End Sub
    Private Sub HandleTheEvent() _
        Handles theEventClass.theEvent
        Console.WriteLine("theEvent handled")
    End Sub
End Class
Public Class theClass
    Public Event theEvent()
    Public Sub EventSub()
        RaiseEvent theEvent()
    End Sub
End Class

In fact, the class that is instantiated, theClass, is so basic that it only contains the minimum event processing code. Let's add a little more to that class, and - more significantly here - change the modifier of the event to "Shared".


Public Class theClass
    Shared Event theSharedEvent()
    Public Property theProperty As Integer
    Public Sub NonSharedSub()
        theProperty = 54321
        RaiseEvent theSharedEvent()
    End Sub
End Class

The code still works! This leads us to the first rule. A shared event can be raised by a shared or non-shared method. No difference. We'll see later why this is important.

The code was also upgraded a bit to reflect the other changes, but these don't affect the logic. Here's the revised event handler code:


Private Sub HandleTheEvent() _
    Handles theEventClass.theSharedEvent
    Console.WriteLine("theEvent handled: " &
        CStr(theEventClass.theProperty))
End Sub

Lets add a shared method now and see how that works.

--------
Click Here to display the illustration
--------

It doesn't work too well. The shared method can't access the property. So, let's change the property to shared and see how that works.

--------
Click Here to display the illustration
--------

That doesn't work either! Now the event handler code can't access the property. It's a problem either way. What can you do about that?

Like so many things in programming, the answer isn't even a part of anything you have changed so far. The answer is that shared events can't use the "Handles / WithEvents" keywords. You have to use an AddHandler statement instead.


AddHandler _
    theClass.theSharedEvent,
    AddressOf HandleTheEvent

But your problems aren't over yet. Now, the compiler is complaining that, "Reference to a non-shared member requires an object reference." when the code references "theClass.NonSharedSub()". (Before, it was executing the sub in the class directly ... functionally about the same as a shared sub.) So you have to instantiate the class and reference the instance instead. Both of these (in this program) are done in the form load sub.


Private Sub Form1_Load(
    sender As System.Object,
    e As System.EventArgs
    ) Handles MyBase.Load
    AddHandler _
        theClass.theSharedEvent,
        AddressOf HandleTheEvent
    Dim anInstanceClass As New theClass
    anInstanceClass.NonSharedSub()
    theClass.SharedSub()
End Sub

Note that both shared and non-shared methods are executed from the class, and both raise the same shared event.

--------
Click Here to display the illustration
--------

To illustrate why this can be important, suppose your code required a parameterized "New" constructor. For this example, let's pass a value that will be saved in the shared property.


Public Sub New(PropVal As Integer)
    theProperty = PropVal
    RaiseEvent theSharedEvent()
    Console.WriteLine("New Constructor Executed")
End Sub

If you're using a shared method, then a parameterized constructor is a required, non-shared method that must be in the same class. That's exactly what has already been demonstrated, so this allows you to use the shared event in the constructor.

--------
Click Here to display the illustration
--------

The illustration shows the code in action in a generic form. But you may need this kind of code if you want your constructor to trigger some specific action somewhere else, such as logging the creation of objects. You might also want to count object creation. The key is knowing that it's available when you do need it.

  1. About.com
  2. Technology
  3. Visual Basic
  4. Using VB.NET
  5. Shared Events in VB.NET

©2014 About.com. All rights reserved.