Home > Microsoft .Net Development Tips > Visual Basic and Visual Basic .NET > Put VB.NET events in the hands of AddHandler
Win Development Tips:
EMAIL THIS
 TIPS & NEWSLETTERS TOPICS 

VISUAL BASIC AND VISUAL BASIC .NET

Put VB.NET events in the hands of AddHandler


Bruce D. Neiger
02.21.2007
Rating: --- (out of 5)


.NET Essentials Channel
Digg This!    StumbleUpon Toolbar StumbleUpon    Bookmark with Delicious Del.icio.us    Add to Google


A simple conundrum posed by Visual Basic 6 -- how to trap and handle events from objects that are not assigned to an individual variable -- was solved by the earliest versions of VB.NET. The solution is the AddHandler command.

.NET provides the flexible handles clause to assign routines to handle events from object variables declared with the WithEvents keyword. There are, however, two common cases where there is no object variable to manipulate -- first, where there is no object instance associated with the event, and second, where the object is stored in a collection or an array.

AddHandler addresses both of these needs, and, as a bonus, permits us to change the handler routine at runtime. It also makes the WithEvents keyword unnecessary. This tip describes an example that demonstrates both cases in the same form.

Case 1: No Object Instance to Handle

The first case occurs with either an event declared in a module or with a shared event in a class.

As an example, error logging functionality was built into a class called ErrLogger. All of Errlogger's members, including its lone LogWritten event, which gets raised whenever the log file is written to, are declared using the shared keyword. ErrLogger is shown in Listing 1.

Listing 1: ErrLogging Class

When using only shared members of a class, you don't have to instantiate the class. That's like having a global object, without having to track what happens to it. However, without an object instance, the handles clause can't be appended to a subroutine to handle an event.

Fortunately, Addhandler doesn't need an object instance -- only an event name and the address of a handler routine.

The syntax of Addhandler is this:
AddHandler event, AddressOf eventhandler.

Thus, in the form's load event handler, this line of code assigns the subroutine ErrorLogged as a handler...


Digg This!    StumbleUpon Toolbar StumbleUpon    Bookmark with Delicious Del.icio.us    Add to Google



RELATED CONTENT
Visual Basic and Visual Basic .NET
Compose XML more quickly using Visual Basic 9
Virtualization keeps Legacy Apps alive
VB 9 Anonymous Types help create flexible objects
Visual Studio Team System Add-ins: Conchango Scrum for Team System and Scrum Dashboard
Book Excerpt: Sams Teach Yourself Visual Basic 2008 in 24 Hours -- Complete Starter Kit
Check out CodePlex for a ton of interesting .NET projects
Book excerpt: Murach's VB 2008
Book excerpt: Printing in Visual Basic 2005
Visual Basic 2008 and closures
WinForms development using SQL Server 2005 and Visual Basic 2005

VB 6 to VB .NET Migration
On managing a .NET Framework 1.x migration
Tool translates VB .NET code to Java
Microsoft unveils VB 2005 'Power Packs'
Mini-Guide: The VB.NET Development Environment, Part 3
Mini-Guide: The VB.NET Development Environment, Part 2
Mini-Guide: The VB.NET Development Environment, Part 1
Choosing VB.NET or C# Learning Guide
Object-Oriented Programming in VB .NET Learning Guide
Quiz: What do you know about VB 6 migration?
1. First thing to do when migrating to VB.NET

RELATED GLOSSARY TERMS
Terms from Whatis.com − the technology online dictionary
.NET  (SearchWinDevelopment.com)

RELATED RESOURCES
2020software.com, trial software downloads for accounting software, ERP software, CRM software and business software systems
Search Bitpipe.com for the latest white papers and business webcasts
Whatis.com, the online computer dictionary


to the ErrLogger class' LogWritten event:
AddHandler Errlogger.LogWritten, AddressOf ErrorLogged

Case 2: Handling Events from an Object within a Collection

AddHandler solves the problem of trapping and handling events raised by objects stored in a collection or array with relative ease. Use it to assign a handler to each object prior to adding it to the array or collection.

Example Description

Envision a collection containing one or more collections, each of which contains one or more elements. (The example code was developed for electronic signs, each of which contains a collection of one or more lines of text that are populated at regular intervals from an external data source. The example fits collections of tables with a variable number of chairs or classrooms with a variable number of students just as easily.)

The signs are represented as Group objects that contain collections of Line objects. The Group and Line objects are constructed dynamically (earlier in the application) from data in a database, so a count is not available at design time.

The data members of the Line and Group objects are displayed on a form using separate objects. Groups are displayed using groupDisplay objects that are stored in a collection owned by the form. Similarly, the Lines are displayed (and controlled) by lineDisplay objects, which are stored in a collection that is owned by their parent groupDisplay object.

The form's user can click on a lineDisplay's button to override the display. The goal of this tip is to show how the form can trap and handle the override events raised by individual lineDisplay objects.

The Form

An image of the form, configured for two groupDisplays with three lineDisplays each, is shown in Figure 1.

Figure 1: Form with Three LineDisplays within Two GroupDisplays

[IMAGE]

Each lineDisplay object has four constituent controls to display and control the text:

  • Two labels -- to show the its name and current value,
  • A textbox to enter an operator over-ride value, and
  • A button to start the over-ride process.

Note that there's no data from the external source in these controls -- but a user can override "nothing" just as easily as "something." Also note that the bottom half of the form displays errors that are logged by the ErrLogger object -- as described above.

Handling the Event

AddHandler is used to assign a handler to the object before it is added to the collection. The object that raised the event is identified by using the sender object in the event's parameters.

The extra layer of collections in the example means that there's an extra required step: the lineDisplay's override event notifies the groupDisplay, which, in turn raises its own override event to notify the form. Each layer has its own handler routine, and the notification bubbles up through each layer.

This is less complex than it sounds. The relevant parts of the lineDisplay and groupDisplay classes are shown in Listings 2 and 3. The "irrelevant" parts of these classes, which create and place constituent controls and do other bookkeeping, have been omitted for clarity.

Listing 2: lineDisplay Class

Listing 3: groupDisplay Class

As shown in Listing 2, lineDisplay's override event is raised in the button's click event handler. Meanwhile, the groupDisplay code in Listing 3 shows a lineDisplay object being created for each Line object in the group's Lines collection and the event handler -- (HandleLDButton()) -- being assigned.

When a particular lineDisplay raises its override event, it is handled by the groupDisplay via its HandleLDButton routine. To notify the client form, HandleLDButton raises the groupDisplay's override event.

How does the form know which object raised the event? That is in the lineDisplay's override event, as the sender parameter. That information is passed along when re-raising the event (for the client form) with a System.EventArgs-derived object that incorporates the lineDisplay object as a custom field.

The last piece is the code for the client form's load event, the relevant parts of which are shown in Listing 4.

Listing 4: Relevant Form Load Event Code

Note the assignment of the ErrLogger.LogWritten event that was excerpted earlier. After that, there's a simple for loop to create groupDisplay objects and assign the form's ButtonHandler routine as the groupDisplay object's override event's handler.

Conclusion

There are countless real-world applications dealing with events raised by objects stored in collections or non-instantiated class events. Where they occur, Addhandler addresses the inter-object communication problem very neatly.

Bruce D. Neiger is a licensed professional engineer working for Parsons Transportation Group (PTG) in New York City. His 20-year career has included of highway-related air quality and noise modeling, application development, OOP, and object architecture. He can be reached at Bruce.D.Neiger@Parsons.com.

Rate this Tip
To rate tips, you must be a member of SearchWinDevelopment.com.
Register now to start rating these tips. Log in if you are already a member.




DISCLAIMER: Our Tips Exchange is a forum for you to share technical advice and expertise with your peers and to learn from other enterprise IT professionals. TechTarget provides the infrastructure to facilitate this sharing of information. However, we cannot guarantee the accuracy or validity of the material submitted. You agree that your use of the Ask The Expert services and your reliance on any questions, answers, information or other materials received through this Web site is at your own risk.



Database Programming Solutions - .NET XML, Visual Studio LINQ, ORM .NET
About Us  |  Contact Us  |  For Advertisers  |  For Business Partners  |  Site Index  |  RSS
SEARCH 
TechTarget provides technology professionals with the information they need to perform their jobs - from developing strategy, to making cost-effective purchase decisions and managing their organizations' technology projects - with its network of technology-specific websites, events and online magazines.

TechTarget Corporate Web Site  |  Media Kits  |  Site Map




All Rights Reserved, Copyright 2000 - 2009, TechTarget | Read our Privacy Policy
  TechTarget - The IT Media ROI Experts