问题描述:
在aspx页面动态生成一个控件,比如点击按钮a生成按钮b,然后再点击按钮b的时候,无论如何也进不到按钮b的Click事件里。
网上的答案基本不对,要么就是演示得特复杂难看懂,现在我写一个最简单的例子
首先在aspx页面随便一处加一行,控件类型不限,ID也随便起
<asp:HiddenField ID="HiddenFieldMark" runat="server" />
然后在aButton的click事件多加一句话,
protected void aButton_Click(object sender, EventArgs e)
{
HiddenFieldMark.Value = "aButton"; //做个标记表示点击了aButton
//Button bButton = new Button(); //这里加的按钮只能看不能点,所以不需要
//bButton.Click += new EventHandler(bButton_Click); //这句写了也没用,原理后面讲
//静态控件.Controls.Add(bButton);
}
最后写一个方法,或者写在Page_Load方法里应该也可以
protected void Page_Init(object sender, EventArgs e)
{
string eventString = Request.Form[HiddenFieldMark.UniqueID]; //获取刚才用来传标记的HiddenFieldMark
if (!string.IsNullOrEmpty(eventString)) //判断null或空字符
{
if (eventString.Contains("aButton")) //用.equals()也可以
{ //动态生成控件
Button bButton = new Button();
bButton.Click += new EventHandler(bButton_Click);
静态控件.Controls.Add(bButton);
}
if (eventString.Contains("xxButton")) //如果还有其他静态控件做触发器也加上来
{
。。。
}
}
}
再运行看看?妥妥的。生成控件的代码很多的话,可以另外放在一个方法里面拿来调用比较好。
为什么会这样?这跟页面控件创建过程有关,虽然动态生成的控件能马上看到,但并没有在ASP.net框架里面注册,也就没有被自动处理成后台能够使用的变量。既然没有获得对控件实例的引用,当然就无法对其操作了。
下面再来分步说明发生了什么事情:
1 点击aButton生成bButton,注册发生在aButton_Click之前,所以bButton是未注册的
2 点击bButton,其实并不是想象的那样马上触发bButton_Click事件,而是先刷新页面,进入了Page_Init方法
3 Page_Init的执行在注册之前,所以在Page_Init里生成的bButton将被注册。同理如果Page_Load在注册之前,那么代码也可以写在Page_Load里面,有兴趣可以自己试下
4 系统遍历页面为所有控件注册
5 点击bButton其实只刷新了页面,实际抛出Click事件的已经是新的bButton实例,于是顺利进入bButton_Click方法
网上常见误解:
1 静态控件.Controls.Add(bButton)要写在bButton.xx()方法之前
顺序并不重要,关键是看控件生成发生在注册前还是注册后?
2 生成控件的方法加一个"0"参数
参数是为了识别谁发出了click事件,只需要加在HiddenFieldMark即可,不需要加在AddButton("0")
更多问题欢迎QQ交流,176457718