IDE:Visual Studio 2010
.net版本:3.5
操作系统:Windows 7
Web服务器:Visual Studio 2010开发服务器
下面是一些asp.net C#代码。这是一个空白的,开箱即用的Web表单背后的代码。我不明白为什么单击按钮时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");
}
}
答案 0 :(得分:4)
因为只有在请求不是回发时才会执行该代码,因此不会创建控件并且不会附加事件处理程序。将控件(和事件处理程序)放在标记中,或者在每个请求上添加/附加它,而不仅仅是非后退。
控件及其事件不会在请求中持续存在 - 它们可以从标记或后面的代码中创建。当您进行回发后,该控件在页面上不存在,因此无法触发事件。
答案 1 :(得分:3)
通过动态连接Page_Load
中的事件处理程序,只有在IsPostBack
为false时才会订阅事件处理程序,即在第一次呈现页面时,在回发之前(例如之前)点击Buttons
等。
与按钮上的其他控件属性(如.Text
,.Color
等)不同,事件处理程序不能在ViewState
之间进行序列化,因此无论是否PostBack都必须连接。< / p>
对于设计时控件,最好将事件处理程序连接到实际的.ASPX
按钮控件定义中。
但是,由于您已动态创建Button
,因此您无其他选择,只能每次都连接处理程序。