自定义服务器端的RadioButton控件实现单选功能 (转自博客园Charles2008)

 在项目中常常需要这样的功能:把RadioButton控件放到GridView(容器)控件中,设置GroupName为固定的一个值的时候实现单选功能,但是当最终生成HTML页面的时候,生成的Name会用 INamingContainer的规则自动生成不同的Name,就不能达到实现单选的效果。 (Name不唯一造成)

问题:如果在容器控件(如GridView)中的模板列中放入Asp:RadioButton控件的时候,实现对列表中的RadioButton的单选,应该怎么实现呢?

有人建议用客户端控件,可以很好的实现绑定,但是后台只能获取到选中项的值,但有时候需要获取未被选中的值,这样的话用客户端控件是不能达到需要的效果的。

那么用服务器端的控件该怎样实现radiobutton的单选呢?

在网上查找了相关的解决方案,找到两种解决方案,但都不是那么令人满意。

1.通过JavaScript脚本设置生成的不唯一Name的radiobutton实现单选的效果.

当然这种通过JavaScript能达到想要的效果,也能实现其功能,但是毕竟Javascript语言是不稳定的。(用户禁用Javascript后发送到服务器后可能会引起一些未知的问题)。

2.通过asp.net Ajax框架中的UpdatePanel,当用户点击服务器端的asp:radioButton后发送到服务器端,执行服务器端的代码,让其实现单选,这样虽然能够实现,但是这样增加了客户端和服务器端数据的传输量。这是不推荐使用的。

思考:其实用实现单选功能,只需要把radiobutton的Name属性设置成一样就可以(这才是关键),但是由于Asp.net机制,放到容器控件中的Template控件中后,生成后的RadioButton的Name就不是唯一的的(模板行ID+radiobutton的ID)(如:Repeater1_ctl02_CustomerRadio1,Repeater1_ctl03_CustomerRadio1

根据上面的思路:自己做一个自定义控件,实现像asp:radioButton那样的功能,又能实现在容器中的Template中也能实现唯一的ID(设置相同的GroupName即可)。根据这个思路,终于实现了,下面是相关的代码实现:请参考

  public   class  SingleCheckRadio : WebControl, IPostBackDataHandler
    
{
        
public string GroupName
        
{
            
get
            
{
                
return ViewState["GroupName"== null ? this.UniqueID : ViewState["GroupName"].ToString();
            }

            
set
            
{
                ViewState[
"GroupName"= value;
            }

        }

 
        
public string Text
        
{
            
get
            
{
                
return ViewState["_text"== null ? "" : ViewState["_text"].ToString();
            }

            
set
            
{
                ViewState[
"_text"= value;
            }

        }


        [DefaultValue(
false)]
        
public Boolean Checked
        
{
            
get
            
{
                
object obj2 = this.ViewState["_checked"];
                
return ((obj2 != null&& ((bool)obj2));

            }

            
set
            
{
                ViewState[
"_checked"= value;
            }

        }


        
protected override void OnInit(EventArgs e)
        
{
            Page.RegisterRequiresPostBack(
this);
            
base.OnInit(e);
        }

        
protected override void Render(HtmlTextWriter writer)
        
{
            
string output = string.Empty;
            
if (Checked)
            
{//如果为true就设置为选择,否则的话不选中。
                output 
= "<input id=/"" + this.ClientID + "/" type=/"radio/" name=/""+GroupName+"/" checked=/"checked/" value=/"" + this.ClientID + "/" />";
            }

            
else
            
{
                output 
= "<input id=/"" + this.ClientID + "/" type=/"radio/" name=/""+GroupName+"/"  value=/"" + this.ClientID + "/" />";
            }

            
if (!string.IsNullOrEmpty(Text))//如果用户设置了Text属性就增加一个label标签(这里类似于asp:radioButton的Text属性的实现)
            
{
                output 
+= "<label for=/"" + this.ClientID + "/">" + Text + "</label>";
            }

            writer.Write(output);

        }



        
protected virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection)
        
{
            
bool flag = false;
            
string str = postCollection[GroupName];
            
bool flag2 = string.Equals(str, this.ClientID);//这里是关键,比较用户选择的那个radiobutton,如果为true的话就把该Check属性设置为true,否则为false.(后怎样把用户选择的值保存下来)
            flag = flag2 != this.Checked;
            
this.Checked = flag2;//这

            
return flag;
        }


        
#region IPostBackDataHandler 成员

        
bool IPostBackDataHandler.LoadPostData(string postDataKey, NameValueCollection postCollection)
        
{
            
return LoadPostData(postDataKey, postCollection);
        }


        
public void RaisePostDataChangedEvent()
        
{
            
return;
        }


        
#endregion
        
    }

这样编写的自定义RadioButton控件,放到容器控件的Template中,生成的RadioButton的Name就是唯一的,都是用户设置的GroupName的值。

下面是根据上面开发的自定义控件做的测试:aspx页面如下:

  < asp:Repeater  ID ="Repeater1"  runat ="server" >
        
< ItemTemplate >
                
< cc1:SingleCheckRadio  ID ="SingleCheckRadio"  Text ='<%#DataBinder.Eval(Container.DataItem,"Name")  % > ' GroupName="test" runat="server" />
        
</ ItemTemplate >
        
</ asp:Repeater >       

下面是后台.cs代码,比较简单就不多说了。(绑定数据并获取选择项radiobutton的text属性。)

  public   class  Person
    {
        
public   string  Name {  get set ; }
        
public   int  Age {  get set ; }
    }
    
public   partial   class  _Default : System.Web.UI.Page
    {

        
protected   void  Page_Load( object  sender, EventArgs e)
        {
            
if  ( ! IsPostBack)
            {
                List
< Person >  Persons  =   new  List < Person > ();

                
for  ( int  i  =   0 ; i  <   10 ; i ++ )
                {
                    Person p 
=   new  Person();
                    p.Name 
=   " Charles "   +  i;
                    p.Age 
=   21   +  i;
                    Persons.Add(p);
                }
                Repeater1.DataSource 
=  Persons;
                Repeater1.DataBind();
            }
        }
        
protected   void  Button1_Click( object  sender, EventArgs e)
        {
            
string  str  =  String.Empty;
            
foreach  (RepeaterItem item  in  Repeater1.Items)
            {

                CustomerRadioNamespace.SingleCheckRadio btn 
=  item.FindControl( " SingleCheckRadio " as  CustomerRadioNamespace.SingleCheckRadio;
                
                
if  (btn.Checked  ==   true )
                {
                    str 
=  btn.Text;
                }
            }

            Response.Write(str);
        }
最后我们来看看生成的HTML源代码:(可以看出生成出来的Name就是程序中设置的GroupName属性且是唯一的,这样就能实现单选功能了)

 <div>
        
                
<input id="Repeater1_ctl00_SingleCheckRadio" type="radio" name="test"  value="Repeater1_ctl00_SingleCheckRadio" /><label for="Repeater1_ctl00_SingleCheckRadio">Charles0</label>
        
                
<input id="Repeater1_ctl01_SingleCheckRadio" type="radio" name="test"  value="Repeater1_ctl01_SingleCheckRadio" /><label for="Repeater1_ctl01_SingleCheckRadio">Charles1</label>
        
                
<input id="Repeater1_ctl02_SingleCheckRadio" type="radio" name="test"  value="Repeater1_ctl02_SingleCheckRadio" /><label for="Repeater1_ctl02_SingleCheckRadio">Charles2</label>
        
                
<input id="Repeater1_ctl03_SingleCheckRadio" type="radio" name="test"  value="Repeater1_ctl03_SingleCheckRadio" /><label for="Repeater1_ctl03_SingleCheckRadio">Charles3</label>
        
                
<input id="Repeater1_ctl04_SingleCheckRadio" type="radio" name="test"  value="Repeater1_ctl04_SingleCheckRadio" /><label for="Repeater1_ctl04_SingleCheckRadio">Charles4</label>
        
                
<input id="Repeater1_ctl05_SingleCheckRadio" type="radio" name="test"  value="Repeater1_ctl05_SingleCheckRadio" /><label for="Repeater1_ctl05_SingleCheckRadio">Charles5</label>
        
                
<input id="Repeater1_ctl06_SingleCheckRadio" type="radio" name="test"  value="Repeater1_ctl06_SingleCheckRadio" /><label for="Repeater1_ctl06_SingleCheckRadio">Charles6</label>
        
                
<input id="Repeater1_ctl07_SingleCheckRadio" type="radio" name="test"  value="Repeater1_ctl07_SingleCheckRadio" /><label for="Repeater1_ctl07_SingleCheckRadio">Charles7</label>
        
                
<input id="Repeater1_ctl08_SingleCheckRadio" type="radio" name="test"  value="Repeater1_ctl08_SingleCheckRadio" /><label for="Repeater1_ctl08_SingleCheckRadio">Charles8</label>
        
                
<input id="Repeater1_ctl09_SingleCheckRadio" type="radio" name="test"  value="Repeater1_ctl09_SingleCheckRadio" /><label for="Repeater1_ctl09_SingleCheckRadio">Charles9</label>
               
    
</div>

 

这样上面提到的效果实现了。而且兼容该控件放到其他子控件,还是比较实用的。

注:另外还可以为该控件定义事件,通过用户选择触发相应的服务器事件。(上面的代码未提供)

最后希望各位朋友们多多提出宝贵的意见,非常感谢。

Charles Chen

Regards

MSN:Charles.C.Chen@newegg.net

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值