Events
are fully supported within the context of inheritance. If a base class defines
a Public
event, then that event can be raised by both the code in that base class and
from any subclasses derived from that base class.
For instance, we may have a simple base class such as:
Public Class Parent
Public Event ParentEvent()
Public Sub DoEvent()
RaiseEvent
ParentEvent()
End Sub
End Class
It is no surprise that code in this class
can raise the ParentEvent
event. However, we can then create a subclass such as:
Public Class SubClass
Inherits Parent
Public Sub DoSomething()
RaiseEvent
ParentEvent()
End Sub
End Class
This class is derived from Parent
through the use of the Inherits
keyword, gaining not only properties and methods, but also events from the base
class.
Events can be declared with any scope.
Those Private
in scope can only be received by the sending object, while those Public
in scope can be received by any object. Protected
events can only be received by objects created by the defining class or subclasses,
while events declared as Friend
can be received by any object within the VB.NET project.
Unlike methods, events cannot be overloaded
using the Overloads
keyword. A class can only define one event with any given name. Since any subclass
will automatically gain the event from its parent class, the Overrides
keyword makes no sense and cannot be used with events.
Shared Events
Events
may be declared as Shared
.
Shared methods can only raise shared events, not non-shared events. For instance:
Public
Class EventSource
Shared Event SharedEvent()
Public Shared Sub DoShared()
RaiseEvent SharedEvent()
End Sub
End
Class
A shared event can be raised by both shared and non-shared methods:
Public
Class EventSource
Public Event TheEvent()
Shared Event SharedEvent()
Public Sub DoSomething()
RaiseEvent TheEvent()
RaiseEvent SharedEvent()
End Sub
Public Shared Sub DoShared()
RaiseEvent SharedEvent()
End Sub
End
Class
Attempting to raise a non-shared event from a shared method will result in a syntax error.
Raising Events across Projects
In Beta 1, events do not appear to be fully implemented. In particular, events cannot be raised from code in one VB project into code in a separate VB project without some extra work on our part.
The Event
and RaiseEvent
keywords in VB.NET are actually implemented behind the scenes through the use
of delegates. We discussed the Delegate
keyword and the concept of delegates in Chapter 3. If we want to raise an event
from one VB.NET project and have it be received by code in another project,
we’ll have to use a mix of event and delegate concepts.
Implementing the Remote Event Source
While we’ll still use the
RaiseEvent
statement to raise the event, we need to declare the event somewhat differently
if it will be received by code in another VB.NET project. In particular, we
need to define the event as a delegate using the Delegate
statement – outside the class that will be raising the event.
Create a new Class Library project named
EventSource
and add a simple class to it named RemoteClass
.
Suppose we want to raise an event that
returns a String
parameter. We’d first declare a delegate with that type of parameter:
Public
Delegate Sub RemoteEventHandler(ByVal SomeString As String)
Normally VB.NET automatically creates this delegate for us behind the scenes. However, in Beta 1 this delegate is being created in such a way that it is not available from other projects – thus we must declare it explicitly.
Then, in the same code file, we can create the class that will raise the event:
Public
Class RemoteClass
Public Event RemoteEvent As RemoteEventHandler
Public Sub DoSomething()
RaiseEvent RemoteEvent(“My event”)
End Sub
End
Class
The key to success here lies in the declaration of the event itself:
Public Event RemoteEvent As RemoteEventHandler
The event doesn’t declare its parameters explicitly, instead relying on the delegate to make that declaration. Instead, the event is declared as a specific type – that being the delegate that we just defined.
Beyond that, the code to raise the event
is as we’d expect – just a simple RaiseEvent
statement:
RaiseEvent
RemoteEvent(“My event”)
It provides the parameter value to be returned as the event is raised.
Receiving the Remote Event
In a separate VB.NET project we can write code to receive the event. Add a Windows Application project to the current solution. Right-click on it and choose the Set As Startup Project option so it will be run when we press F5.
To have access to the class that raises
our event, we must add a reference to the EventSource
project we just created by using the Project
| Add Reference menu option.
With that done, we can add a button to the form and then open the form’s code window. Import the remote namespace:
Imports
System.ComponentModel
Imports
System.Drawing
Imports
System.WinForms
Imports
EventSource
In the form’s code we need to declare
the remote class using the WithEvents
keyword:
Public Class Form1
Inherits System.WinForms.Form
Private WithEvents
objRemote As RemoteClass
We can now see the event listed in the
Method
Name dropdown list in the upper-right of the code
window when the objRemote
entry is selected in the Class
Name dropdown in the upper-left. When we select this
entry the following code is created:
Public Sub objRemote_RemoteEvent()
Handles objRemote.RemoteEvent
End Sub
Unfortunately this code is not correct, as it has no provision for the parameter we’re passing. Strangely enough, the IDE knows this is in error (even though it created the code) and flags it as a syntax error. To fix the problem we just need to add the parameter into the declaration:
Public Sub objRemote_RemoteEvent(ByVal
Data As String) _
Handles
objRemote.RemoteEvent
Messagebox.Show(Data)
End
Sub
We’ve also added code to display the result in a dialog. If we add a button to the form with the following code, we can run the project to see the dialog displayed:
Protected Sub Button1_Click(ByVal
sender As Object, ByVal e As System.EventArgs)
objRemote = New RemoteClass()
objRemote.DoSomething()
End Sub
Though a bit of extra work in Beta 1, this technique allows us to raise events from one project and have them received by code in another project.
Comments