为什么在下面的asp.net代码中EventHandler没有触发?

本文关键字:EventHandler 在下面 asp net 代码 为什么 | 更新日期: 2023-09-27 17:52:50

IDE: Visual Studio 2010

.net版本:3.5

操作系统:Windows 7

Web Server: Visual Studio 2010 Development Server

下面是一些asp.net c#代码。这是一个空白的,开箱即用的网页表单后面的代码。我不明白的是为什么当我单击按钮时testClick事件不会触发,但是如果我注释掉下面的行,以便在回发时呈现按钮,那么会触发

if (!IsPostBack)

显然这与页面生命周期和如何/何时渲染控件有关,但我不明白。当页面返回时,btnTest按钮不是btnTest的新实例吗?为什么页面关心回发后它是否实际存在?事件处理程序已存在。这似乎才是最重要的事情。我希望有人能打破事情发生的顺序,并向我解释这种(显然是正确的和故意的)行为。

感谢您的阅读。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class _Default : System.Web.UI.Page 
{
    Button btnTest = new Button();
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            btnTest.Text = "TEST";
            this.Form.Controls.Add(btnTest);
            btnTest.Click += new EventHandler(testClick);
        }
    }
    protected void testClick(Object sender, EventArgs e)
    {
        Response.Write("Test button event has been handled");
    }
}

好吧,现在我完全糊涂了!在下面的代码中,btnTest和btnTest2不是同一个按钮。当页面返回时,它触发btnTest2的事件处理程序,就好像btnTest2被点击了,但btnTest2没有被点击。btnTest。我不理解这种行为。我已经按照建议在https://msdn.microsoft.com/en-us/library/ms178472(v=vs.80).aspx上阅读了页面生命周期的文章,但我认为它没有充分解释这种行为。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class _Default : System.Web.UI.Page 
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            Button btnTest = new Button();
            btnTest.Text = "TEST";
            this.Form.Controls.Add(btnTest);
            btnTest.Click += new EventHandler(testClick);
        }       
        if (IsPostBack)
        {
            Button btnTest2 = new Button();
            btnTest2.Text = "TEST";
            this.Form.Controls.Add(btnTest2);
            btnTest2.Click += new EventHandler(testClick_Postback);
        }        
    }
    protected void testClick(Object sender, EventArgs e)
    {
        Response.Write("Test button event has been handled by original handler");
    }
    protected void testClick_Postback(Object sender, EventArgs e)
    {
        Response.Write("Test button event was handled by new handler assigned on postback");
    }
}

为什么在下面的asp.net代码中EventHandler没有触发?

因为该代码仅在请求不是回发时执行,所以没有创建控件,也没有附加事件处理程序。要么将控件(和事件处理程序)放在标记中,要么将其添加/附加到每个请求上,而不仅仅是非回发。

控件及其事件不会在请求之间持久存在——它们要么是从标记中创建的,要么是在后面的代码中创建的。当您执行回发时,控件在页面上不存在,因此没有要触发的事件。

通过动态连接Page_Load中的事件处理程序,事件处理程序将仅在IsPostBack为false时才会被订阅,即在页面第一次呈现时,在回发之前(例如在单击Buttons等之前)。

与按钮上的其他控件属性(如.Text, .Color等)不同,事件处理程序不可跨ViewState序列化,因此必须连接起来,无论是否PostBack。

对于设计时控件,最好将事件处理程序保留在实际的.ASPX按钮控件定义中。

但是,由于您已经动态地创建了Button,因此除了每次连接处理程序之外,您别无选择。