Building a web application has become a snap using Visual Studio.NET. You create
an aspx webform, drag some controls from the toolbar and then customize
the controls in the properties window. That window has two tabs, one for the
properties themselves and one for events. Properties have straight values like
a color or size, but events stand for real code. This code is written in the
programming language chosen for the project. I will choose C# to explore this
world of .NET events.
Every event has an associated event handler, this is the piece of code which
will execute when the event occurs. When the user clicks a button an OnClick
event occurs and the associated OnClick
method will run. .NET has a carefully designed model behind this. An object
is said to publish an event, methods of an object can subscribe to the event.
A button publishes an OnClick event, a Button1_Click
will subscribe to this publication. The publishing button will fire methods
on the subscribers, Button1_Click will be executed
when the user really clicks the button. This may sound an overcomplicated way
to do get things done, but the nice thing in this model is that it is no problem
at all for a publisher to have multiple subscriptions. This is also known as
a multicast event. So when the user hits the button other subscribers than just
your Button1_Click could be fired as well.
The method being fired by .NET components is of type void and has two parameters.
The first parameter is the sender, this is the object which did fire the event.
It is the button which was clicked. The second parameter is an object to hold
arguments in which additional info can be passed from the publisher to the subscriber.
The result type of the method in combination with the number and type of its
parameters is called the signature of a method. In .NET a method signature can
be declared as a type on itself and is called a delegate. From this delegate
type subscriber objects can be created. The method to be executed when the subscriber
gets notified by the publisher is passed as a parameter to the constructor of
the delegate object.
In the core of the .NET class libraries is System.delegate,
a base class to describe event signatures. This is a sealed class which means
you cannot use classical OOP to create your own delegate classes. There is a
point there, a delegate is only the declaration of a single method, without
its class. Which is something which cannot really exist in .NET, as everything
is an object in there. Instead the C# language has the delegate keyword
to declare your method signature as it is. From this delegate you create delegate
objects which subscribe to published event properties. System.EventHandler
is a wrapper class round a delegate for the default (minimal) signature in a
.NET event. The type is used for control properties like Click.
The .NET Framework has events everywhere and the handling of events in .NET
offers some very interesting possibilities. In this article I will show how
event handling methods are linked to webcontrols and how to (de-) couple these
event handlers at runtime.
A webform with a button
I will create a new webform. On this webform is a list box and a button. In
the button's properties window I select the events tab and doubleclick
the action Click to enter the code editor.
When the user clicks this button I want to add a message to the list box, so
I code:
| private
void Button1_Click(object
sender, System.EventArgs e)
{
ListBox1.Items.Add("You clicked
the button...");
}
|
Every time the button is clicked the list box grows. To clear the list box
I will use a second button also with a Click
action.
| private
void Button2_Click(object
sender, System.EventArgs e)
{
ListBox1.Items.Clear();
}
|
These two methods are event handlers. They contain code which is executed when
the event, being with the click of a button, happens. Both methods have the
System.EventHandler signature, a void method
taking a parameter of type object and a parameter of type System.EventArgs.
First I will dive deeper into sender, the first parameter. It is the
object which fired the event. A button click is fired by a button, I should
be able to get some button info out of this sender parameter.
| private
void Button1_Click(object
sender, System.EventArgs e)
{
System.Web.UI.WebControls.Button
b = sender as System.Web.UI.WebControls.Button;
if (null != b)
ListBox1.Items.Add(string.Format("You
clicked a button with caption '{0}'", b.Text));
else
ListBox1.Items.Add("You clicked something else");
}
|
The incoming sender object is typecasted to webbutton b using the as
operator. The nice thing about this operator is that b will be set to
a null value when the sender was not a Web button, without raising an exception.
This is a good example of typesafety in .NET, a variable is either of the correct
type, as declared, or null. Performing a hard typecast
|
System.Web.UI.WebControls.Button b = (System.Web.UI.WebControls.Button)
sender; |
would raise an exception when the sender is not a Web button.
A generic eventhandler
Every event handler has the System.EventHandler
signature. I will create a new method having this same signature, it will do
exactly the same as the previous Button1_Click.
| void
ClickMe(object sender, System.EventArgs
e)
{
System.Web.UI.WebControls.Button b
= sender as System.Web.UI.WebControls.Button;
if (null
!= b)
ListBox1.Items.Add(string.Format("You
clicked a button with caption '{0}'", b.Text));
else
ListBox1.Items.Add("You
clicked something else");
}
|
With the property editor you can set the event handing method of a control.
In a dropdown all methods with the EventHandler
signature will be shown. The ClickMe method
I just wrote will be one of them.

I will add another control to the form, a Link Button. This control has a click
action as well. The ClickMe method will appear
again in its dropdown list and I will use this same method again.
Now two controls on my webform use the same event handling method. The result
of clicking the controls can be seen in the list box.

Multiple event handlers responding to one event
So far just one method fired when an event happened. The nice thing about event
handlers in .NET is that multiple methods can be executed when an event fires.
The event handler has a collection of subscribed delegate objects and each delegate
object has a method which will be fired. I need another event handling method
to demonstrate this.
| void
JustAnotherEventHandler(object sender, System.EventArgs
e)
{
ListBox1.Items.Add("Event 1 says
hello");
}
|
This method has to be connected to the event, the user clicking button1. In
.NET speak my method will have to subscribe to the buttonClick
publication. This is done by creating a subscribing delegate object. The method
to be fired is passed as a parameter to the constructor. The System.Eventhandler
class provides standard delegate objects.
| void
Page_Load(object sender, System.EventArgs
e)
{
// Put user
code to initialize the page here
Button1.Click+= new
System.EventHandler(this.JustAnotherEventHandler);
}
|
A webform is initialized in the Page_Load method
(which is actually an event as well). The delegate object is constructed using
the JustAnotherEventHandler method. The object
subscribes by adding itself with the += operator to the Button1.Click
event. The result of this is that clicking the button will now result in two
methods being executed, leading to two strings being added to the list box:

Passing data in the event
The second parameter of the event handling method is
used to bring data from the publisher to the subscriber. This second parameter
in System.Eventhandler is of type System.EventArgs,
and cannot hold any data itself. It is a base class from which you can inherit
to satisfy your needs. I will derive the MyEventArgs
class from the System.EventArgs class, objects
of my class pass a string to the subscriber of the event. This string is initialized
in the constructor of my arguments class.
| class
MyEventArgs : System.EventArgs
{
public string
astring;
public MyEventArgs(string
a)
{
astring = a;
}
}
|
A delegate is used to connect subscribing methods to a publisher. I need a
delegate which understands MyEventArgs. It is
declared straightforward way:
| delegate void
MyDelegate(object sender, MyEventArgs e); |
This delegate describes the signature of methods
which can be connected. So, I need a method which has this signature
and does know what to do with MyEventArgs.
| void
ListString(object sender, MyEventArgs e)
{
ListBox1.Items.Add(e.astring);
}
|
The method extracts a string form the incoming MyEventArgs
object and adds it to the list box.
Now I have all the building blocks to create the MyEvent
class. Objects of this class contain the data, know how to fire MyEvent
and know how to fire a default event. I have to store and (later) execute a
method, which can be handled by declaring a variable of type MyDelegate.
This variable is assigned to in the constructor and is fired when the event
occurs in the DoIt method:
| class
MyEvent
{
private MyDelegate YouDoIt;
private string
param;
public MyEvent(MyDelegate
d, string p)
{
YouDoIt = d;
param = p;
}
public void
DoIt(object sender, System.EventArgs e)
{
YouDoIt(sender, new MyEventArgs(param));
}
}
|
The data for the event is stored in the private param
string. The method to be fired is stored in the private MyDelegate
object YouDoIt. Both values are initialized
in the constructor of the MyEvent class.
The class has a method DoIt, this method has
exactly the signature of the default EventHandler
delegate. So it can be used to construct delegate objects for subscribing to
a button click. The method DoIt will fire my
own delegate passing it the original sender and a new MyEventArgs
object based on the param string.
Now everything is ready to add this data sending event to the click of the
button.
| MyEvent mevent = new
MyEvent( new MyDelegate(this.ListString),
"Just fooling..");
Button1.Click+= new System.EventHandler(mevent.DoIt);
|
A new MyDelegate object based on the ListString
method is created. Together with a string constant it is used to construct
a MyEvent object. This MyEvent
object has the method DoIt which has the right
signature to create a new System.EventHandler
delegate object. Which will subscribe to the Button.Click
event.
Clicking the button will now lead to three methods firing and three strings
being added to the list box.

Adding it up : dynamically adding and deleting events
Every time the user clicks a button this leads to a roundtrip. On the webserver
the page will be rebuild in the Page_Load method.
This is the place to connect and disconnect additional event handling code.
When doing so I can use the state of the controls on the webform to decide whether
to connect. Text values in controls are used to construct MyDelegate
objects. I will add three checkboxes on the form which will determine the setting
of the handlers.
| void
Page_Load(object sender, System.EventArgs
e)
{
// Put user code to initialize
the page here
if (CheckBox1.Checked)
{
MyEvent mevent =
new MyEvent(new
MyDelegate(this.ListString), TextBox1.Text);
Button1.Click+=
new System.EventHandler(mevent.DoIt);
}
if (CheckBox2.Checked)
{
MyEvent mevent =
new MyEvent(new
MyDelegate(this.ListString), Label1.Text);
Button1.Click+=
new System.EventHandler(mevent.DoIt);
}
if (! CheckBox4.Checked)
Button1.Click-=
new System.EventHandler(this.ClickMe);
}
|
If one of the first two checkboxes is checked a new MyEvent
object will be created and its DoIt method
will subscribe at runtime to the Button1.Click
event publisher. The data string needed in the constructor of MyEvent
is read from a TextBox for the first event handler
and from a Label for the other.
Button1.Click had one event handler set at
design time, this was the ClickMe method. If
the third checkbox is not checked a new delegate object based on ClickMe
is created and this object will be subtracted from the Button1.Click
event using the -= operator. The ClickMe
method withdraws its subscription to the click event and will no longer be executed
when the button is clicked.

Events in real world applications
For the sake of simplicity I have used a very basic webform and very basic
event data. Included is a small demo application
to play with events yourself. It is up to your imagination and needs to create
any event handling code you can think of and construct any event data you might
consider useful. At design time one event handling method can be set, at runtime
you can rebuild the list of event subscribers again and again at every page_load.
The strongest thing about events in C# is that they are multicast. When you
have a background in Delphi you probably were familiar with event handlers which
could be set at runtime. But with Delphi you could hook only one method at the
time. In C# you can send your events out to anyone who wants to hear them.