Monday, December 17, 2007

Event and Delegtes

Delegate:-

A delegate in C# is similar to a function pointer in C or C++. Using a delegate allows the programmer to encapsulate a reference to a method inside a delegate object. The delegate object can then be passed to code which can call the referenced method, without having to know at compile time which method will be invoked.

An interesting and useful property of a delegate is that it does not know or care about the class of the object that it references. Any object will do; all that matters is that the method's argument types and return type match the delegate's. This makes delegates perfectly suited for "anonymous" invocation.

A delegate is called a single delegate that derives from the System.Delegate class contains an invocation list with one method. Now we will look at how the single-cast delegates are declared. In single-cast delegates, the delegate can point to both static and non-static method if both have the same signature as the delegate

The signature of a single cast delegate is shown below:

Delegate result-type identifier ([parameters]);

Where:

Result-type: The result type, which matches the return type of the function.

* Identifier: The delegate name.
* Parameters: The Parameters that the function takes.

Examples: public delegate void SimpleDelegate ()

This declaration defines a delegate named SimpleDelegate, which will encapsulate any method that takes
no parameters and returns no value.

public delegate int ButtonClickHandler (object obj1, object obj2)

This declaration defines a delegate named ButtonClickHandler, which will encapsulate any method that takes
two objects as parameters and returns an int

using System;

namespace Akadia.BasicDelegate
{
// Declaration
public delegate void SimpleDelegate();

class TestDelegate
{
public static void MyFunc()
{
Console.WriteLine("I was called by delegate ...");
}

public static void Main()
{
// Instantiation
SimpleDelegate simpleDelegate = new SimpleDelegate(MyFunc);

// Invocation
simpleDelegate();
}
}
}

Multi-cast Delegates:

A delegate is called Multi-cast Delegate that derives from the System.MulticastDelegate contains an invocation list with multiple methods. At times it is desirable to call two methods through a single delegate. This can be achieved through Single-cast Delegate but it is different from having a collection, each of which invokes a single method.

In Multi-casting you create a single delegate that will invoke multiple encapsulated methods. The return type of all the delegates should be same. Now the question why are we using Multi-cast delegates when Single-cast delegates are enough. Well the answer to this question is what if you want to call three methods when a button is clicked. The Multi-cast delegates are used with events where multiple call to different methods are required. System.MulticastDelegate contains two methods Combine and Remove. The Combine is a static method of class System.MulticastDelegate and is used to Combine the delegates and the remove method is used to remove the delegate from the list. For user convenience we have += operator overloaded for delegate Combine method and -= operator overloaded for Remove method Multi-cast delegates are similar to Single-cast delegates for e.g.

public delegate void MulticastDelegate();

Multi-cast delegate can have arguments and can return value as well. All the Methods pointed by delegates should return the similar value as the delegate return type.

public delegate string MultiCastOne(string Name);

Consider a simple example:

using System;

namespace Multi_castDelegate

{

/// Summary description for Class1.

class MyClassDelegate

{

/// The main entry point for the application.

public delegate string StringDelegate(string s);

}

}

Below is the class that defines the static methods having same signature as delegate.

using System;

namespace Multi_castDelegate

{

/// Summary description for MyImplementingClass.

public class MyClass

{

public MyClass()

{

}

public static string WriteString(string s)

{

Console.WriteLine("Writing string");

return "null";

}

public static string logString(string s)

{

Console.WriteLine("loging string");

return "null";

}

public static string TransmitString(string s)

{

Console.WriteLine("Transmitting string");

return "null";

}

}

}

The Main class:

using System;

using System.Threading;

namespace Multi_castDelegate

{

/// Summary description for Test.

public class Test

{

public static void Main()

{

MyClassDelegate.StringDelegate

Writer,Logger,Transmitter;

MyClassDelegate.StringDelegate

myDelegate;

Writer=new

MyClassDelegate.StringDelegate(MyClass.WriteString);

/// calling Writer

Writer("hello i am Writer just acting like Single cast");

Logger=new MyClassDelegate.StringDelegate(MyClass.logString);

///calling Logger

Logger("hello i am Logger just acting like Single-cast");

Transmitter=new MyClassDelegate.StringDelegate(MyClass.TransmitString);

///calling Transmitter

Transmitter("hello i am Transmitter just acting like Single-cast");

///here mydelegate used the Combine method of System.MulticastDelegate

///and the delegates combine

myDelegate=(MyClassDelegate.StringDelegate)System.Delegate.Combine(Writer,Logger);

myDelegate("used Combine");

///here Transmitter is also added using the overloaded form of Combine

myDelegate+=Transmitter;

myDelegate("Using Overloaded Form");

///now using the Remove method

myDelegate=(MyClassDelegate.StringDelegate)System.Delegate.Remove(myDelegate,Writer);

myDelegate("Without Writer");

///overloaded Remove

myDelegate-=Transmitter;

myDelegate("Without Transmitter");

System.Threading.Thread.Sleep(2300);

}

}

}

Description of the Above Code:

The above program contains three classes, MyClassDelegate contains the delegate.

public delegate string StringDelegate(string s);

The class MyClass Contains the static methods that contains the static methods that have a similar signature as the delegate StringDelegate. The third class is the Test Class which shows how to combine the delegates and how to remove the delegate from the list.
Events

The Event model in C# finds its roots in the event programming model that is popular in asynchronous programming. The basic foundation behind this programming model is the idea of "publisher and subscribers." In this model, you have publishers who will do some logic and publish an "event." Publishers will then send out their event only to subscribers who have subscribed to receive the specific event.

In C#, any object can publish a set of events to which other applications can subscribe. When the publishing class raises an event, all the subscribed applications are notified. The following figure shows this mechanism.

Events are the messages sent by an object to indicate the occurrence of an event. Event can also be defined as a member that enables an object to provide notification. Events provide a very powerful means of inter-process communication. The most familiar example of events are graphical user interface, events are fired when any control is clicked on the GUI.

Events are not used only for graphical user interfaces. Events provide a generally useful way for objects to signal state changes that may be useful to the client of that object. In C# events are used with delegates. If you don't have through understanding of delegates please refer the above portion. In event communication the event raiser class doesn't know who is going to handle the event now the delegates comes into play that acts as an intermediary between the source and the receiver.

We can categories events into two types

· Customized Events

· Predefined Events



1. Customized Events:

Don't confuse these terms because I have categorized events so that the explanation become simple. Now what do we mean by customize events, they are events which we define according to our needs and are not defined. For e.g we want to raise an event whenever a dynamic control is created on the form. To declare an event, first define the delegate for that event, if none is already declared. The delegate type defines the set of argument that are to be passed to the method which will act as event handler.

Example of Customized Events:

namespace Eventhandling

{

public delegate void IamClicked();

/// Summary description for Form1.

public class Form1 : System.Windows.Forms.Form

{

/// Required designer variable.

///

private System.ComponentModel.Container components = null;

public System.Int32 o_IntCounter=0;

public event IamClicked ClickMe;

System.Int32 o_intXaxis=120;

System.Int32 o_intYaxis=80;

public Form1()

{

// Required for Windows Form Designer support

InitializeComponent();

//

// TODO: Add any constructor code after

InitializeComponent call

//

Button b1=new Button();

b1.Parent=this;

b1.Location=new Point(o_intXaxis,o_intYaxis);

b1.Name="Click1";

b1.Text="Click Me";

ClickMe+=new IamClicked(Show);

ClickMe();

}

/// Clean up any resources being used.

protected override void Dispose( bool disposing )

{

if( disposing )

{

if (components != null)

{

components.Dispose();

}

}

base.Dispose( disposing );

}

#region Windows Form Designer generated code

/// Required method for Designer support - do not modify

/// the contents of this method with the code editor.

private void InitializeComponent()

{

// Form1

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);

this.ClientSize = new System.Drawing.Size(304, 237);

this.Name = "Form1";

this.Text = "Events";

}

#endregion


/// The main entry point for the application.

[STAThread]

static void Main()

{

Application.Run(new Form1());

}

/// Event Handler Function Which is called when the

/// Click Event is Raised.

public void Show()

{

MessageBox.Show("JUST BORN");

}

}

}

Description:

The above program shows hoe we can fire our own events. In this program a button is created dynamically.

Button b1=new Button();

b1.Parent=this;

b1.Location=new Point(o_intXaxis,o_intYaxis);

b1.Name="Click1";

b1.Text="Click Me";

ClickMe+=new IamClicked(Show);

ClickMe();

The delegate and event defined in above program are

public delegate void IamClicked();

public event IamClicked ClickMe;



The delegate points to the following function.

public void Show()

{

MessageBox.Show("JUST BORN");

}

When the ClickME event is fired the delegate attached to this event call the above function Show. Look at the signature of the function and the delegate both are same. The function just shows a message box with the message "Just Born".

2. Predefined Events:

Events and delegates go hand in hand. Now we are considering Predefined events like

· Click

· Closed

· Closing

· DragDrop

· Enter

· Load

· Leave

etc

We normally use predefined events in our programming practice. Multiple events can share the same delegate type. The event is declared as the delegate type. In C# we must follow precise signature for Handler.

void OnClick(object o,EventArgs ea)

{

//Code

}

Example of Events:

using System;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

using System.Data;

namespace Eventhandling

{

/// Summary description for Form1.

public class Form1 : System.Windows.Forms.Form

{

/// Required designer variable.

private System.ComponentModel.Container components = null;

public System.Int32 o_IntCounter=0;

private System.Windows.Forms.Button btnNewControl;



public Form1()

{

// Required for Windows Form Designer support

InitializeComponent();

// TODO: Add any constructor code after

InitializeComponent call

}

/// Clean up any resources being used.

protected override void Dispose( bool disposing )

{

if( disposing )

{

if (components != null)

{

components.Dispose();

}

}

base.Dispose( disposing );

}



#region Windows Form Designer generated code

/// Required method for Designer support - do not modify

/// the contents of this method with the code editor.

private void InitializeComponent()

{

this.btnNewControl = new System.Windows.Forms.Button();

this.SuspendLayout();

// btnNewControl

this.btnNewControl.Name = "btnNewControl";

this.btnNewControl.Size = new System.Drawing.Size(112, 32);

this.btnNewControl.TabIndex = 0;

this.btnNewControl.Text = "New Control";

this.btnNewControl.Click += new System.EventHandler(this.btnNewControl_Click);

// Form1

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);

this.ClientSize = new System.Drawing.Size(304, 237);

this.Controls.AddRange(new System.Windows.Forms.Control[] {

this.btnNewControl});

this.Name = "Form1";

this.Text = "Events";

this.ResumeLayout(false);



}

#endregion

/// The main entry point for the application.

[STAThread]

static void Main()

{

Application.Run(new Form1());

}

/// Event Handler Function Which is called when the

/// Click Event is Raised.

public void btnAdd(object o,EventArgs ea)

{

o_IntCounter++;

MessageBox.Show(o_IntCounter.ToString());



}

private void btnNewControl_Click(object sender, System.EventArgs e)

{

System.Int32 b_intCount;

System.Int32 b_intXaxis=120;

System.Int32 b_intYaxis=80;

for(b_intCount=1;b_intCount < = 3;b_intCount++,b_intYaxis+=20)

{

///new buttons are created at run time

///with there location and names.

Button b1=new Button();

b1.Parent=this;

b1.Location=new Point(b_intXaxis,b_intYaxis);

b1.Name="Click1"+b_intCount;

b1.Text="Click Me";

b1.Click+=new EventHandler(btnAdd);

}

}

}

}

Description:

The above program creates three buttons at run time and when any of the buttons is clicked the Click event of that button is fired.

for(b_intCount=1;b_intCount < = 3;b_intCount++,b_intYaxis+=20)

{

///new buttons are created at run time

///with there location and names.

Button b1=new Button();

b1.Parent=this;

b1.Location=new Point(b_intXaxis,b_intYaxis);

b1.Name="Click1"+b_intCount;

b1.Text="Click Me";

b1.Click+=new EventHandler(btnAdd);

}

The Click event belongs to the button class. We will reference it when we are registering a delegate.

b1.Click+=new EventHandler(btnAdd);

The delegate EventHandler is also defined in the System namespace of Dot net Framework library. All what we have to do is to define our callback function that is invoked when the button is clicked and accepts two arguments object and EventArgs type conforms the signature of delegate EventHandler defined in System namespace

public void btnAdd(object o,EventArgs ea)

{

o_IntCounter++;

MessageBox.Show(o_IntCounter.ToString());

}

The handler btnAdd() Method catches this event and shows a message box that indicates a number that how many times these buttons are clicked.

Diff between Event and Delegates:-

1) Delegates are the like pointer to the event it only point to the event and that event get fire
like we can say
use can raise event even without that event happen

2) Events are the actions of the system on user manipulations (e.g. mouse clicks, key press, timer etc.) or any event triggered by the program.
Delegate is type which holds the method(s) reference in an object. It is also referred as a type safe function pointers.

3) Delegated is a Function Pointer that stores address of Subprograms
Events are raised by using Delegates

4) Event is Array list of delegates .
* Delegate (as its English meaning): Secretary or someone who connect two persons through him.
* Delegate can fire only one method
But Event fire more than one delegate, each call one method

* Example : in Windows App. or ASP.NET App.
Button : is a class that has internally an event called ( e.g. click ) and there is
a method you want to do if this button clicked so make an instance of the delegate
which button. Click deal with ( System.EventHandler ) and make this delegate
execute the method e.g. Button1_Click
Google