1. Computing

How to Raise an Event in an Inherited Class

You can't do it directly, but you can do it indirectly.

By

One of the main breakthrough differences that made PC's different from mainframes (Trust me on this. I worked on mainframes for years.) is the change from procedural programming to event-driven programming. VB.NET is completely event-driven. In fact, the original Visual Basic has a great claim to the honor of being the programming language that brought event-driven programming to the mainstream. Since procedural programming on mainframes is almost extinct, making the mental switch from procedural programming to event-driven programming isn't such a problem anymore ... but it used to be a real bear.

Here's a fast example showing how events work in VB.NET. One way to write the code to declare, raise, and handle an event is shown below.


' Declare the event
Public Event theBaseClassEvent(
    ByVal eventArg As String)
' Raise the event
Public Sub eventRaisingSub()
    RaiseEvent theBaseClassEvent(
        "Handling theBaseClassEvent")
End Sub
' Handle the event
Public Sub eventHandlingSub(
    ByVal eventArg As String
    ) Handles Me.theBaseClassEvent
    Console.WriteLine(eventArg)
End Sub

To kick off the event processing, just execute the sub that raises the event.


Dim theClass As New eventClass
theClass.eventRaisingSub()

If you need a more detailed explanation, About Visual Basic describes event-driven programming in several articles. A basic introduction can be found in the article, Creating Your Own Event Code. Event-driven programming really starts with Windows, however, since detecting and reacting events depends on the way Windows works. The relationship to Windows is covered in The Form as an Application. A more detailed article about the actual code you need for events is described in Events - Program and Handle Your Own Unique Event in VB.NET.

The same technique doesn't work when you want to trigger the event from a derived class, however.

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

VB.NET simply doesn't allow it. The fix is relatively simple, if you have access to the base class code. All you have to do is add a Protected method to the base class and execute that instead.


' Handle the event
Public Sub eventHandlingSub(
    ByVal eventArg As String
    ) Handles Me.theBaseClassEvent
    Console.WriteLine(eventArg)
End Sub
' Handle event from a derived class
Protected Sub raiseEventFromDerivedClass(
    ByVal eventArg As String)
    RaiseEvent theBaseClassEvent(
        eventArg)
End Sub

When the event occurs in the derived class, just call the protected method in the base class.


Class derivedClass
    Inherits baseClass

    Public Shadows Sub eventRaisingSub()
        raiseEventFromDerivedClass(
            "Handling theBaseClassEvent")
    End Sub

End Class

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

This is actually what Protected and Protected Friend are for. The definition of Protected is:

Specifies that one or more declared programming elements are accessible only from within their own class or from a derived class.

Protected Friend simply adds "the same assembly" to the list of places where the programming elements are accessible. This allows developers to maintain security (because the events can't be accessed outside the chain of inheritance, or the assembly in the case of Protected Friend) but still allows developers to use common code provided in a base class. A longer article about these two "access modifiers" can be found here: Friend and Protected Friend in VB.NET.

Notice that the Protected sub in baseClass that actually processes an event raised in derivedClass is almost identical to the sub that processes an event raised in the baseClass. Keep in mind that there are a variety of ways that you can arrange the code (including using the AddHandler keyword instead of the Handles clause that is used here) and some might be more efficient in your situation. For example, you could combine the subs that handle the event and still allow custom code for the two cases like this:


Public Class baseClass
    ' Declare the events
    Public Event theEvent(
        ByVal eventArg As String)
    Public Sub eventRaisingSub(
        ByVal eventArg As String)
        eventArg &= " from baseClass"
        RaiseEvent theEvent(
            eventArg)
    End Sub
    ' Handle the event in both cases
    Public Sub eventHandlingSub(
        ByVal eventArg As String
        ) Handles Me.theEvent
        Console.WriteLine(eventArg)
    End Sub
    ' Handle event from derivedClass
    Protected Sub raiseEventFromDerivedClass(
        ByVal eventArg As String)
        eventArg &= " from derivedClass"
        RaiseEvent theEvent(
            eventArg)
    End Sub
End Class
Class derivedClass

To test this new syntax, an instance of both baseClass and derivedClass are created, but both are called in exactly the same way:


Dim eventParm As String = "Raising Event"
Dim theDerivedClass As New derivedClass
theDerivedClass.eventRaisingSub(eventParm)
Dim theBaseClass As New baseClass
theBaseClass.eventRaisingSub(eventParm)

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

See More About
  1. About.com
  2. Computing
  3. Visual Basic
  4. Quick Tips
  5. Raising Inherited Events

©2014 About.com. All rights reserved.