【问题标题】:How do I attach an event handler to an ASP.NET control created at runtime?如何将事件处理程序附加到在运行时创建的 ASP.NET 控件?
【发布时间】:2010-11-10 15:07:31
【问题描述】:

大家早上好。

我有一个与控件和事件处理有关的问题。假设我想创建一个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!";
}

如果我在Page_Load 中运行loadLinkButton 函数,一切正常。但是当我尝试通过单击简单按钮运行loadLinkButton 时,会创建链接按钮但未处理事件。

protected void Button1_Click(object sender, EventArgs e)
{
    loadLinkButton();
}

我有什么办法解决吗?或者 loadLinkBut​​ton 必须始终在 Page_LoadPage_init 等上重新生成。

【问题讨论】:

  • 这段代码绝对没有动态。我有点失望,回答这个问题的人鼓励使用这个术语。
  • @Aaronaught - 你会怎么称呼它?以编程方式添加控件长期以来一直被称为动态添加控件。您访问的几乎所有论坛、用户组或博客都会使用相同的术语...
  • @Josh:早就错误地这么称呼它了,是的。我不讨厌 OP 感到困惑,但高声誉的回答者不应该重复这个词。 “动态”这个词只有在与 static(即动态链接库,dynamic typing)或引用ASP.NET Dynamic Data 对比时才有意义。这个问题是指在 design timeruntime 创建的控件之间的区别,正如我在编辑中指出的那样。
  • @Aaronaught - 我理解这个论点的学术方面,但是关于运行时完成的事情,许多不同语言和平台的从业者已经采用了一个通用的命名法。当你说“动态添加”“动态控件”时,每100个人中就有99人会明白你的意思。真的不重要了。就像有人说“酷!”一样。他们通常不谈论温度。
  • @Josh:我完全理解英语本身并不是学术规定的正式语言,但计算机语言和框架实际上由规范正式定义的,一个词确实不正确,因为很多人滥用它(例如Agile)。在 this 情况下保持正确尤为重要,因为“动态”这个词在 C# 中已经意味着不同,而这正是 [dynamic] 标记应该用于的用途.

标签: c# asp.net controls


【解决方案1】:

使用动态控件时,我总是将控件添加到 Page_Init 中,因为视图状态加载将在 Init 之后立即发生。如果将其添加到 Page_Load,则有可能会丢失视图状态。只需确保提供唯一的控件 ID。

【讨论】:

  • Page_Load 通常来不及添加控件并让它们响应回发事件; Page_Init 是更好的地方,您需要在每次回发时重新创建控件。在Button1_Click 中创建控件几乎肯定会让人头疼。
【解决方案2】:

了解 ASP.Net 如何确定调用哪些事件非常重要。每个事件的来源都使用隐藏字段传递:

<input type="hidden" name="__EVENTTARGET" value="" />

每当页面加载时,它都会从该字段中提取事件源,然后确定要调用哪个事件。现在这一切都非常适合通过标记添加的控件,因为每次请求都会重新生成整个控件树。

但是,您的控件只添加了一次。发生回发时,您的控件不再作为服务器控件存在于树中,因此该事件永远不会触发。

避免这种情况的简单方法是确保每次加载页面时都添加动态控件,通过Page_Init 事件或Page_Load 事件。

【讨论】:

    【解决方案3】:

    你是对的。这是预期的行为。 Page_Load 和 Page_Init 将是您应该添加它的事件。

    【讨论】:

      【解决方案4】:

      那是因为当您单击动态生成的链接按钮时,您会回发到服务器。在那里你做了一个全新的页面加载,但你原来的按钮点击(生成链接)现在从未发生过,所以链接按钮永远不会被制作,并且事件不能被抛出。

      另一种方法是将您动态添加的链接按钮静态添加到您的页面,其中 Visible = false。当您单击另一个按钮时,使其可见。

      【讨论】:

      • 感谢解释原因
      【解决方案5】:

      我不确定您面临什么问题,但您应该按照@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!"; 
              }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-01
        • 2011-12-12
        • 1970-01-01
        • 1970-01-01
        • 2021-04-25
        相关资源
        最近更新 更多