• 扩展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发生客户端点击事件时,动态设置其它选择按钮的选中状态。例如上文中的onclick="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];
            }

           

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


     

  • 相关阅读:
    System Idle Process SYSTEM占用CPU
    apache和nginx的rewrite的区别
    解决file_get_contents failed to open stream: HTTP request failed! 错误
    个人总结大型高并发高负载网站的系统架构(转)
    代码的抽象三原则
    mysqldump导入某库某表的数据
    mysql中insert into和replace into以及insert ignore用法区别
    【原创】学习日记4:nginx负载均衡(二)2012.01.08
    【原创】学习日记1:redis安装以及lnmp环境搭建2012.01.06
    mysql优化 mysql.ini优化
  • 原文地址:https://www.cnblogs.com/ASPNET2008/p/1441163.html
Copyright © 2020-2023  润新知