问题描述
做了个动态模板列测试,页面放一个gridView,后台代码Pageload中给gridView的Columns属性添加一个TemplateField列和一个BoundField列。BoundField列来展示数据,HeaderText="设备编码"DataField="Equip_Code1"。TemplateField列里的HeaderTemplate和Itemplate都是含有Checkbox控件的模板。代码如下:问题是:HeaderTemplate的CheckBox的AutoPostBack属性是true,同时注册了CheckedChanged事件(完成全选效果),但是点击列头的CheckBox时,第一次触发事件,第二不触发事件,第三次触发事件,第四次不触发。。。可将代码复制到vs中,然后在CheckedChanged事件方法中添加断点,然后执行可看到隔一次一触发的现象。为什么是这种现象?逐步调试时发现,触发与不触发的差别就是gdvTest.DataBind()走完后是否走CheckedChanged事件方法。搞不懂了,谢谢大家帮帮看看吧,谢谢啦。页面:<%@PageLanguage="C#"AutoEventWireup="true"CodeFile="DynaiColSmartGridView.aspx.cs"Inherits="DynaiColSmartGridView"%><!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><htmlxmlns="http://www.w3.org/1999/xhtml"><headrunat="server"><title>动态模板测试</title></head><body><formid="form1"runat="server"><div><asp:Buttonrunat="server"ID="btnTest"Text="postback"/><asp:GridViewID="gdvTest"runat="server"AutoGenerateColumns="false"Width="100%"></asp:GridView></div></form></body></html>后台代码:usingSystem;usingSystem.Data;usingSystem.Configuration;usingSystem.Collections;usingSystem.Web;usingSystem.Web.Security;usingSystem.Web.UI;usingSystem.Web.UI.WebControls;usingSystem.Web.UI.WebControls.WebParts;usingSystem.Web.UI.HtmlControls;publicpartialclassDynaiColSmartGridView:System.Web.UI.Page{//行模板列privateclassmyRowTemplate:ITemplate{publicvoidInstantiateIn(Controlcontainer){CheckBoxck=newCheckBox();ck.ID="chbSelect";container.Controls.Add(ck);}}//头模板列privateclassmyHeadTemplate:ITemplate{publicvoidInstantiateIn(Controlcontainer){CheckBoxck=newCheckBox();ck.ID="chbSelectFlag";ck.AutoPostBack=true;ck.CheckedChanged+=newEventHandler(chbSelectFlag_CheckedChanged);container.Controls.Add(ck);}///<summary>///全选事件///</summary>///<paramname="sender"></param>///<paramname="e"></param>protectedvoidchbSelectFlag_CheckedChanged(objectsender,EventArgse){CheckBoxchb=(CheckBox)sender;GridViewcontainer=(GridView)((GridViewRow)chb.NamingContainer).NamingContainer;for(inti=0;i<container.Rows.Count;i++){CheckBoxchbSelect=(CheckBox)(container.Rows[i].Cells[0].FindControl("chbSelect"));chbSelect.Checked=chb.Checked;}}}protectedvoidPage_Load(objectsender,EventArgse){#region测试数据DataTabledt=newDataTable();dt.Columns.Add("Equip_Code1");dt.Rows.Add(newstring[]{"0000-00001"});dt.Rows.Add(newstring[]{"0000-00002"});dt.Rows.Add(newstring[]{"0000-00003"});dt.Rows.Add(newstring[]{"0000-00004"});dt.Rows.Add(newstring[]{"0000-00005"});#endregion#region测试templateFieldTemplateFieldtf=newTemplateField();tf.HeaderTemplate=newmyHeadTemplate();tf.ItemTemplate=newmyRowTemplate();tf.ItemStyle.Width=Unit.Pixel(20);#endregion#region测试BoundFieldBoundFieldbf=newBoundField();bf.DataField="Equip_Code1";bf.HeaderText="设备编码";#endregion#regionGridViewgdvTest.Columns.Clear();gdvTest.Columns.Add(tf);gdvTest.Columns.Add(bf);gdvTest.DataSource=dt;gdvTest.DataBind();#endregion}}
解决方案
解决方案二:
发出来一看还挺长的,其实代码很简单的,页面就一个空的gridview,代码就是加两个列。只要粘贴到vs里就可以试了。大家要是没事儿,帮忙试下。多谢了,我实在想不通了。
解决方案三:
CheckedChanged事件挺好玩,难道只是每次选中了才触发?换成click或者别的事件是不是好点?
解决方案四:
是因为你Page_Load中没加IsPostBack导致你没做checed都会重新绑定grid,事件也重新绑定//绑定的时候checkbox默认是没选中的所以你取消全选的时候就没触发事件状态没改变//但Page_Load中加IsPostBack就会将模版内容清空,你可以将控件机会保存到session中或viewstate
解决方案五:
引用2楼的回复:
CheckedChanged事件挺好玩,难道只是每次选中了才触发?换成click或者别的事件是不是好点?
好像,没有click事件吧。
解决方案六:
引用3楼的回复:
//取消全选效果没有:是因为你Page_Load中没加IsPostBack导致你没做checed都会重新绑定grid,事件也重新绑定//绑定的时候checkbox默认是没选中的所以你取消全选的时候就没触发事件状态没改变//但Page_Load中加IsPostBack就会将模版内容清空,你可以将控件机会保存到session中或viewstat……
如果不是动态模板,page_load中加上if(!IsPostBack){...}好用,不加就不好用,而且是一次都不会走CheckedChanged事件方法,好像是因为,重新绑定grid把事件也重新绑定了。但是如果是动态模板,page_load中不加if(!IsPostBack){...},为什么第一次可以触发CheckedChanged事件方法。按上边的道理,也是先重新绑定的,而且是先把列都清空,再绑定列,再绑定行的。也应该一次都触发不到啊?(另外,如果初始化是选中的状态。//行模板列privateclassmyRowTemplate:ITemplate{publicvoidInstantiateIn(Controlcontainer){CheckBoxck=newCheckBox();ck.ID="chbSelect";ck.Checked=true;//加上这句,默认勾选。container.Controls.Add(ck);}}绑定的时候,如果设置CheckBox的checked=true,那么结果变为全选无效,取消有效,总之就是第一次触发了CheckedChanged事件,第二次不触发。)
解决方案七:
引用3楼的回复:
//取消全选效果没有:是因为你Page_Load中没加IsPostBack导致你没做checed都会重新绑定grid,事件也重新绑定//绑定的时候checkbox默认是没选中的所以你取消全选的时候就没触发事件状态没改变//但Page_Load中加IsPostBack就会将模版内容清空,你可以将控件机会保存到session中或viewstat……
//但Page_Load中加IsPostBack就会将模版内容清空,你可以将控件机会保存到session中或viewstat……动态模板page_load中加if(!IsPostBack){...},回调后模板内容会清空,如果把控件存入ViewState中,会说GridView不能序列化什么的,大概就是说ViewState只能保存可以序列化得对象。放到Session里,我是这么放的,但是模板内容还是清空了。if(!IsPostBack){...//不变,把原来的代码放进去。Session["gdv"]=gdvTest;//加上这句,把绑好的gridview存入session}else{//下次回调的时候在把gridview赋值gdvTest=(GridView)Session["gdv"];}但是这样做,效果还是和只加入if(!IsPostBack){...}中一样,回调后模板内容就清空了。谢谢hanqing_liu,提供的解决思路,是不是存的不对啊,希望再给点提示~谢谢喽~:)