扩展GridView之添加单选列

      背景:实现GridView的单选列,传统的做法应该是新增模板列,然后添加RadioButton,客户端实现单选,后台遍历读取选中行数据。


      第一:添加模板列,加入RadioButton。为了取值方便,我把记录的主键放在HiddenField中保存。

< asp:TemplateField meta:resourcekey = " TemplateFieldResource3 " >
     
< ItemTemplate >
         
< asp:RadioButton ID = " rbChecked "   runat = " server "  onclick = " rbCheck(this.id) "   />
       
< asp:HiddenField ID = " hidID "  Value  = ' <%# Eval("ID") %> '  runat = " server "   />
      
</ ItemTemplate >
 
</ asp:TemplateField >

 

      发现问题:生成的选择列并没有单选功能,解决过程:
      1:设置RadionButton的GroupName,结果证明是不可行的。
      2:RadionButton生成的html为input,可不可以设置name属性呢,结果也是不可行,因为GridView生成数据行的时候,会修改这个name值,使得最终的name值各不相同。

      解决方案:在RadioButton发生客户端点击事件时,动态设置其它选择按钮的选中状态。例如上文中的οnclick="rbCheck(this.id)"。这样可以实现单选的效果。

function rbCheck(obj)
{
  var gv 
=  $( " <%=this .GridView1 .ClientID  %> " );
       
// 被选择的个数
       var num = 0 ;
         
for (i  =   1 ;i  <  gv.rows.length; i ++ )
         {
             var inputArray 
=  gv.rows[i].getElementsByTagName( " input " );
             
for (var j = 0 ;j < inputArray.length;j ++ )
             { 
                 
if (inputArray[j].type == ' radio ' )
                 {
                   
if (inputArray[j].id == obj)
                   {
                        inputArray[j].
checked = true ;
                        
                   }
                   
else
                   {
                        inputArray[j].
checked = false ;
                   }
                  }
             }
          }
}

 

      后台的取值需要遍历GridView所有数据行,然后根据HiddenField和RadioButton的选中情况来取最后的记录的主键值。

 

///   <summary>
    
///  取选中行的ID
    
///   </summary>
    
///   <returns></returns>
     private   string   getID()
    {
        
string  id = "" ;
        
foreach  (GridViewRow row  in   this .GridView1.Rows)
        {
            CheckBox cb 
=  (CheckBox)row.FindControl( " rbChecked " );
            
if  (cb  !=   null   &&  cb.Checked)
            {
                HiddenField hidID 
=  (HiddenField)row.FindControl( " hidID " );
                id 
=  hidID.Value.ToString();
            }
        }
        
return  id;

    }

 

     小结:上面的方案在功能上已经实现了单选列的效果,但如果这样的页面多几个的话,就需要考虑封装下,这里jillzhang以前扩展过GridView,他的文章的中实现了单选列功能。我在这里在单拿这一方面的功能总结一下如果扩展GridView实现新增模板列。GridView本身提供了多选模板列,我们需要新增一个单选模板列。


      第一:模板列需要实现ITemplate 接口:定义用子控件填充模板化 ASP.NET 服务器控件的行为。子控件表示页上定义的内联模板。它包含一个重要的方法:InstantiateIn(Control container),ITemplate需要实现的方法当由类实现时,定义子控件和模板所属的 Control 对象。然后在内联模板中定义这些子控件。这里我们创建一个类:由于RadioButton会动态改变name值,所有这里直接生成html控件radio,这样可以保证name值都是一样的。

///   <summary>
    
///  ITemplate  :定义用子控件填充模板化 
    
///  ASP.NET 服务器控件的行为。子控件表示页上定义的内联模板。
    
///   </summary>
     public   class  RadioColumItemTemplate:ITemplate   
    {
        
///   <summary>
        
///  单选按钮的ID
        
///   </summary>
         public   static   string  RadioButtonItemId
        {
            
get
            {
                
return   " RadioColumnItem " ;
            }
        }
        
///   <summary>
        
///  ITemplate需要实现的方法
        
///  当由类实现时,定义子控件和模板所属的 Control 对象。然后在内联模板中定义这些子控件。
        
///   </summary>
        
///   <param name="container"></param>
         public   void  InstantiateIn(Control container)
        {
            HtmlGenericControl l 
=   new  HtmlGenericControl();
            l.DataBinding 
+=   new  EventHandler(l_DataBinding);           
            container.Controls.Add(l);
        }
        
///   <summary>
        
///  具体事件,添加单选按钮
        
///   </summary>
        
///   <param name="sender"></param>
        
///   <param name="e"></param>
         void  l_DataBinding( object  sender, EventArgs e)
        {
            
// 加入html控件
            HtmlGenericControl l  =  sender  as   HtmlGenericControl;
            
if  (l  !=   null )
            {
                GridViewRow row 
=  (GridViewRow)l.NamingContainer;
                l.InnerHtml 
=   " <input type='radio' name=' "   +  RadioButtonItemId  +   " ' value=' "   +  row.DataItemIndex  +   " '/> " ;
            }
        }    

 

       第二:我们需要对新增的单选模板列做些设置以及把它集成到GridView控件中去,这里最重要的就是重写GridView的CreateColumnEvent。在生成列的时候执行我们自定义的模板列。

if  (Owner  !=   null && Visible)
{
   Owner.CreateColumnEvent 
+=   new  WebCustomControl_GridViewEx.CreateColumnHandler(Owner_CreateColumnEvent);               
}

///   <summary>
        
///  生成列事件
        
///   </summary>
        
///   <param name="col"></param>
         void  Owner_CreateColumnEvent(System.Collections.ICollection col)
        {
            ArrayList colList 
=  col  as  ArrayList;
            AddColumn(colList);
        }
        
///   <summary>
        
///  添加单选列
        
///   </summary>
        
///   <param name="col"></param>
         void  AddColumn(ArrayList col)
        {
            
if  (Visible)
            {
                TemplateField checkColumn 
=   new  TemplateField();
                checkColumn.HeaderStyle.Width 
=   this .Width;
                checkColumn.ItemStyle.HorizontalAlign 
=  HorizontalAlign.Center;
                checkColumn.HeaderStyle.HorizontalAlign 
=  HorizontalAlign.Center;
                RadioColumItemTemplate cbItemTemplate 
=   new  RadioColumItemTemplate();
                checkColumn.ItemTemplate 
=  cbItemTemplate;
                checkColumn.ItemStyle.Width 
=   this .Width;             
                checkColumn.HeaderText 
=   " 单选列 " ;
                
if  ( this .Align  ==  CustomColumnAlign.Left)
                {
                    col.Insert(
0 , checkColumn);
                }
                
else   if  ( this .Align  ==  CustomColumnAlign.Right)
                {
                    col.Add(checkColumn);
                }
                
else   if  ( this .Align  ==  CustomColumnAlign.Custom)
                {
                    col.Insert(
this .Position, checkColumn);
                }
            }
        }


      第三:读取单选列被选中记录的主键值,控件中因为事先并不知道数据源结构,所以这里只返回数据行的索引值,后台需要根据这个索引值在数据源中查询相关数据。

///   <summary>
        
///  读取单选列的值
        
///   </summary>
        
///   <returns></returns>
         public   string  GetRadioItemValue()
        {
            HttpRequest request 
=  HttpContext.Current.Request;
            
return  request.Form[RadioColumItemTemplate.RadioButtonItemId];
        }

       

      总结:扩展后控件单选效果的实现得到简化,无需程序员去手动添加模板列,以及实现客户端单选功能。后台取值也简化了。扩展服务器控件其实并不难,难的是你不去了解它。有时就是这样的小小封装对你平时的工作效率会有比较大的提高。一个人的成功有时往往体现在细节上。

 


 

转载于:https://www.cnblogs.com/ASPNET2008/archive/2009/04/22/1441163.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值