Using Delegates Across Project Boundaries


Visual Basic .NET Unleashed
By Paul Kimmel
Table of Contents
Chapter 9.  Understanding Delegates

Using Delegates Across Project Boundaries

Events can be defined and used across project boundaries. An event defined in a class library can be handled in an application making reference to that class and having defined an event handler for the class library event. The net result is that classes don't have to be defined within your application to take advantage of the event mechanism.

Complete the numbered steps.

  1. Create a new blank Windows application project.

  2. Using the Solution Explorer, add a new Class Library project named RaisesEvent to the Windows application solution started in step 1.

  3. Name the class library file RaisesEvent.vb and the class RaiseTest.

  4. Declare an Event attribute by typing Public Event SendString(ByVal Str As String).

  5. Add a method test that raises the event with the statement RaiseEvent SendString("RaisesEvent").

  6. In the Form Designer of the Windows application, add a button control. Double-click the button control to generate the Click event handler for the button.

  7. Outside the Button1_Click event handler, declare the statement WithEvents R As RaisesEvent.RaiseTest, where RaisesEvent is the class library and RaiseTest is the name of the class.

  8. Within the Button1_Click event handler, create an instance of RaiseTest and assign it to R, the name in the WithEvents statement in step 7, and call the Test method with Obj.Test().

  9. Select the name R from the objects list and R_SendString from the procedure list to generate the event handler in the form.

  10. Add the statement MsgBox(Str) to the R_SendString event handler.

After completing steps 1 through 10, run the Windows application part of the solution and click the button. You should get a message with the string of text sent from the event in the RaisesEvent class library. Listing 9.11 contains the complete code listing for the Windows application (this listing demonstrates a Windows Form class responding to an event raised in a class library). (The class library is in Listing 9.12).

Listing 9.11 Handle an event across project boundaries
  1:  Public Class Form1  2:  Inherits System.Windows.Forms.Form  3:   4:  [ Windows Form Designer Code ]  5:   6:  WithEvents R As RaisesEvent.RaiseTest  7:   8:  Private Sub Button1_Click(ByVal sender As System.Object, _  9:  ByVal e As System.EventArgs) Handles Button1.Click  10:   11:  Dim Obj As New RaisesEvent.RaiseTest()  12:  R = Obj  13:  Obj.Test()  14:   15:  End Sub  16:   17:  Private Sub R_SendString(ByVal Str As String) Handles R.SendString  18:  MsgBox(Str)  19:  End Sub  20:   21:  End Class 

The WithEvents statement sets up the event-handling capability for the RaiseTest class. Button1_Click creates a RaiseTest object and calls the Test method. RaisesEvent.Test raises the SendString event, which is handled on lines 17 through 21 of Listing 9.11.

Listing 9.12 demonstrates declaring the event and raising it.

Listing 9.12 Declare and raise an event in a class. The event can be handled in the same or external project
  1:  Public Class RaiseTest  2:   3:  Public Event SendString(ByVal Str As String)  4:   5:  Public Sub Test()  6:  RaiseEvent SendString("RaisesEvent.Test")  7:  End Sub  8:   9:  End Class 

This is identical to the code you would write if RaiseTest and Form1 were defined within the same project. The implied difference is that delegates are working behind the scenes to support this event interaction.

When you define a statement such as the one on line 3 of Listing 9.12, you are implicitly declaring a Delegate. The WithEvents statement is creating the necessary connection piece that allows you to express the relationship between event and handler. This relationship could have been explicitly defined, as demonstrated in the revised code in Listings 9.13 and 9.14.

Listing 9.13 Revision of the code from Listing 9.12, defining the form using delegates explicitly
  1:  Public Class Form1  2:  Inherits System.Windows.Forms.Form  3:   4:  [  Windows Form Designer generated code  ]  5:   6:  Private Sub Button1_Click(ByVal sender As System.Object, _  7:  ByVal e As System.EventArgs) Handles Button1.Click  8:   9:  Dim Obj As New RaisesEvent.RaiseTest()  10:  Obj.D = AddressOf SendString  11:  Obj.Test()  12:   13:  End Sub  14:   15:  Private Sub SendString(ByVal Str As String)  16:  MsgBox(Str)  17:  End Sub  18:   19:  End Class 

Note the absence of the WithEvents statement. Line 10 takes care of assigning the AddressOf the handler SendString to the Delegate member RaisesEvent.D. Look at Listing 9.14 for the revised implementation of the event and its invocation.

Listing 9.14 Revised implementation of RaiseTest from Listing 9.12, using Delegates instead of RaiseEvent
  1:  Public Class RaiseTest  2:   3:  Public Delegate Sub Sender(ByVal Str As String)  4:  Public D As Sender  5:   6:  Public Sub Test()  7:  D("RaisesEvent.Test")  8:  End Sub  9:   10:  Public Sub HandleClick(ByVal sender As System.Object, _  11:  ByVal e As System.EventArgs)  12:  MsgBox("RaisesEvent.Click")  13:  End Sub  14:  End Class 

In Listing 9.14, the Delegate is explicitly defined on line 3. Line 4 declares a public attribute named D, representing an instance of the Delegate Sender. Line 7 calls all of the procedures in D's invocation list oblivious to whether there are any procedures or not. The revised version performs exactly like its predecessor in Listing 9.12, without the Event and RaiseEvent statements.


The reverse of the behavior supported by Listings 9.11 and 9.12 or 9.13 and 9.14 can be implemented also. That is, you could define an event in Form1 and the handler in the RaiseTest class (or any class). Try this operation by creating a RaiseEvent object in the Form1 class. In Form1_Load use AddHandler Button1. Click, AddressOf Obj.Handler to add a procedure named Handler, defined in RaiseTest, to Button1's Click invocation list. When Button1 is clicked, RaiseTest's Handler event handler will respond. The code is defined in InterProjectEvent.sln along with the code from Listings 9.11 through 9.14.

Using Delegates explicitly may take a little getting used to if you were accustomed to using the WithEvents, RaiseEvent, and Event statements. However, calling the event using the same notation as a procedure is a little cleaner implementation.


Visual BasicR. NET Unleashed
Visual BasicR. NET Unleashed
Year: 2001
Pages: 222 © 2008-2017.
If you may any questions please contact us: