使CheckBoxList的Attributes属性生效 修改微软的一个bug
• 经验
使CheckBoxList的Attributes属性生效(修改微软的一个bug)本文将描述如何使CheckBoxList中的项目添加的属性在客户端有效。CheckBoxList是一个非常有用的组件,它支持数据绑定和其他功能。但是他有和DropDownList一样的问题,就是当我们给他们的项目添加项目的时候,如果我们要给这些项目添加客户端行为,这些行为是无法在客户端体现出来的。我们通常使用以下方法:HTML页面部分如下所示:ASP:CheckBoxListid= checkboxlist 1 runat= server ASP:ListItem value= 1 1/ASP:ListItemASP:ListItem value= 2 2/ASP:ListItemASP:ListItem value= 3 3/ASP:ListItem/asp:复选框列表我们在Page_Load中添加了以下代码:foreach(ListItemiteminthis。复选框列表1 .项目){项目。Attributes.Add(onclick , alert( item。文本 ));}这样做的目的是:当我们点击复选框时,我们希望警告会显示我们选中的复选框的内容,当然还有其他更有用的应用。但实际上这段代码并不能正常工作。我们看不到客户端点击复选框时的提示信息,无论你给Attributs加什么都不会有响应。其他列表控件也存在同样的问题,比如DropDownList。以下是该页面上显示的客户端脚本:tableid= checkboxlist 1 border= 0 trtdinputid= checkbox list 1 _ 0 type= checkbox name= checkbox list 1:0 /label for= checkbox list 1 _ 0 1/label/TD/trtrtdinputid=复选框列表1_1type=复选框 name=复选框列表1:1/labelfor=复选框列表1_12/label/td/trtrtdinputid= checkboxlist 1 _ 2 type= checkbox name= checkboxlist 1:2 /label for= checkboxlist 1 _ 2 3/label/TD/tr/表格可以看到,这里并没有出现我们预期的onclick事件。下面,我会提供一个完善这个控件的方法。既然完美,那我就保留这个控件原有的所有特性,修复上面的bug(我觉得应该是bug)。可能已经有人想到用什么方法了。是的,我将通过继承重用该控件。用我们的新控件做些事情,使它更容易使用。我将这个控件命名为NewCheckBoxList。首先,我们从客户端代码的分析开始。我们发现写在服务器端的代码在客户端什么都不显示,那怎么显示呢?在这里,我将重写这个组件的Render方法来实现最终的目标。这是我的想法。首先,我将把应该从Render输出到页面的流输出到一个StringBuilder,这样我就可以编辑这个StringBuilder来完成剩下的工作。在获得这个StringBuilder之后,我们会根据我们想要的逻辑向这个字符串添加内容,然后在添加内容之后将这个字符串写入控件的输出流中。下面是该控件的实现代码:使用系统;使用系统;使用系统。Web . UI使用系统。Web . UI.WebControls使用系统。组件模型;使用系统。文本;命名空间Cuike519。Web.UI.WebControls{命名空间Cuike519。Web.UI.WebControls{///摘要///SummarydescriptionforNewCheckBoxList。////摘要[DefaultProperty(Text )。toolbox data( { 0 }:NewCheckBoxListrunat=server/{ 0 }:NewCheckBoxList )]public classnewcheckboxlist:System。web . ui . web controls . checkboxlist {protectedoverridevoiddrender(HtmlTextWriterwriter){protectedoverridevoiddrender(HtmlTextWriterwriter){StringBuildersb=new string builder();系统。IO.TextWritertw=newSystem。IO . string writer(sb);HtmlTextWriterOriginalStream=newHtmlTextWriter(tw);基地。render(original stream);字符串=sb。ToString();int start=0;意图=s .长度;for(inti=0;这是。项目。计数;i ){start=s.IndexOf(input ,start,end-start);stringbuilders sbitemattribute=newstring builder();这个。items[I]. attributes . render(newHtmlTextWriter(new system。IO . string writer(sbItemAttribute)));s=s.Insert(start 7,sbItemAttribute。ToString()“”);start=s.IndexOf(/,start,s . Length-start);end=sbItemAttribute。长度1;}作家。写;}}}代码描述如下:我将构造一个StringBuilder来保存这个控件呈现的内容(这个内容不完整,需要修改)。我们将使用base。Render将原流写入sb,然后获取它的字符串,然后我们会在整个字符串中的指定位置寻找对应的输入。这里的算法要优化一下,有兴趣的用户可以试试。我会找到上一次输入末尾的/作为下一次搜索的开始。找到字符串后,我将使用item的Render方法。属性将我们在叶子上添加的内容输出到一个新的StringBuilder(过程与前面的类似),然后我们将把这个输出写到原始流字符的适当位置。在此控件被修改之前,以下是测试结果:我们将以下指令添加到使用该控件的页面中:% @ register tag prefix= CK namespace= Cui ke 519。web . ui . web controls assembly= Test %指出一些必要的参数,这里的测试是我的测试项目生成的程序集。该页面的控制部分如下:CK:NewCheckBoxListid= newcheckboxlist 1 runat= server ASP:ListItem value= a a/ASP:ListItemASP:ListItem value= b b/ASP:ListItemASP:ListItem value= c c/ASP:ListItem/ck:NewCheckBoxList我们在页面的加载中编写上面相同的代码:foreach(ListItemiteminthis。NewCheckBoxList1.Items){项目。Attributes.Add(onclick , alert( item。文本 ));}相同的代码只是替换了控件。我们来看看运行效果。下面是生成的客户端脚本:tableid= newcheckboxlist 1 border= 0 trtdinputonclick= alert( a ) id= new checkboxlist 1 _ 0 type= checkbox name= new checkboxlist 1:0 /label for= new checkboxlist 1 _ 0 a/label/TD/trtrtdinputonclick= alert( b ) id= new checkboxlist 1 _ 1 type= checkbox name= new checkboxlist 1:1 /label for= new checkboxlist 1 _ 1 b/label/TD/trtrtdinputonclick= alert( c ) id= new checkboxlist 1 _ 2 type= checkbox name= new checkboxlist 1:2 /label for= new checkboxlist 1 _ 2 c/label/TD/tr/表格和上一个不一样吗?j同样的方法也适用于像DropDownList这样的组件。以下是NewDropDownList实现的部分代码,只需替换NewCheckBoxList的相应部分:for(inti=0;这是。项目。计数;i ){ start=s.IndexOf(option ,start,end-start);stringbuilders sbitemattribute=newstring builder();这个。items[I]. attributes . render(newHtmlTextWriter(new system。IO . string writer(sbItemAttribute)));s=s.Insert(start 7,sbItemAttribute。ToString()“”);start=s.IndexOf(/option ,start,s . Length-start);end=sbItemAttribute。长度1;}这篇文章的灵感来自CSDN网友的提问。