Search code examples
c#asp.neteventsgridviewiteration

Can't wire-up Click event for dynamically created Buttons in a GridView


I'm dynamically creating the templates for a GridView and data binding it in my ASP.NET web app. I've added the header column templates as well as a column of buttons. The trouble I'm having is that wiring up click events for the buttons never seem to fire. I've tried grabbing the buttons (after the DataBind() method) in multiple ways, but nothing seems to fire when the button is clicked.

Note: the GridView is inside an ASP:UpdatePanel and AJAX accordion pane (ToolkitScriptManager on Site.Master).

Here's the relevant portion of the aspx page (simplified)...

<ajaxToolkit:AccordionPane ID="accordionSelfRegisteredUsers" runat="server">
    <Header>Find All Self-Registered Users</Header>
    <Content>
        <asp:UpdatePanel ID="updatepnlSelfRegisteredUsers" runat="server">
            <ContentTemplate>
                <div id="divFixedHeaderSelfRegisteredUsers"></div>
                <div id="divSelfRegisteredUsers">
                    <asp:GridView ID="gridviewSelfRegisteredUsers" runat="server"
                        AutoGenerateColumns="False" />
                </div>
            </ContentTemplate>
        </asp:UpdatePanel>
    </Content>
</ajaxToolkit:AccordionPane>

Here's the page's C# code.

One way...

List<Button> gvConfirmButtons = new List<Button>();
foreach (GridViewRow row in gridviewSelfRegisteredUsers.Rows)
{
    foreach (Control c in row.Controls)
    {
        if (typeof(DataControlFieldCell) != c.GetType())
        {
            continue;
        }
        foreach (Control cf in c.Controls)
        {
            if (typeof(Button) == cf.GetType())
            {
                gvConfirmButtons.Add((Button)cf);
            }
        }
    }
}
foreach (Button b in gvConfirmButtons)
{
    b.Click += new EventHandler(btnGVSRUConfirm_Click);
}

And another I tried...

foreach (GridViewRow row in gridviewSelfRegisteredUsers.Rows)
{
    foreach (Control c in row.Controls)
    {
        if (typeof(DataControlFieldCell) != c.GetType())
        {
            continue;
        }
        for (int i = 0; i < gridviewSelfRegisteredUsers.Rows.Count; i++)
        {
            //find buttons by client ID
            Button b = (Button)c.FindControl(
                "contentMain_gridviewSelfRegisteredUsers_btnConfirm_" + i);
            b.Click += new EventHandler(btnGVSRUConfirm_Click);
        }
    }
}

The buttons are found and I can access them, but the click event from the button never triggers the click event method I have in code.

private void btnGVSRUConfirm_Click(object sender, EventArgs e)
{
}

Any thoughts on how I might be messing this up? I have a feeling it's related to the current state of the gridview within the page lifecycle when the button is clicked by the user, but not sure how to proceed.


Solution

  • I had a simular issue a while back when putting an update panel inside a ModalPopup control. Something to do with the __doPostback not being wired-up correctly to the buttons OnClick event. Not sure if it is a bug or what, but this is what I did in the Page_Load event to solve the issue:

    PostBackOptions opt = new PostBackOptions(this.YourButtonID);
    opt.AutoPostBack = true;
    opt.ClientSubmit = true;
    opt.PerformValidation = true;
    opt.RequiresJavaScriptProtocol = true;
    
    // This will put a '__doPostBack()' javascript call on the OnClick 
    // event (using above options).
    this.YourButtonID.OnClientClick = ClientScript.GetPostBackEventReference(opt);
    

    Hope this solves your issue!