2005-02-23
| Rate This Article: | Add This Article To: |
A class that is defined in VB.Net gives you the option of defining one or more events that the class can raise. These class events are different from the user events, such as mouse clicks and key presses, that are an important part of the VB.Net programming model. Rather, class events are events that can triggered in code in the class and can then be detected by the host program. There are lots of uses for such events, such as a class that downloads large amounts of data from the Internet, and uses an event to signal that the download is complete. Another example is a class that carries out a time-consuming process and uses an event to inform the host program of its progress.
There are three aspects to using events: declaring the event, raising the event, and handling the event.
Declaring the Event
An event is declared in a class definition using the Event keyword. The event declaration specifies the name of the event and the number and types of arguments that the event has (if any). The syntax is as follows:
Public Event EventName(ArgumentList)
EventName is the name of the event, following standard VB.Net variable naming rules. ArgumentList is a list of the arguments that the event uses, and has the same format as the argument list of other procedures (optional arguments and ParamArray arguments are not permitted, however). Use empty parentheses for
events that take no arguments. Here is the declaration of an event that takes one type Integer argument:
Public Event MyEvent(PercentDone As Integer)
Raising the Event
Once the event has been declared, code in the class can raise it using the RaiseEvent statement. The syntax is:
RaiseEvent EventName(ArgumentList)
EventName is the name of the event to raise, which must have been declared in the same module as the RaiseEvent statement is being called from. ArgumentList is the list of arguments required by the event. If the event takes no arguments, you should use empty parentheses.
The following listing presents a simple class that has a single method, DoSomething(). It declares an event named ReportProgress which takes one type Integer argument. The task that DoSomething() performs is mimicked by nested For loops that take a few seconds to complete.
Public Class ClassWithEvent
Public Event ReportProgress(ByVal PercentDone As Integer)
Public Sub DoSomething()
Dim x As Integer, y As Integer
For x = 0 To 10
RaiseEvent ReportProgress(x * 10)
For y = 1 To 50000
Application.DoEvents()
Next
Next
End Sub
End Class
The outer loop repeats from x=0 to x=10. Each time the loop iterates, it calls the ReportProgress event, passing the value of (x*10) which will range from 0 to 100. When the program responds to this event, it can make use of this information as needed.
Note the use of the Application.DoEvents() method. This method lets your application handle other events while it is in the midst of processing code, such as another event handler. Without a call to DoEvents(), new events (such as repainting a screen window) wait in the queue until the current process is terminated. In the example shown above, without the call to DoEvents(), the user would not be able to accomplish things (such as drag the program's screen window to a new location) while the For loops are executing. Nor would the "percent done" value display on the program's main for (which I'll get to in a moment).
Responding to the Event
There are two ways a program can respond to an event raised by a class. For most situations, the recommended way to create event handlers is by using the WithEvents and Handles keywords. There are several parts to this.
First, the object that will raise the event must be declared using the WithEvents keyword. For example, if ClassWithEvents is a class that raises events, you would declare an instance of it like this:
Public WithEvents obj As ClassWithEvents
Note that you cannot use the New keyword when declaring an object using
WithEvents. In other words, the following is not permitted:
Public WithEvents obj As New ClassWithEvents
You must declare and instantiate the object separately:
Public WithEvents obj As ClassWithEvents obj = New ClassWithEvents
Then you must write an event handler for each event. An event handler is a regular VB.Net Sub procedure that is linked to one or more events by the Handles keyword. The syntax is:
Sub HandlerName(ArgumentList) Handles EventList
HandlerName is the name of the event handler, and can be any legal VB.Net name. It is a good idea, however, to assign names in the form ObjectName_EventName because this is the format used for other event handler names, and it makes it clear that the procedure is an event handler and the object and event that are involved.
ArgumentList is a list of arguments passed by the event, and must match the argument list in the event declaration in the class. EventList is a list of one or more events that will be handled by this procedure. Each event is specified using the format:
ObjectName.EventName.
If the list contains more than one event, separate them by commas.
Here is an example of an event handler that handles the ReportProgress event for the object named obj1. Assume that this event passes one type Integer argument.
Private Sub obj1_ReportProgress(PercentDone As Integer)
Handles obj1.ReportProgress
' Code to handle the event goes here.
End Sub
To provide an demonstration of creating an event handler this way, I will use the class ClassWithEvent that was presented in the previous listing. Follow these steps to create the demonstration program:
- Create a new Windows Application project in VB.Net.
- Add a new class to the project, and add the class definition from the listing to the class module.
- Add a TextBox control to the project's form. Leave the control's name at the default value of TextBox1, and change its Text property to a blank string.
- Add the following declaration to the form class definition:
- Add the following code to the class to define the event handler:
- Create an event handler for the Form1_Click event that will instantiate the class and call its DoSomething() method when the user clicks the form:
Public WithEvents obj As ClassWithEvent
Protected Sub obj_ReportProgress(ByVal PercentDone As Integer)
Handles obj.ReportProgress TextBox1.Text = PercentDone
End Sub
Private Sub Form1_Click
(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Click
obj = New ClassWithEvent()
obj.DoSomething()
End Sub
When you run the program, click on the form to call the DoSomething() method. As the method executes, it raises the ReportProgress() event repeatedly. Each time this event fires, the event handler displays the latest "percent done" value in the text box. You'll see the value in the text box change from 0 to 10, 20 and so on, up to 100.
Handling Events Using AddHandler
Using the WithEvents and Handles keywords to set up event handlers works fine in most situations, as described in the previous section. There are some
limitations, however. Specifically, this technique:
- Cannot be used with an object reference that is declared as a generic Object type. The object variable must be declared as the specific class type.
- Cannot be used to handle shared events.
- Cannot associate multiple event handlers with a given event.
- Cannot be used with arrays of object variables.
To overcome these limitations, you can use the AddHandler statement to associate an event handler with an event. When using this technique, the object instance is declared in the normal manner, without any special keywords. The event handler itself is a regular VB.Net Sub procedure with an argument list that matches that of the event that is being handled. Again, no special keywords are needed. Then, assign the event handler using the following syntax:
AddHandler ObjectName.EventName, AddressOf Me.HandlerName
ObjectName is the name of the object, EventName is the name of the event, and HandlerName is the name of the event-handling procedure. Note the use of the Me keyword, which provides a reference to the object the class is running in and which in this case contains the event handler procedure. AddHandler is very flexible. You can assign more than one event handler to an event, and you can also assign the same event handler to more than one event. To dissociate an event handler from an event, use the RemoveHandler statement, which has exactly the same syntax as AddHandler.
Now, let's repeat the previous demonstration using the ClassWithEvent class, but this time assigning an event handling using the AddHandler statement. Here are the steps to follow:
- Create a new Windows Application project in VB.Net.
- Add a new class to the project and add the class definition to the class module.
- Add a TextBox control to the project's form. Leave the control's name at the default value of TextBox1, and change its Text property to a blank string.
- Add the following declaration to the form class definition:
- Add the following code to define the event handler:
- Create an event handler for the
Form1_Clickevent that will assign the event handler and call theDoSomething()method when the user clicks the form:
Public obj As New ClassWithEvent
Protected Sub obj_ReportProgress(ByVal PercentDone As Integer)
TextBox1.Text = PercentDone
End Sub
Private Sub Form1_Click
(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Click
AddHandler obj.ReportProgress, AddressOf Me.obj_ReportProgress
obj.DoSomething()
End Sub
The new demo will work exactly the same as the previous one.
![]() |
|


