Article
Event Driven ASP.NET Development with C#
Assigning Handlers in the Code Behind
While the previous example was fairly straightforward, it did have one sticking point. The event handler for the button was assigned in the .aspx file, violating the separation of design code and server-side logic that we have previously achieved with code behind files.
To improve this situation, we can instead assign the event handler in the code behind. The best place to do this is in the Page_Init method, which is called automatically by ASP.NET when the page is initialized (i.e. when the server loads it before processing the first request for it by a browser). Here's the updated ButtonTest.cs, with changes shown in bold:
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
public class ButtonTest : Page
{
protected Button button1;
protected Label message;
protected void Page_Init(Object sender, EventArgs e)
{
button1.Click += new EventHandler(ButtonClick);
}
protected void ButtonClick(Object sender, EventArgs e)
{
message.Text = "Thanks for clicking!";
}
}
Make the changes above, remove the OnClick attribute from the button1 tag in ButtonTest.aspx, and you should find that the example behaves exactly as before. Let's examine what we've done here:
button1.Click += new EventHandler(ButtonClick);
As you can probably guess, this line adds the ButtonClick method as a handler for the Click event of button1. But the syntax is somewhat mysterious, especially compared to the simple OnClick attribute it replaces!
All .NET events behave similarly to properties of their respective classes. So the Click event supported by all System.Web.UI.WebControls.Button objects is accessible in this case as button1.Click.
Now, any .NET event can have multiple handlers associated with it (i.e. multiple methods that will be triggered in sequence when the event occurs). So rather than assigning an event handler with the assignment (=) operator, we merely add an event handler to whatever existing handlers may exist (+=). .NET does not let you use the = operator with events, and any attempt to do so will result in a compilation error. You can also use the -= operator to remove event handlers, but that's it.
As for the event handler itself, you may have expected to see something like this (I know I did!):
button1.Click += ButtonClick; /* This is wrong */
The reason we must explicitly create an EventHandler object with the ButtonClick method (rather than directly assigning the method as an event handler) has to do with a confusing little detail of the C# language -- delegates.
I'll refer you to the C# Language Specification or a good book such as "Programming C#" (O'Reilly, 2001) for a complete discussion of delegates; however, here are the basics. A C# delegate is special type of class, objects of which contain a group of methods that have the same number and type of parameters and return the same type of value.
The System.EventHandler class is a simple example of a delegate. EventHandler specifies that it must contain methods that take two parameters (an Object and an EventArgs) and return void.
So as an event of type System.EventHandler, the Click event of the Button class requires us to assign it a delegate of type EventHandler. To do this, we create a new EventHandler object containing our ButtonClick method with the code new EventHandler(ButtonClick), and add it to the event.
Don't fret too much if this is really not sinking in. Delegates were the hardest feature of C# for me to come to grips with, as it is not a feature you'll easily find in other languages in popular use today. After awhile, the syntax just becomes second nature, and only advanced applications require an understanding of delegates beyond how to create event handlers with them.