Custom Events in VB.NET 2005

Visual Basic .NET is well known for its event-driven programming capabilities. VB.NET 2005 adds new functionality for custom events that provides flexibility in handling and controlling events.

Creating custom events with Visual Basic .NET 2005

Events model in VB.NET

Events are defined as actions or occurances of interest. An interested object can subscribe to an event and be notified when it happens. For example, a button on a form can generate a click event and the form can subscribe and get notified when the event occurs. This click event is processed through the form code.

VB.NET 2005 provides a range of flexible event models to address simple or very complex events. Below is an example of a simple event using a Worker class with a DoWork method:

The DoWork method has a For loop repeating 100 times, waiting one second between loops, and printing out the completed work to the console. But a client such as a form using the object of the above class, for example, should provide visual feedback on how much work has been completed when the DoWork method is called. Adding an event to the Worker class and altering the DoWork method to call the event can provide this information to the client.

An event called WorkDone has been identified with an integer argument through which the amount of work completed can be passed. And in the DoWork method, the event passing the actual amount of work completed is raised. Now the above class can be consumed by a client by declaring and creating a Worker class object with events and handling the WorkDone event to provide feedback on progress.

In the above code, the work_WorkDone method will be called each time the WorkDone event is raised. The Handles clause after the method signature links the event-handling code with the actual event.

A method can also dynamically link to an event using the AddHandler method and be removed from handling an event using the RemoveHandler method as seen below. This enables more flexibility by relating a method to an event and removing the binding required at runtime. Even when the Handles keyword is used to bind a method to an event internally, a call to the AddHandler method is done to perform the actual binding.

‘We dont require to use WithEvents since we are binding to events dynamically
Private mWorker As New Worker

Delegates in .NET events

VB.NET implements events through a construct called delegates. Delegates point to a method and can hold the address of a method, enabling a method to be invoked through an instance of its delegate. The Worker class can be implemented without events using a delegate as follows:

In the code above, a delegate named WorkDone that accepts an integer argument has been defined. This delegate can point to any method with a similar signature (a sub-procedure that accepts an integer). After the delegate is defined, a public variable delegate named Handler has been defined, and instead of raising the event in the DoWork method, the delegate instance is invoked.

In the Worker class client, the delegate instance is set to point to the method that will be called when reporting the amount of work done.

The above code uses delegates directly, not the event construct, so neither the AddHandler nor RemoveHandler methods can be used. This exposes only one public variable, so there can be only one method to handle the invocation of the delegate.

Directly using the delegates method eliminates the setting of multiple event handlers for one event source, which would notify all handlers when the event occurs. But an event type can be set as a delegate and use the event-handling mechanism, resulting in cleaner code as follows:

Custom events in VB.NET 8.0

Custom events provide flexibility and control in creating and managing events. When using custom events, it is the responsibility of the developer to bind and unbind handlers, as well as to specify the actual calls to raise the events. Although this requires a bit more code than the earlier implementations, it provides more control over the handlers and the invocation.

A custom event is defined by using the Custom keyword in front of the event declaration, and by providing the delegate type for the event. The custom event has three sections: The AddHandler section, which is invoked whenever a handler is added using the Handles keyword or the AddHandler method; RemoveHandler section, which is called whenever a handler is removed using the RemoveHandler method; and the RaiseEvent section that will be invoked whenever an event is requested. The developer should write the necessary code in each of these sections to manage the handlers, as well as specify how handlers will be notified when an event is requested.

Below, the Worker class is implemented using the custom event construct in VB.NET 2005.

Using custom events enables more control over the handlers. In the above code, for example, there is a condition in the AddHandler section limiting the number of handlers for which events are provided. The RaiseEvent method has been changed to notify the handlers only when the completed Work is more than 50. Another advantage to using custom events is a central unit of code containing all of the handlers of the event within the event construct.

Using RaiseEvent twice, once in the DoWork method and then in the custom event construct, can lead to confusion. RaiseEvent in the DoWork method will raise the event, but the RaiseEvent section in the custom event construct specifies the code to be executed when the event is raised. In this case, all of the handlers are looped through and delegates are invoked.

Events and delegates are important parts of the .NET language. VB.NET 2005 gives developers control and flexibility in handling simple event models and custom events.