C# 为什么在下面的asp.net代码中不触发EventHandler?
IDE:VisualStudio2010 .net版本:3.5 操作系统:Windows7 Web服务器:Visual Studio 2010开发服务器 下面是一些asp.net C#代码。这是一个空白的、开箱即用的web表单上的代码。我不明白的是,当我单击按钮时,为什么testClick事件不会触发,但是如果我注释掉下面的行,以便在回发时呈现按钮,它就会触发 显然,这与页面生命周期以及控件的呈现方式/时间有关,但我不明白。当页面发回时,btnTest按钮不是btnTest的新实例吗?为什么页面关心回发后它是否真的存在?事件处理程序已存在。看来这应该是最重要的事情。我希望有人能打破事情发生的顺序,向我解释这种行为(显然是正确的和故意的) 谢谢你的阅读C# 为什么在下面的asp.net代码中不触发EventHandler?,c#,asp.net,C#,Asp.net,IDE:VisualStudio2010 .net版本:3.5 操作系统:Windows7 Web服务器:Visual Studio 2010开发服务器 下面是一些asp.net C#代码。这是一个空白的、开箱即用的web表单上的代码。我不明白的是,当我单击按钮时,为什么testClick事件不会触发,但是如果我注释掉下面的行,以便在回发时呈现按钮,它就会触发 显然,这与页面生命周期以及控件的呈现方式/时间有关,但我不明白。当页面发回时,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一样。测试结果是。我不理解这种行为。我已经按照建议阅读了关于页面生命周期的文章,但我认为它不能充分解释这种行为
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");
}
}
因为只有当请求不是回发时才会执行该代码,所以不会创建控件,也不会附加事件处理程序。要么将控件(和事件处理程序)放入标记中,要么在每个请求上添加/附加它,而不仅仅是非回发
控件及其事件不会在请求之间持久化—它们要么是从标记中创建的,要么是在代码隐藏中创建的。执行回发时,该控件不在页面上,因此没有要触发的事件。通过在
页面加载中动态连接事件处理程序,只有当IsPostBack
为false时,即在回发之前第一次呈现页面时,才会订阅事件处理程序(例如,在单击按钮之前)
与按钮上的其他控件属性(如.Text
,.Color
等)不同,事件处理程序不能跨视图状态
序列化,因此无论是否回发,都必须连接
对于设计时控件,最好在实际的.ASPX
按钮控件定义中保留事件处理程序连接
但是,由于您已经动态创建了按钮
,因此您没有其他选择,只能每次连接处理程序。您单击按钮,会发生回发,然后它会查看单击事件,但没有。因此处理程序不会启动。谢谢。这是我正在编写的类的一个非常精简的SSCE,我正在编写这个类试图创建一个与C#MessageBox相当的asp.net,它包装一个面板控件并显示一条可配置的消息,然后在按下OK按钮时触发一个事件。我对它进行了编码,使其填充了u eventTarget和u eventArgument,并处理了点击页面加载,但我希望对其进行配置以使其消失在回发时ear并启动一个可配置的委托,而不必重新呈现面板控件。我开始认为我的第一个解决方案可能是可行的。令人困惑的是,似乎在回发时应在viewstate中传递EventHandler委托。例如“嘿,这个处理程序已经按下了一个按钮,所以当你发回时会触发它。”不管这个按钮是否实际呈现。当页面发回时,这里的动态按钮不是按钮对象的一个全新实例吗?它不是在垃圾收集中丢弃了旧按钮吗?
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");
}
}