大家早上好。
我有一个与控件和事件处理相关的问题。假设我想创建一个LinkButton
。
protected void loadLinkButton()
{
ContentPlaceHolder content = (ContentPlaceHolder)this.Master.FindControl("MainContent");
LinkButton lnk = new LinkButton();
lnk.ID = "lnikBtn";
lnk.Text = "LinkButton";
lnk.Click += new System.EventHandler(lnk_Click);
content.Controls.Add(lnk);
}
这是事件处理程序:
protected void lnk_Click(object sender, EventArgs e)
{
Label1.Text = "ok!";
}
如果我在loadLinkButton
内运行Page_Load
函数,一切正常。但是当我尝试通过单击简单按钮运行loadLinkButton
时,会创建链接按钮但不处理事件。
protected void Button1_Click(object sender, EventArgs e)
{
loadLinkButton();
}
我有什么方法可以解决它吗?或者必须始终在Page_Load
,Page_init
等上重新生成loadLinkButton。
答案 0 :(得分:3)
了解ASP.Net如何确定要调用的事件非常重要。使用隐藏字段传递每个事件的来源:
<input type="hidden" name="__EVENTTARGET" value="" />
每当页面加载时,它会从该字段中提取事件源,然后确定要调用的事件。现在这一切都适用于通过标记添加的控件,因为整个控制树都会在每次请求时重新生成。
但是,您的控件只添加了一次。发生回发时,您的控件不再作为树中的服务器控件存在,因此事件永远不会触发。
避免这种情况的简单方法是通过Page_Init
事件或Page_Load
事件确保每次页面加载时都会添加动态控件。
答案 1 :(得分:3)
使用动态控件时,我总是在 Page_Init 中添加控件,因为viewstate加载将在Init之后立即发生。如果将其添加到Page_Load,则可能会丢失viewstate。只需确保您提供唯一的控件ID。
答案 2 :(得分:0)
你是对的。这是预期的行为。 Page_Load和Page_Init将是您应该添加它的事件。
答案 3 :(得分:0)
那是因为当您单击动态生成的链接按钮时,您会回发到服务器。在那里你做了一个全新的页面加载,但你原来的buttonclick(生成链接)现在从未发生过,所以链接按钮永远不会发生,并且不能抛出事件。
另一种方法是使用Visible = false将动态添加的链接按钮静态添加到页面中。当您单击其他按钮时,将其显示。
答案 4 :(得分:-1)
我不确定你遇到了什么问题,但你应该按照@johnofcross的建议将动态控制代码放在Page_Init中:
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Page_Init(object sender, EventArgs e)
{
CreateControls();
}
private void CreateControls()
{
var lb = new LinkButton();
lb.Text = "Click Me";
lb.Click += lb_Click;
ph.Controls.Add(lb);
ph.DataBind();
}
void lb_Click(object sender, EventArgs e)
{
lblMessage.Text = "Button is clicked!";
}
}