views:

716

answers:

2

I am creating an user control. The user control is a div and I want to add a click event to it.

Edit:

The page that has this control on it has to handle this event.

How can I do this?

+2  A: 

First, you need to define an event on your UserControl that allows Page that contains the UserControl to register and handle the event. For example:

public partial class MyUserControl : System.Web.UI.UserControl
{    
    // Event for page to handle
    public event EventHandler DivClicked;

    protected virtual void OnDivClicked(EventArgs e)
    {
        if (DivClicked != null)
            DivClicked(this, e);
    }        

    protected void Page_Load(object sender, EventArgs e)
    {
        // Page Load Code goes here
    }
}

Note: The next part would be easier if you were using a control that supported postbacks. However, since you want to use a div, I'll explain how to force a div to do postbacks. I'd like thank Mathew Nolton for this solution.

So, in the Page_Load method of the UserControl you need add an onClick attribute to call the ASP.NET's __doPostback() javascript function that calls the server back for your div. This is what gives a div the ability to postback to the server. In addition, to determine which control caused the postback, I supplied the div's ClientId along with some symbols to differentiate my postback from other controls. Remember when you define the div on the .ascx file it has to have an id assigned and set runat="server", to be accessible on the server side.

Ok, now by adding an onclick attribute to the div, it will postback to the server anytime its clicked. So, when a postback causes Page_Load to get called, I check to see if it was the div which caused the postback. If so, I raise the UserControl's DivClicked event to be handled by the Page.

public partial class MyUserControl : System.Web.UI.UserControl
{
    // Event Definition and Raising methods
    ...

   protected void Page_Load(object sender, EventArgs e)
   {
       // @@@@ will denote this is an argument I provided.
       string arg = "@@@@" + divClickableDiv.ClientID;
       // Add postback method to onClick 
       divClickableDiv.Attributes.Add("onClick", 
       Page.ClientScript.GetPostBackEventReference(divClickableDiv, arg));

       if (IsPostBack)
       {
           // Get event arguments for post back.
           string eventArg = Request["__EVENTARGUMENT"];

           // Determine if postback is a custom postback added by me.
           if (!string.IsNullOrEmpty(eventArg) && eventArg.StartsWith("@@@@"))
           {
               // Raise the click event for this UserControl if the div
               // caused the post back.
               if (eventArg == arg) 
                   OnDivClicked(EventArgs.Empty);
            }
        }
    }
}

That should do it for the UserControl, now all you have to do is register for the DivClicked event on the page.

Unfortunately, you wont get design time support to register for the event. However, you can still add the code to the .aspx page. On the page where you drop your UserControl add an attribute to the UserControl called OnXXX where XXX is the name event. So, for my example above i would define my UserControl on the page would look like this:

<uc1:MyUserControl  ID="MyUserControl1" runat="server" OnDivClicked="MyUserControl1_DivClicked" />

Now you add your handler code to the Page's codebehind file (assuming your using codebehind) like this:

public partial class MyPage : System.Web.UI.Page 
{
    // Called whenever div in MyUserControl is clicked.
    protected void WebUserControl1_DivClicked(object sender, EventArgs e)
    {
        // Handle Div click event here.
    }
}

That should do it. I hope this post helps you.

rocka
Wow, what a fine explanation! Very interesting stuff! Thank you very much!
Martijn
No problem. Glad I could help
rocka
+3  A: 
<div runat="server" onserverclick="MyClickHandler">
...
</div>
orip