I was hoping to get this post up earlier, but got distracted by a couple of things. First, I jacked up my hand trying to separate my dogs from fighting to the point I couldn’t even move my ring finger (long story about the dogs, but I love ‘em). Second, I started a new job at Groove Commerce on Monday. So far, so good. I feel it’ll keep me on my game and give me some nice challenges ahead.
A few entries ago we talked about custom server controls and mentioned how to structure a composite control to allow the ViewState to “pick up” on it’s post back content so that data isn’t re-binded with every call. It was a very basic composite control, but it showed how to add native WebControl objects to the Controls tree to create a basic layout without using a .ASCX design file. This type of control can be added to your app_code directory or manually compiled as an assembly and placed into your bin directory. The advantage of the latter is to feasibly add it to your Visual Studio toolbar by loading the assembly. This time, we’ll add a custom event to our control using a delegate for an event, as well as a custom event argument class to pass along with it.
We’ll take the code from last time, but add several things which are highlighted in green.
- A line to declare our event delegate variable and the delegate itself.
- A class which will be used for our arguments.
- A binded event for the button Click.
- A line in the button Click handler to invoke the event delegate.
using System;
using System.Web;
using System.Web.UI.WebControls;
using System.ComponentModel;
namespace RyanControls
{
public class MyCompositeControl : CompositeControl
{
public MyCompositeControl() { }
// Declare the Updating event of delegate type CustomControlUpdateHandler
public event CustomControlUpdateHandler Updating;
protected override void CreateChildControls()
{
TextBox txtMyData = new TextBox();
DropDownList drpMyList = new DropDownList();
Button btnUpdate = new Button() { Text = "Update!" };
Controls.Add(drpMyList);
Controls.Add(txtMyData);
Controls.Add(btnUpdate);
if (!Page.IsPostBack)
{
drpMyList.Items.Add(new ListItem("item 1"));
drpMyList.Items.Add(new ListItem("item 2"));
drpMyList.Items.Add(new ListItem("item 3"));
}
// Add a handler for the button click to launch the Updating event
btnUpdate.Click += new EventHandler(FireEvent);
}
// The method that handles the Click event from the button
// and triggers the Updating event by calling the delegate
protected void FireEvent(Object s, EventArgs e)
{
Updating(s, new CustomControlUpdateEventArgs() { SomeData = "The control was updated!" });
}
}
// Our custom event class that inherits EventArgs. You may use
// EventArgs as the class if you don't have additional data to pass
public class CustomControlUpdateEventArgs : EventArgs
{
public CustomControlUpdateEventArgs() { }
public String SomeData;
}
// The delegate declaration (or template, as I call it) for the handler
public delegate void CustomControlUpdateHandler(Object s, CustomControlUpdateEventArgs e);
}
There you have it. If you place this code into a .CS file inside your app_code directory, you’ll be able to include the control on your pages. If you compiled it into an assembly, toss it into your bin directory and feel free to add it to your toolbar in VS or VWD.
<asp:MyCompositeControl runat="server" ID="cntMyControl" OnUpdating="DisplayUpdate" />
By assigning an event handler for the Updating event (the page automatically prepends the “On” for “OnUpdating”) to call a method to handle the update, you can use data contained in the CustomControlUpdateEventArgs object. In this case, there’s only a public string called SomeData.
protected void DisplayUpdate(Object s, RyanControls.CustomControlUpdateEventArgs e)
{
Response.Write(String.Format("<div>From the event handler: {0}</div>", e.SomeData));
}
When you run the code and click the button, the method will be invoked and the message displayed. Similarly, you can bind the handler programmatically by adding cntMyControl.Updating += new RyanControls.CustomControlUpdateHandler(DisplayUpdate) in your code-behind.
So again, while the code isn’t really useful, it shows how to create your own event handlers and custom argument class(es) for a composite server control. The point is to be able to create one or more event handlers, as well as combine those with one or more types of event argument classes. The fields of that particular argument class should be specific to that type of event and it is best not to use one custom event args class to satisfy many types of event argsuments, unless the data being passed into your hander functions generic enough to do so.
Happy coding!

