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
- From the MSDN Library: NET Framework Developer’s Guide: Events and Delegates
- Balena, Francesc0. 2006. Chapter 7: Delegates and Events. Programming Visual Basic 2005: The Language. Microsoft Press : Redmond.
(The explaination of delegates and events in Balena is excellent. This is where I got most of my information.)
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!