ASP.NET中,本来RadioButton的Groupname是为了标识同一组RadioButton准备的,也就是说如果Groupname相同,那么认为是同一组单选按钮,同一时间只能选中其中一个。翻译成客户端代码的时候,会把Groupname翻译成html里面的name。
但是DataGrid或DataList模板列中,如果放置了一个RadioButton控件,其设置的Groupname是无效的。原因在于,在转换成客户端代码时,控件的name会变成DataList名:_ct行号:Groupname名。这样,每一行的RadioButton也就有了不同的name,这样html就会认为是不同组的RadioButton,也就造成了控制单选无效的结果。
解决方法有几种,一种是RadioButton的AutoPost设为true,这样每次点击单选按钮就会回传,然后在触发的代码里把其他按钮的选择清空。但是这样频繁回传,不是一个好办法。有篇文章也写到了一种javascript控制的方法,原理是差不多,实现办法看似比较笨,但很管用。也就是在每一行的RadioButton的onclick事件里,将其他行的RadioButton选择一行行清空。打个比方,假如只有一个顾客吃饭,他从其他桌改坐二号桌,那么就去检查清理下其他桌上有没遗漏什么东西,清理一号桌,清理三号桌,清理四号桌……
{
RadioButton rb=(RadioButton)DataListABC.Items[i].FindControl("RadioButtonABC");
sTemp="";
for(int j=0;j<DataListABC.Items.Count;j++)
{
if(j!=i)
{
RadioButton rb2=(RadioButton)DataListABC.Items[j].FindControl("RadioButtonABC");
sTemp=sTemp+"uncheck('"+rb2.ClientID+"');";
}
}
if(sTemp!="")
{
rb.Attributes.Add("onclick",sTemp);
}
}
二、javascript脚本解决方法
javascript代码:
<script language="javascript" type="text/javascript">
function clickit() {
var dom=document.all;
var el=event.srcElement;
if(el.tagName=="INPUT"&&el.type.toLowerCase()=="radio")
{
for(i=0;i<dom.length;i++)
{
if(dom[i].tagName=="INPUT"&&dom[i].type.toLowerCase()=="radio")
{
dom[i].checked=false;
}
}
}
el.checked=true;
}
</script>
单选按钮的代码如:
<asp:RadioButton ID="RadioButton1" runat="server" οnclick="clickit();"
Text='<%# DataBinder.Eval(Container.DataItem, "CARD_NBR")%>' />
其他见解:
实看似“正统”的思路未必是精准的,编程最好务求精准而不仅仅是正统。FindControl几乎不去使用才更能够又快有准地找到控件——控件它自己来触发事件而不是我们去找它。在GridView的模板中,我们可能放入任何东西,说不定哪一天你把CheckBox放入一个复杂的控件中(例如MultiView之类的)。FindControl让人觉得又慢又不适合很好地对设计进行维护。应该让CheckBox“主动通知我们”而不是我们去寻找它,这就是 MVP 编程的意义。只是要加上一点:CheckBox可以自身同时带着它的标识信息。
这样,界面设计可以是这样的:
-
HTML code
-
< asp:TemplateField HeaderText ="abc" SortExpression ="ytf" > < ItemTemplate > < asp:CheckBox ID ="chk" runat ="server" 哈哈 ='<%# Eval("key_field") % > ' OnCheckedChanged="chk_CheckedChanged" /> </ ItemTemplate > </ asp:TemplateField >
设计时可以为服务器控件随意增加任何新的属性,它会写入控件的Attributes集合中,并且当你变成修改它时控件会自动在回发之间维护这个状态值。我这里就随便起了一个名字为“哈哈”的属性,当GridView被绑定时它的值使用Eval绑定为数据库中的一个标识值(通常是记录主键值)。
-
C# code
-
System.Collections.Generic.List < string > chks = new System.Collections.Generic.List < string > (); protected void chk_CheckedChanged( object sender, EventArgs e) { CheckBox chk = (CheckBox)sender; chks.Add(chk.Attributes[ " 哈哈 " ]); }
每一个CheckBox在事件中都将自己的“哈哈”这个属性的值保存入chks。如果在界面上更改10个CheckBox,那么chk_CheckedChanged方法就会执行10次。然后就可以在你的Button的click事件处理程序中直接遍历chks集合。
所有的关于属性更改的事件都是在回发事件之前触发的,因此会先调用所有的 chk_CheckedChanged 方法,之后才调用 Button1_Click 方法。