Events and Delegates in the .NET Framework

<Previous Topic   ^Exam 70-536 Topics^   Next Topic>

Events are signals that a sending object sends to a receiving object, or receiving objects to notify it (or them) of some action that occurred out in the real world (like a button click), or some change of state in the program (like the completion of a computation). A sending object is said to raise an event, and a receiving object is said to handle an event.

When a sending object sends and event, it does it by calling a method on the receiving object.  Here is an example of an event handler in VB:

Public Class Form2 
    'This event handler is a method of the receiving class 
    Public Sub IncomingBirdsBitsMessage(ByVal sMessage As String) 
        TextBox1.Text = sMessage 
    End Sub

But, a sending object doesn’t doesn’t always know which object or objects might be receiving events. This problem is solved by the use of an intermediary called a delegate. A delegate is a class that can hold a reference to a method on a receiving object. The sending object is then able to invoke a method on the receiving object indirectly via the delegate.  (If you’ve done C programming, you can think of a delegate as being similar to a function pointer, or a callback, but delegates are type-safe.)  A delegate class only needs a declaration, you don’t need to provide the implementation since the CLR will implement it. The declaration specifies the signature (arguments and return value) of methods that can be called. Here’s and example in VB:

Public Class Form1 
    'This delegate declaration is made in the sending class. 
    'The signature of Sub matches the signature for event handlers in receiving objects. 
    Public Delegate Sub BirdsBitsEventHandler(ByVal sMessage As String)

The following VB example shows how the sending class creates an instance of a delegate and uses it to raise an event.

'This is part of the sending class: Class Form1 
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click  

Dim BBDelegate As New BirdsBitsEventHandler(AddressOf Form2.IncomingBirdsBitsMessage) 
        BBDelegate.Invoke("This is a test of the BirdsBits event handler")

Here is an experiment that I wrote in VB2005: (This isn’t elegant programming, just a quick experiment to see how events and delegates work!) This example demonstrates delegate multicasting which means sending an event to multiple receiving objects. I also added code to allow objects to register their delegates at run-time. This allows you to design a much more flexible software system in which there are optional objects that may or may not be created at run time and thus couldn’t be “hard wired” at design time to receive messages.

I created a windows forms project and added three forms: Form1, Form2, and Form3. The code from Form1 is shown below this paragraph. (I only showed the code I added, not the code created by the Forms Designer.) Form1 just has one button on it. When you push the button, it invokes events for any delegates that have been registered through the method: BirdsBitsEventHandler(…).

—————————————————————————————–

Public Class Form1
    Public Delegate Sub BirdsBitsEventHandler(ByVal sMessage As String)
    Dim MultiBBEventDelegate As BirdsBitsEventHandler

—————————————————————————————–

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Form2.Show()
        Form3.Show()
    End Sub

—————————————————————————————–

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        If MultiBBEventDelegate IsNot Nothing Then
            MultiBBEventDelegate.Invoke(“This is a test of the BirdsBits event handler”)
        Else
            MsgBox(“No callbacks registered”)
        End If
    End Sub

—————————————————————————————–

Public Sub RegiserHandler(ByRef BBEventDelegate As BirdsBitsEventHandler)

        If MultiBBEventDelegate Is Nothing Then
            MultiBBEventDelegate = BBEventDelegate
        Else
            MultiBBEventDelegate = System.Delegate.Combine(MultiBBEventDelegate, BBEventDelegate)
        End If

    End Sub

End Class

—————————————————————————————–

Form2 and Form3 are identical. The code from Form2 is shown below this paragraph. The form has one text box for displaying messages and a button for registering this form’s method: IncomingBirdsBitsMessage(…) with the sending form (Form1). You could actually have any number of receiving forms with this same code.

—————————————————————————————–

Public Class Form2    Public Sub IncomingBirdsBitsMessage(ByVal sMessage As String)
        TextBox1.Text = sMessage
    End Sub

—————————————————————————————–  

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim DelegateForThisSub As New Form1.BirdsBitsEventHandler(AddressOf IncomingBirdsBitsMessage)
        Form1.RegiserHandler(DelegateForThisSub)
    End Sub
End Class
  

—————————————————————————————–

Sources

(The explaination of delegates and events in Balena is excellent. This is where I got most of my information.)

1 Comment Add your own

  • 1. ryla  |  October 6, 2009 at 3:51 am

    Could you clear this up for me, basically when the users click “button1” the following happens:

    button1.click –> DelegateForThisSub –> BirdsBitsEventHandler

    button1 calls BirdsBitsEventHandler by using DelegateForThisSub

    Your answer is much appreciated thanks!

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Trackback this post  |  Subscribe to the comments via RSS Feed


%d bloggers like this: