Button Control not firing CommandEventHandler

Dynamically building a Table object with each row having one TableCell.Controls.Add(newButtonControl)

set newButtonControl.Text
set newButtonControl.Id
set newButtonControl.Command += new CommandEventHandler(this.Update_Click);
set newButtonControl.OnClientClick

protected void Update_Click(object sender, EventArgs e) will not fire

All of this is in a panel.  I have a breakpiont in Update_Click but never gets hit.
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Hi there,
There is a problem where you can not add a handler to a dynamically generated button outside of the Page_Load event.

I used to dynamically generate tables to display my records until I found out about the repeater control.  It may take you a little while to get your head around it but trust me, it is a much better solution and handles buttons perfectly well.
I'm more of a VB man myself so it took me a while to find an example for you in C# that completely uses the codebehind.  I myself am not a fan of inserting code directly into the .aspx file.

Check out this example. It should show you what I mean. They use dynamic text boxes and buttons.


The key functions that you should look at are :

YourRepeater_ItemDataBound <-- This populates your records

Pay attention the the CommandName and CommandArgument that is given to the buttons.  You will need this info in the below function.

YourRepeater_ItemCommand <-- This handles the button clicks inside the repeater.

ws11Author Commented:
Is this a limitation on buttons only or on other controls as well?
CompTIA Cloud+

The CompTIA Cloud+ Basic training course will teach you about cloud concepts and models, data storage, networking, and network infrastructure.

Basically anything that has events.  So that's buttons, dropdownlists etc.  It all has to do with the page life cycle, the timing of when things are set up, rendered etc.  As I understand it, by the time you come to adding your buttons to the page it's too late to add the handler to the button.

When I originally had this issue I found many articles about this on the net as many developers have come across this issue.  I'm just finding it hard to find anything that properly explains the problem for you.

If you're merely displaying data then dynamically creating the table is fine but I do suggest looking at the repeater.  If you're wanting to add buttons and stuff that works with events then you're best to use the repeater.
ws11Author Commented:
I have a possible solution.  My Onclientclick event does work.  I could simply mark the row by changing the value of a hidden input and then check the response from the submit.  The problem that I still have is I can not get the postback to return the previous panel that I was viewing.  It returns to the default panel.
ws11Author Commented:
So basically anything with a template for each row should work.  I guess a list view would also resolve this.
OnClientClick will work because that information has already been rendered to the page and is irrelevant of the postback.  The problem is that as you have rendered the buttons after the PageLoad  method the postback information for the buttons has not been rendered to the page.

The problem with viewing information like this is that it does not retain session state.  You have to re-generate your results every time otherwise they simply will not
be displayed.  I believe this is the same with the Repeater but I am not sure as to the exact specifics.

Honestly, give the Repeater a try.  It is so much more powerful and flexible than generating the table yourself.  Once you get the hang of it you'll wonder how you ever did without it.
ws11Author Commented:
Thanks for the suggestion  I understand the order of how everything occurs a little better now.  I did not want to get into managing all these server side controls at this time.  So a simple question can anyone answer is as follows:

Can you use the method I described above and return to the previous View State?  This looks similar to what I want but I have multiple panels and I keep getting sent to my default panel.  It does not appear to totally make sense how to return anything from the dynamic scenario I have described and then view the correct panel without some hack.


Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ws11Author Commented:
How do you reference objects in the Item Template.  Normally I can do <#=controlname.ClientID%> in my client side javascript to do validation but it will not see it as an object.  Same with having to fill my dropdownlist.  Each row along with the buttons has a dropdownlist and I can get the code behind intellisense to see it as if it does not exists.
Ah, yes... there is a little quirk about that.

Basicly you use DirectCast and the "FindControl" method of the RepeaterItemEventArgs to find the control within the repeater and assign it to a local variable of the same type.  From there you can do whatever you want with it.

I'm more familiar with VB.NET so I'll show you an example using that.  It should be easy enough for you to translate to C#.

e.g. If I had a List of cars and bound the list to the repeater :

Dim Cars as New List(of Car)
    Repeater1_DataSource = Cars

Protected Sub Repeater1_onItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles Repeater_Discounts.ItemDataBound
    Dim CurrentCar as Car = Nothing
    Select Case e.Item.ItemType
        Case ListItemType.Item, ListItemType.AlternatingItem
            ' Retrieve the Collection that was bound to the Repeater
            CurrentCar = DirectCast(e.Item.DataItem, Car)

            ' Populate the fields
            With DirectCast(e.Item.FindControl("txtMake"), Literal)
                .Text = HTMLEncode(Car.Make)
            End With

            With DirectCast(e.Item.FindControl("txtModel"), Literal)
                .Text = HTMLEncode(Car.Model)
            End With

            ' Configure the modify button
            With DirectCast(e.Item.FindControl("btModify"), Button)
                ' Configure the button with info to be used in Repeater1_ItemCommand sub
                .CommandName = "Modify"
                .CommandArgument = Car.ID
            End With

    End Select
End Sub

Open in new window

ws11Author Commented:
I have a dropdownlist name ddlName.  It does not show as an object in code behind when I type the ID.  How do I reference it.

Dim ddlName as DropDownList = DirectCast(e.Item.FindControl("ddlName"), DropDownList)

' Then..

It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.