views:

1056

answers:

5

I am loading a LinkButton dynamically when a user clicks on another LinkButton. I am attaching an event handler to it. When the user clicks on the dynamically loaded LinkButton, the event does not fire.

From what I've been reading, I understand this is because when the page posts back the dynamically loaded control no longer exists. It looks like I'm supposed to make sure this control is recreated in Page_Init.

The dynamically created LinkButton is dependedent on a value (Product ID). I need someway to access this value so I can properly create the control. ViewState is not accessible and I'm concerned if I use Session it could time out and then that wouldn't help. Any ideas?

Also, I hardcoded a Product ID value just for testing, and that still did not cause the event to fire. Is there something else I need to do?

protected void Page_Init(object sender, EventArgs e)
{
   SetTabText(1, 1);
}

SetTabText calls SetActionLinks which creates the LinkButton:

protected Panel SetActionLinks(int prodID, int tabID) {
...
LinkButton lnkBtn = new LinkButton();
lnkBtn.ID = "lnkBtn" + rand.Next().ToString();
lnkBtn.CommandName = "action";
lnkBtn.Command += new CommandEventHandler(this.lnkAction_Command);
panel.Controls.Add(lnkBtn);
...
}
void lnkAction_Command(object sender, CommandEventArgs e)
{
   LinkButton btn = (LinkButton)sender;
   switch (btn.CommandArgument)
   {
      AddCart();
   }
}
A: 

Look at anonymous delegates

LinkButton lb = new LinkButton();
lb.Command += delegate { // do something here. also you can access any variable from current stack };
abatishchev
I changed my events to anonymous delegates, but it doesn't seem to have changed anything...
+2  A: 

In your scenario I tried your code, the line below causes your event firing fault :

lnkBtn.ID = "lnkBtn" + rand.Next().ToString();

try to set an id that not changes between postbacks.

For ViewState, You can move your code to Page_Load. Your code works same, but you can access ViewState and your Control's posted values

Canavar
So the ID must remain the same I see. I changed it to have the naming consistent, but that did work.
+2  A: 

You can put your Product ID in a hidden field and get its value in Page_Init using

Page.Request(Page.FindControl("hdnPageIdField"))

This way you don't need to rely on ViewState or SessionState

Also for dynamic controls I highly suggest you read this greate arcticle series

Ender
+1 Great reading Ender, thanks for that Link, it is what I was looking for...
James Campbell
A: 

Have you AutoEventWireup="true" in your .aspx file?

abatishchev
+1  A: 

I spent a sleepless night figuring out something like this a few months ago. That was when I fully grokked the fact that ASP.NET is built on a stateless foundation and it maintains state by ping-ponging viewstate back and forth between the client and the server.

If you are dynamically adding and deleting controls or modifying existing controls in response to a dynamically created control's event firing, then the parent element's PageInit needs to recreate the child controls in the state that they existed at the time the event fired (before the event's actions are applied). It may seem redundant, but it's necessary in order to ensure that the receiver exists and it's handler can be invoked when server wants to fire the event. Then the control's event handler will be able apply the changes (and add or remove controls, assign different ID's etc.)

I found this page on the ASP.NET event lifecycle (http://msdn.microsoft.com/en-us/library/ms178472.aspx) helpful.

Jeff Leonard