Article
Event Driven ASP.NET Development with C#
Sharing an Event Handler
In many cases, you may wish to define a single event handler for multiple event sources. Since all event handlers receive a reference to the source of the event, they can determine which of the multiple sources originated the event and act accordingly.
Consider the following, updated version of ButtonTest.aspx:
<%@ Page Inherits="ButtonTest" src="ButtonTest.cs" %>
<html>
<head>
<title> Event handler example </title>
</head>
<body>
<form runat="server">
<p>
<asp:Label runat="server" id="message">
Click a button!</asp:Label>
</p>
<p>
<asp:Button runat="server" id="button1"
Text="One" />
<asp:Button runat="server" id="button2"
Text="Two" />
<asp:Button runat="server" id="button3"
Text="Three" />
</p>
</form>
</body>
</html>
We now have three buttons to choose from, and we'd like to display a different message upon clicking each. Here's the updated code behind file, ButtonTest.cs:
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 Button button2;
protected Button button3;
protected Label message;
protected void Page_Init(Object sender, EventArgs e)
{
EventHandler clickHandler =
new EventHandler(ButtonClick);
button1.Click += clickHandler;
button2.Click += clickHandler;
button3.Click += clickHandler;
}
protected void ButtonClick(Object sender, EventArgs e)
{
if (sender is Button)
{
Button clickedButton = (Button)sender;
message.Text = "You clicked: " + clickedButton.Text;
}
}
}
We've added references to our two new buttons, and assigned our EventHandler to a variable (clickHandler), which we then add to the Click events of all three buttons. Finally, I've modified the ButtonClick method to display the name of the button that the user clicked. Let me walk you through the code, as it uses a couple of tricks I have not discussed before.
if (sender is Button)
{
The ButtonClick method will always be called with the source of the event in the sender parameter. That parameter is of type Object, which is the base class of the .NET Framework (i.e. all classes are subclasses of System.Object). To display the name of the button that was clicked, we need to treat this parameter as a Button -- not just a mere Object. Before doing so, we must check to be sure that the sender parameter is indeed a Button object, despite being stored in a variable of type Object.
Note: This ability for any object to be stored in a variable of the same class or any of its base classes (a.k.a. superclasses) is actually a feature of modern object oriented languages called polymorphism. In the previous article, this same feature allowed us to treat objects of classCoconutTreejust like objects of classTreeif we wanted to.
To check that the object stored in sender is of class Button (or any subclass thereof), we use the is operator in C#. The syntax is relatively self-explanatory; if sender contains an object that can be treated as a Button, then sender is Button will be true.
Button clickedButton = (Button)sender;
Since we've checked that sender contains a Button, we can create a variable of type Button and store the value of sender into it. Since, as far as C# knows, sender is just an Object, and you can't store an Object in a Button variable, we need to tell C# to take the value in sender and convert it to a Button. This is done by enclosing the type to convert to in parentheses and putting it before the variable name, as we've done here.
This explicit conversion of a value from one type to a more complex type is called casting. An experienced C# programmer would say that we are "casting sender to a Button" on the above line.
Finally, now that we have our clicked button in the clickedButton variable, we can use its label to display an appropriate message:
message.Text = "You clicked: " + clickedButton.Text;
See Figure 2 for the results, or try the script on your own server!
Figure 2: Same event handler, multiple outcomes