All of us have been exposed to event driven programming of some sort or the other. C# adds on value to the often mentioned world of event driven programming by adding support through events and delegates. This article is a part of a series that aims at understanding fully the way in which delegates and events operate. Part1 helps you understand the role of multicast delegates in the context of UI interaction. The emphasis of this article would be to identify what exactly happens when you add an event handler to your common UI controls. A simple simulation of what could possibly be going on behind the scenes when the AddOnClick or any similar event is added to the Button class will be explained. This will help you understand better the nature of event handling using multi cast delegates. All the examples provided are in C#.
An event is the outcome of an action. There are two important terms with respect to events. The event source and the event receiver. The object that raises the event is called event source and the object that responds to the event is called event receiver. Did you observe a hitch in the above explanation? O.K. my event source raises the event and my event receiver receives it, but what is the communication channel between them. Take the instance of you talking with a friend of yours over the telephone. Now you are the event source and your friend is the event receiver and the telephone cable is the communication channel. Similarly the communication channel between an event source and an event receiver is the delegate. The internals of events and their relationship to delegates would be dealt with in a later article. The explanation of events here is just to help the reader understand and visualize what exactly events are.
Forget computers for a moment. Just think about delegates in the real world. Who are delegates? Delegates are people who represent a particular country or region or state in another country or region or state. Extend this same definition now to C#. In C#, delegates act as an intermediary between an event source and an event destination.
To be even precise delegates are similar to function pointers. They can be called as type safe function pointers. Delegates have other uses in addition to event handling. But this article would focus on describing delegates with respect to event handling. A delegate class used as an intermediary between an event source and event receiver is called an event handler.
There are basically two types of delegates. Single Cast delegate and Multi Cast delegate. Let us first understand at the broader level the definition of both these delegates. A single cast delegate can call only one function. A multi cast delegate is one that can be part of a linked list. The multi cast delegate points to the head of such a linked list. This means that when the multi cast delegate is invoked it can call all the functions that form a part of the linked list. Assume that i have several clients who would like to receive notification when a particular event occurs. Putting all of them in a multi cast delegate can help call all the clients when a particular event occurs.
To support a single cast delegate the base class library includes a special class type called System.Delegate. To support multi cast delegates the base class library includes a special class type called SystemMultiCastDelegate.
The signature of a single cast delegate is shown below. The letters in italics can be replaced with your own names and parameters.
public delegate Boolean DelegateName (parm1, parm2)
public delegate Boolean MyDelegate(Object sendingobj, Int32 x); public class TestDelegateClass { Boolean MyFunction(Object sendingobj, Int32 x) { //Perform some processing return (true); } public static void main(String [] args) { //Instantiate the delegate passing the method to invoke in its constructor MyDelegate mdg = new MyDelegate(MyFunction); // Construct an instance of this class TestDelegateClass tdc = new TestDelegateClass(); // The following line will call MyFunction Boolean f = mdg(this, 1); } }
Boolean f = mdg(this, 1);
public delegate void DelegateName (parm1, parm2)
public static Delegate Combine(Delegate a, Delegate b);
public static Delegate Remove(Delegate source, Delegate value);
using System; class MCD1 { public void dispMCD1(string s) { Console.WriteLine("MCD1"); } } class MCD2 { public void dispMCD2(string s) { Console.WriteLine("MCD2"); } } public delegate void OnMsgArrived(string s); class TestMultiCastUsingDelegates { public static void Main(string [] args) { MCD1 mcd1=new MCD1(); MCD2 mcd2=new MCD2(); // Create a delegate to point to dispMCD1 of mcd1 object OnMsgArrived oma=new OnMsgArrived(mcd1.dispMCD1); // Create a delegate to point to dispMCD2 of mcd2 object OnMsgArrived omb=new OnMsgArrived(mcd2.dispMCD2); OnMsgArrived omc; // Combine the two created delegates. Now omc would point to the head of a linked list // of delegates omc=(OnMsgArrived)Delegate.Combine(oma,omb); Delegate [] omd; // Obtain the array of delegate references by invoking GetInvocationList() omd=omc.GetInvocationList(); OnMsgArrived ome; // Now navigate through the array and call each delegate which in turn would call each of the // methods for(int i=0;i{ // Now call each of the delegates ome=(OnMsgArrived)omd[i]; ome("string"); } } }
csc /r:System.DLL;System.WinForms.DLL;Microsoft.Win32.Interop.DLL FormTest.cs
/* Creating a form and adding a button to it and associating the button with an event handler */ using System; using System.WinForms; public class FormTest : Form { //Create a button private Button button1 = new Button(); public static void Main (string [] args) { //Run the application Application.Run(new FormTest()); } public FormTest() { //Set up the Form this.Text = "Hello WinForms World"; //Set up the button button1.Text = "Click Me!"; //Register the event handler button1.AddOnClick(new System.EventHandler(buttonClicked)); //Add the controls to the form this.Controls.Add(button1); } //The event handling method private void buttonClicked(object sender, EventArgs evArgs) { MessageBox.Show("Button clicked"); } }
public delegate void ButtonEventHandler(object sender, ButtonEventArgs e);
public class ButtonEventArgs : EventArgs { public string msg; //identifies the action public ButtonEventArgs(string message) { msg=message; } }
}
public void AddOnClick(ButtonEventHandler handler); public void RemoveOnClick(ButtonEventHandler handler); public void AddOnPress(ButtonEventHandler handler); public void RemoveOnPress(ButtonEventHandler handler);
protected virtual void OnPress(ButtonEventArgs e); protected virtual void OnClick(ButtonEventArgs e);
public void click(); public void press();
Build Your Own ASP.NET Website Using C# & VB.NET