背景:
网上很多帖子都问在DataList(或者DataGrid)的ItemTemplate列中嵌入单选按钮,如何能实现单选功能。我们知道,由于DataList的内部原因(我们这里不深究), 当页面发送到客户端的时候,会为它的每一个DataListItem中的控件的Name属性自动赋值。
例如,DataList的ID为“DL”,嵌入DataList的单选按钮的Name值我们设为“radio”, 假设数据邦定后有3个DataListItem,那当页面发送到客户端的时候页面上的三个单选按钮的Name可能分别为"DL_ctl0_radio","DL_ctl1_radio","DL_ctl2_radio"。如此我们等到了三个完全不同的单选按钮,根本不可能实现三个按钮的单选效果。
解决方案:
我的解决方案就是我们在DataList数据绑定的时候动态写入Html代码。具体操作如下:
我们通常为了排版的方便经常会在ItemTemplate列中先放入一个HtmlDataTable,然后再在各个表格(HtmlTableCell)内放入我们需要的控件。但是这里,我们需要你将其中一个表格设为服务器控件(例如:ID为CellForRadio)以便在后台可以获取得到。
接着就是在数据绑定时向CellForRadio写入Html代码,如下所示:
private
void
DL_MyReport_ItemDataBound(
object
sender, System.Web.UI.WebControls.DataListItemEventArgs e)
{
HtmlTableCell CellForRadio;
if(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
CellForRadio = (HtmlTableCell) e.Item.FindControl("CellForRadio");
CellForRadio.InnerHtml = "<input type=radio id='Radio"+index+"' runat='server' name='radio')>";
index++;
}
}
{
HtmlTableCell CellForRadio;
if(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
CellForRadio = (HtmlTableCell) e.Item.FindControl("CellForRadio");
CellForRadio.InnerHtml = "<input type=radio id='Radio"+index+"' runat='server' name='radio')>";
index++;
}
}
这里我们看到我们将Radio的Name设为了radio,页面送到客户端也不会变化radio的name,这样我们就实现了radio的单选功能了,是不是很方便,但事情远没有我们想象的这么简单。
大家看到我这里还设了radio的ID属性,并且用index动态改变ID值,这个index其实是一个全局变量,作用就不多说了。为什么要加一个ID属性了,其实是想把它变为服务器控件,因为单选功能实现了,接下来我们要做什么事情呢?是点击一个单选按钮就打开一个Panel;还是再点击一个Button,通过获取被选择的某个单选按钮的值去触发下一个事件,谁知道呢?但这下都是要让后台知道你究竟选择了哪个单选按钮。
我们就挑在选取了单选按钮后,再去点击Button触发新事件这样一个场景来举例说吧,首先要让服务器端获知你选择了哪个单选按钮,如下所示:
private
void
btn_Execute_Click(
object
sender, System.EventArgs e)
{
for(int i = 0; i<DL.Items.Count; i++)
{
HtmlInputRadio rad_selected = (HtmlInputRadio)DL.Items[i].FindControl("CellForRadio").Controls[0];
if(rad_selected.Checked)
{
//DoSomething
}
}
}
如此,我们就可以像使用普通控件一样使用操作单选按钮了。
{
for(int i = 0; i<DL.Items.Count; i++)
{
HtmlInputRadio rad_selected = (HtmlInputRadio)DL.Items[i].FindControl("CellForRadio").Controls[0];
if(rad_selected.Checked)
{
//DoSomething
}
}
}