RadioButton加入DataGrid模板列引起的问题。
也许各位看官还尚未注意到,将RadioButton加入到DataGrid模板列后(当然DataList,Repeater也一样),尽管你设置了其GroupName,结果还是不能实现我们想要的效果, 即实现RadioButton之初衷:实现单选效果。
也许,你会说,用RadioButtonList即可解决,如:
而如果我们想用RadioButton实现呢?
这时候,我们就必须思考为什么
<input type="radio" name="radioDemo">可以实现单选
而
<input type="radio" name="radioDemo" id="radioDemo" runat="server">
<asp:RadioButton ID="RadioButton1" runat="server" GroupName="Demo" />
却不能实现单选呢?
如果我们查看浏览器输出的源代码,会发现
Runat="server"的RadioButton的Name变成了类似
所以,我们只有让DataGrid输出唯一的ClientID
以下为实现代码:
也许,你会说,用RadioButtonList即可解决,如:
1 <asp:datagrid id="DataGrid1" runat="server"
2 //1、我们将datagrid的第一列设置为模板列,并加入RadioButtonList
3 AutoGenerateColumns="False">
4 <Columns> <asp:TemplateColumn>
5 <ItemTemplate> <asp:RadioButtonList ID="RadioButtonList1" Runat="server"></asp:RadioButtonList>
6 </ItemTemplate>
7 </asp:TemplateColumn> <asp:BoundColumn DataField="CustomerID" HeaderText="CustomerID"></asp:BoundColumn>
8 </Columns>
9 </asp:datagrid>
10 //然后在数据绑定到DataGrid后,即DataGrid1.DataBind();代码之后,写:
11 //将第一列第一单元格的RowSpan设置为DataGrid的总列数
12 DataGrid.Items[0].Cells[0].RowSpan=DataGrid.Items.Count;
13 for (int i=1;i<DataGrid.Items.Count;++i)
14 { DataGrid.Items[i].Cells[0].Visible=false;
15 //从第二列开始隐藏第一个单元格
16 }
17 //将第一列第一个单元格里的RadioButtonList按照DataGrid的总列数进行列添加
18 for (int i=0;i<DataGrid.Items.Count;++i)
19 {
20 ListItem li=new ListItem("","1");
21 ((RadioButtonList)DataGrid1.Items[0].Cells[0].Controls[1]).Items.Add(li);
22 }
23 而确定哪项被选中,可通过 DataGrid1.DataKeys[((RadioButtonList)DataGrid1.Items[0].Cells[0].Controls[1]).SelectedIndex]
24 得到。
当然,最简单的方法就是使用<input type="radio" name=“radioDemo">HTML控件,使用简单,就不再重复了。2 //1、我们将datagrid的第一列设置为模板列,并加入RadioButtonList
3 AutoGenerateColumns="False">
4 <Columns> <asp:TemplateColumn>
5 <ItemTemplate> <asp:RadioButtonList ID="RadioButtonList1" Runat="server"></asp:RadioButtonList>
6 </ItemTemplate>
7 </asp:TemplateColumn> <asp:BoundColumn DataField="CustomerID" HeaderText="CustomerID"></asp:BoundColumn>
8 </Columns>
9 </asp:datagrid>
10 //然后在数据绑定到DataGrid后,即DataGrid1.DataBind();代码之后,写:
11 //将第一列第一单元格的RowSpan设置为DataGrid的总列数
12 DataGrid.Items[0].Cells[0].RowSpan=DataGrid.Items.Count;
13 for (int i=1;i<DataGrid.Items.Count;++i)
14 { DataGrid.Items[i].Cells[0].Visible=false;
15 //从第二列开始隐藏第一个单元格
16 }
17 //将第一列第一个单元格里的RadioButtonList按照DataGrid的总列数进行列添加
18 for (int i=0;i<DataGrid.Items.Count;++i)
19 {
20 ListItem li=new ListItem("","1");
21 ((RadioButtonList)DataGrid1.Items[0].Cells[0].Controls[1]).Items.Add(li);
22 }
23 而确定哪项被选中,可通过 DataGrid1.DataKeys[((RadioButtonList)DataGrid1.Items[0].Cells[0].Controls[1]).SelectedIndex]
24 得到。
而如果我们想用RadioButton实现呢?
这时候,我们就必须思考为什么
<input type="radio" name="radioDemo">可以实现单选
而
<input type="radio" name="radioDemo" id="radioDemo" runat="server">
<asp:RadioButton ID="RadioButton1" runat="server" GroupName="Demo" />
却不能实现单选呢?
如果我们查看浏览器输出的源代码,会发现
Runat="server"的RadioButton的Name变成了类似
1 <input id="countriesGrid__ctl2_selectRadioButton" type="radio" name="countriesGrid:_ctl2:country" value="selectRadioButton" />
这样的Name了,故其实现不了单选。所以,我们只有让DataGrid输出唯一的ClientID
以下为实现代码:
1 using System;
2 using System.Web.UI;
3 using System.Web.UI.WebControls;
4 using System.Globalization;
5
6 namespace Renyu.Web.UI.WebControls
7 {
8 [ToolboxData("<{0}:GroupRadioButton runat=server></{0}:GroupRadioButton>")]
9 public class GroupRadioButton : RadioButton, IPostBackDataHandler
10 {
11 public GroupRadioButton() : base()
12 {
13 }
14
15 #region Properties
16
17 private string Value
18 {
19 get
20 {
21 string val = Attributes["value"];
22 if(val == null)
23 val = UniqueID;
24 else
25 val = UniqueID + "_" + val;
26 return val;
27 }
28 }
29
30 #endregion
31
32 #region Rendering
33
34 protected override void Render(HtmlTextWriter output)
35 {
36 RenderInputTag(output);
37 }
38
39 private void RenderInputTag(HtmlTextWriter htw)
40 {
41 htw.AddAttribute(HtmlTextWriterAttribute.Id, ClientID);
42 htw.AddAttribute(HtmlTextWriterAttribute.Type, "radio");
43 htw.AddAttribute(HtmlTextWriterAttribute.Name, GroupName);
44 htw.AddAttribute(HtmlTextWriterAttribute.Value, Value);
45 if(Checked)
46 htw.AddAttribute(HtmlTextWriterAttribute.Checked, "checked");
47 if(!Enabled)
48 htw.AddAttribute(HtmlTextWriterAttribute.Disabled, "disabled");
49
50 string onClick = Attributes["onclick"];
51 if(AutoPostBack)
52 {
53 if(onClick != null)
54 onClick = String.Empty;
55 onClick += Page.GetPostBackClientEvent(this, String.Empty);
56 htw.AddAttribute(HtmlTextWriterAttribute.Onclick, onClick);
57 htw.AddAttribute("language", "javascript");
58 }
59 else
60 {
61 if(onClick != null)
62 htw.AddAttribute(HtmlTextWriterAttribute.Onclick, onClick);
63 }
64
65 if(AccessKey.Length > 0)
66 htw.AddAttribute(HtmlTextWriterAttribute.Accesskey, AccessKey);
67 if(TabIndex != 0)
68 htw.AddAttribute(HtmlTextWriterAttribute.Tabindex,
69 TabIndex.ToString(NumberFormatInfo.InvariantInfo));
70 htw.RenderBeginTag(HtmlTextWriterTag.Input);
71 htw.RenderEndTag();
72 }
73
74 #endregion
75
76 #region IPostBackDataHandler Members
77
78 void IPostBackDataHandler.RaisePostDataChangedEvent()
79 {
80 OnCheckedChanged(EventArgs.Empty);
81 }
82
83 bool IPostBackDataHandler.LoadPostData(string postDataKey,
84 System.Collections.Specialized.NameValueCollection postCollection)
85 {
86 bool result = false;
87 string value = postCollection[GroupName];
88 if((value != null) && (value == Value))
89 {
90 if(!Checked)
91 {
92 Checked = true;
93 result = true;
94 }
95 }
96 else
97 {
98 if(Checked)
99 Checked = false;
100 }
101 return result;
102 }
103
104 #endregion
105 }
106 }
107
编译为.dll后,即可像System.Web.UI.WebControls.RadioButton一样使用了。2 using System.Web.UI;
3 using System.Web.UI.WebControls;
4 using System.Globalization;
5
6 namespace Renyu.Web.UI.WebControls
7 {
8 [ToolboxData("<{0}:GroupRadioButton runat=server></{0}:GroupRadioButton>")]
9 public class GroupRadioButton : RadioButton, IPostBackDataHandler
10 {
11 public GroupRadioButton() : base()
12 {
13 }
14
15 #region Properties
16
17 private string Value
18 {
19 get
20 {
21 string val = Attributes["value"];
22 if(val == null)
23 val = UniqueID;
24 else
25 val = UniqueID + "_" + val;
26 return val;
27 }
28 }
29
30 #endregion
31
32 #region Rendering
33
34 protected override void Render(HtmlTextWriter output)
35 {
36 RenderInputTag(output);
37 }
38
39 private void RenderInputTag(HtmlTextWriter htw)
40 {
41 htw.AddAttribute(HtmlTextWriterAttribute.Id, ClientID);
42 htw.AddAttribute(HtmlTextWriterAttribute.Type, "radio");
43 htw.AddAttribute(HtmlTextWriterAttribute.Name, GroupName);
44 htw.AddAttribute(HtmlTextWriterAttribute.Value, Value);
45 if(Checked)
46 htw.AddAttribute(HtmlTextWriterAttribute.Checked, "checked");
47 if(!Enabled)
48 htw.AddAttribute(HtmlTextWriterAttribute.Disabled, "disabled");
49
50 string onClick = Attributes["onclick"];
51 if(AutoPostBack)
52 {
53 if(onClick != null)
54 onClick = String.Empty;
55 onClick += Page.GetPostBackClientEvent(this, String.Empty);
56 htw.AddAttribute(HtmlTextWriterAttribute.Onclick, onClick);
57 htw.AddAttribute("language", "javascript");
58 }
59 else
60 {
61 if(onClick != null)
62 htw.AddAttribute(HtmlTextWriterAttribute.Onclick, onClick);
63 }
64
65 if(AccessKey.Length > 0)
66 htw.AddAttribute(HtmlTextWriterAttribute.Accesskey, AccessKey);
67 if(TabIndex != 0)
68 htw.AddAttribute(HtmlTextWriterAttribute.Tabindex,
69 TabIndex.ToString(NumberFormatInfo.InvariantInfo));
70 htw.RenderBeginTag(HtmlTextWriterTag.Input);
71 htw.RenderEndTag();
72 }
73
74 #endregion
75
76 #region IPostBackDataHandler Members
77
78 void IPostBackDataHandler.RaisePostDataChangedEvent()
79 {
80 OnCheckedChanged(EventArgs.Empty);
81 }
82
83 bool IPostBackDataHandler.LoadPostData(string postDataKey,
84 System.Collections.Specialized.NameValueCollection postCollection)
85 {
86 bool result = false;
87 string value = postCollection[GroupName];
88 if((value != null) && (value == Value))
89 {
90 if(!Checked)
91 {
92 Checked = true;
93 result = true;
94 }
95 }
96 else
97 {
98 if(Checked)
99 Checked = false;
100 }
101 return result;
102 }
103
104 #endregion
105 }
106 }
107