Exposing events in Web User Controls

Posted by gabriel, Sat May 17 19:08:00 UTC 2008

Web User Controls are a way encapsulating code that would have to be repeated in various pages, they are definitely a huge help.

VisualStudio makes so simple to create these user controls that even novice users can do it. When the page doesn’t need to interact with the user control it is really simple, and there’s nothing to it but putting the controls you want in the user control. However the controls that are inside the user control are isolated from the Page and you can’t use it’s events. This post will show you how easy it is to overcome this issue.

Let’s say we want to create a simple control with a DropDownList, a Button and a Label. When the button is clicked the selected value in the DropDownList is copied to the label. Here’s the code for it:


<%@ Control Language="C#" ClassName="MyUserControl" %>

<script runat="server">

    protected void ButtonCopy_Click(object sender, EventArgs e)
    {
        LabelText.Text = DropDownListNames.SelectedValue;
    }
</script>
<asp:DropDownList ID="DropDownListNames" runat="server">
    <asp:ListItem>Elisa</asp:ListItem>
    <asp:ListItem>Gabriel</asp:ListItem>
    <asp:ListItem>Rafaela</asp:ListItem>
</asp:DropDownList>
<br />
<br />
<asp:Button ID="ButtonCopy" runat="server" Text="Copy SelectedValue to Label" 
    onclick="ButtonCopy_Click" />
<br />
<br />
<asp:Label ID="LabelText" runat="server" Text="Label" Font-Size="X-Large"></asp:Label>

This is simple enough, right? All you have to do is place this control in any page and this behavior is going to be replicated. What I notice that most novice programmers miss is if you need the control to send some kind of information to the page.

Say you want to have a label in your page showing the time that the Copy button of the user control is clicked. It would be easy if you could access the button click event of the button inside the user control but unfortunately you can’t. What you want is to make the event of the inner button accessible to outside the control, this is done creating a new event exposing the event you want.


<%@ Control Language="C#" ClassName="MyUserControl" %>

<script runat="server">

    //this is the event that will be exposed
    public event EventHandler ButtonClick;

    protected void ButtonCopy_Click(object sender, EventArgs e)
    {
        LabelText.Text = DropDownListNames.SelectedValue;

        //this tests if the event has been subscribed by any method
        if (ButtonClick != null)
        {
            //fires the event passing the same arguments of the button
            //click event
            ButtonClick(sender, e);
        }
    }
</script>
<asp:DropDownList ID="DropDownListNames" runat="server">
    <asp:ListItem>Elisa</asp:ListItem>
    <asp:ListItem>Gabriel</asp:ListItem>
    <asp:ListItem>Rafaela</asp:ListItem>
</asp:DropDownList>
<br />
<br />
<asp:Button ID="ButtonCopy" runat="server" Text="Copy SelectedValue to Label" 
    onclick="ButtonCopy_Click" />
<br />
<br />
<asp:Label ID="LabelText" runat="server" Text="Label" Font-Size="X-Large"></asp:Label>

Now you are able to put the control in a page and use it’s event, like in the following example:


<%@ Page Language="C#" %>

<%@ Register Src="MyUserControl.ascx" TagName="MyUserControl" TagPrefix="uc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">
    protected void MyUserControl1_ButtonClick(object sender, EventArgs e)
    {
        LabelTime.Text = DateTime.Now.ToString();
    }
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <!-- Notice here that I use ButtonClick event I just created in the user control -->
        <!-- Also notice that I didn't misspell the event, the On is added by a VisualStudio convention   -->
        <uc1:MyUserControl ID="MyUserControl1" runat="server" OnButtonClick="MyUserControl1_ButtonClick" />
        <br />
        <asp:Label ID="LabelTime" runat="server" Text="Label" Font-Bold="True" 
            Font-Italic="True" ForeColor="#FF3300"></asp:Label>
    </div>
    </form>
</body>
</html>

You could also subscribe to the event in the code behind just like you do with asp.net controls. Here is the code for it:


<%@ Page Language="C#" %>

<%@ Register Src="MyUserControl.ascx" TagName="MyUserControl" TagPrefix="uc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">
    public void Page_Load(object sender, EventArgs e)
    {
        MyUserControl1.ButtonClick += MyUserControl1_ButtonClick;
    }

    protected void MyUserControl1_ButtonClick(object sender, EventArgs e)
    {
        LabelTime.Text = DateTime.Now.ToString();
    }
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <!-- Notice here that I use ButtonClick event I just created in the user control -->
        <!-- Also notice that I didn't misspell the event, the On is added by a VisualStudio convention   -->
        <uc1:MyUserControl ID="MyUserControl1" runat="server" />
        <br />
        <asp:Label ID="LabelTime" runat="server" Text="Label" Font-Bold="True" 
            Font-Italic="True" ForeColor="#FF3300"></asp:Label>
    </div>
    </form>
</body>
</html>

I wrote this post because I helped a few people in the asp.net forums and I hope it can help other people that are beginning to write web user controls. Happy coding guys.

Filed Under: Tips and Tutorials | Tags: asp.net user controls

Comments

  1. Alain 05.25.08 / 11AM
    Can you tell me how to replace with code OnButtonClick="MyUserControl1_ButtonClick" which you put in the source code of the page

Have your say

A name is required. You may use HTML in your comments.