动态加载控件 - 如何访问Page_Init中的值

时间:2022-06-29 03:40:33

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.

我在用户点击另一个LinkBut​​ton时动态加载LinkBut​​ton。我正在附加一个事件处理程序。当用户单击动态加载的LinkBut​​ton时,事件不会触发。

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.

从我读过的内容来看,我理解这是因为当页面回发时,动态加载的控件不再存在。看起来我应该确保在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?

动态创建的LinkBut​​ton取决于值(产品ID)。我需要一些访问此值,以便我可以正确创建控件。 ViewState是不可访问的,我担心如果我使用Session它可能会超时然后这无济于事。有任何想法吗?

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?

此外,我硬编码产品ID值仅用于测试,但仍未导致事件触发。还有什么我需要做的吗?

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

SetTabText calls SetActionLinks which creates the LinkButton:

SetTabText调用创建LinkBut​​ton的SetActionLinks:

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();
   }
}

6 个解决方案

#1


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

您可以将产品ID放在隐藏字段中,并使用Page_Init获取其值

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

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

这样您就不需要依赖ViewState或SessionState

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

另外对于动态控件我强烈建议你阅读这个greate arcticle系列

#2


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.

尝试设置不在回发之间更改的ID。

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

对于ViewState,您可以将代码移动到Page_Load。您的代码工作原理相同,但您可以访问ViewState和Control的发布值

#3


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.

几个月前,我花了一个不眠之夜搞清楚这样的事情。那时我完全理解了ASP.NET建立在无状态基础上的事实,并且它通过在客户端和服务器之间来回ping-view of viewstate来维护状态。

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.)

如果您是动态添加和删除控件或修改现有控件以响应动态创建的控件的事件触发,那么父元素的PageInit需要在事件触发时(事件的操作之前)状态下重新创建子控件适用)。它似乎是多余的,但是为了确保接收器存在并且当服务器想要触发事件时可以调用它的处理程序是必要的。然后控件的事件处理程序将能够应用更改(并添加或删除控件,分配不同的ID等)

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

我发现ASP.NET事件生命周期(http://msdn.microsoft.com/en-us/library/ms178472.aspx)上的这个页面很有帮助。

#4


This works in Page_Init

这适用于Page_Init

HiddenField ctrl = (HiddenField)Page.FindControl("hfTest");
string strValue = Page.Request.Form.Get(ctrl.ClientID);

The HiddenField will store the controls to be loaded (Pipe Delimited) and the we can load the controls dynamically.

HiddenField将存储要加载的控件(Pipe Delimited),我们可以动态加载控件。

#5


Look at anonymous delegates

看看匿名代表

LinkButton lb = new LinkButton();
lb.Command += delegate { // do something here. also you can access any variable from current stack };

#6


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

你的.aspx文件中有AutoEventWireup =“true”吗?

#1


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

您可以将产品ID放在隐藏字段中,并使用Page_Init获取其值

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

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

这样您就不需要依赖ViewState或SessionState

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

另外对于动态控件我强烈建议你阅读这个greate arcticle系列

#2


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.

尝试设置不在回发之间更改的ID。

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

对于ViewState,您可以将代码移动到Page_Load。您的代码工作原理相同,但您可以访问ViewState和Control的发布值

#3


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.

几个月前,我花了一个不眠之夜搞清楚这样的事情。那时我完全理解了ASP.NET建立在无状态基础上的事实,并且它通过在客户端和服务器之间来回ping-view of viewstate来维护状态。

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.)

如果您是动态添加和删除控件或修改现有控件以响应动态创建的控件的事件触发,那么父元素的PageInit需要在事件触发时(事件的操作之前)状态下重新创建子控件适用)。它似乎是多余的,但是为了确保接收器存在并且当服务器想要触发事件时可以调用它的处理程序是必要的。然后控件的事件处理程序将能够应用更改(并添加或删除控件,分配不同的ID等)

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

我发现ASP.NET事件生命周期(http://msdn.microsoft.com/en-us/library/ms178472.aspx)上的这个页面很有帮助。

#4


This works in Page_Init

这适用于Page_Init

HiddenField ctrl = (HiddenField)Page.FindControl("hfTest");
string strValue = Page.Request.Form.Get(ctrl.ClientID);

The HiddenField will store the controls to be loaded (Pipe Delimited) and the we can load the controls dynamically.

HiddenField将存储要加载的控件(Pipe Delimited),我们可以动态加载控件。

#5


Look at anonymous delegates

看看匿名代表

LinkButton lb = new LinkButton();
lb.Command += delegate { // do something here. also you can access any variable from current stack };

#6


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

你的.aspx文件中有AutoEventWireup =“true”吗?