Asp.net 2.0 自定义控件开发[实现GridView多行表头固定表体滚动效果][示例代码下载]

本文介绍了一种自定义控件GridViewExpendHeader,该控件继承了GridView的所有功能,并增加了表头固定与表体滚动的功能。通过设置扩展属性ScrollWidth和ScrollHeight,可以轻松实现单行或多行表头的自动滚动。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(一). 概述

        1. 实现GridView表头固定表体滚动效果

        2. 继承GridView的所有功能, 增加扩展功能, 表体滚动功能; 不需要另外加辅助滚动控件, 如

.

        3. 支持多行表头滚动, 此控件能够自动检测到使用者增加的表头的行数. 准确的实现表头滚动.

            有增加GridView多表头实现方案, 请看[多表头自定义控件]. 

实现原理:
    一般要实现GridView表头固定,表体滚动功能时,都是自己增加一个
控件,
然后将GridView嵌套在这个
控件里面;使用这个GridView控件就不用在页面中自己
增加个
控件了,因为它自动完成了增加
控件的功能, 具有通用性 .

(二). 运行如图

      1.  单行表头增加自动滚动效果

 

      2.  多行表头增加自动滚动效果

  

 

(三). 用法

   1. 将GridViewExpendHeader控件Dll添加引用到Web站点工程中

   2. 从工具箱拖动一个GridViewExpendHeader控件到设计器中

   3. 设置GridViewExpendHeader控件的属性.

                a.  设置属性窗口中新增的 "扩展" 类别中的两个属性,  这两个属性是指滚动区域的大小, 如下图所示:

                        

               b.  设置GridView本身的高度Height, 这个高度是指滚动区域内的GridView的实际高度, 这个高度数值设置

                     要大于ScrollHeight滚动条才能够呈现.  简单地说, 本自定义控件自动会实现一个GridView(自己)

                    的父控件

,  然后再把自己放在里面,  如果自己高度小于
高度了,  不用滚动就能够显示

                    全自己的数据, 滚动条就没有呈现的意义了.   这里讲得有点啰嗦.   .        

   4. F5运行即可

(四). 完整代码

    1. 主控件GridViewFixedMultiHeader类代码    

  1       ///   < summary >
  2       ///  Author: [ ChengKing(ZhengJian) ] 
  3       ///  Blog:   Http: // blog.youkuaiyun.com / ChengKing
  4       ///   Date :    2007 / 4 / 3
  5       ///   summary>    
  6     /// <summary>
  7     /// 主控件类, 继承GridView的所有功能
  8     ///  summary>
  9     [ToolboxData("<{0}:GridViewExpendHeader runat=server> ")]
 10     public class GridViewFixedMultiHeader : GridView 
 11     {       
 12         [Description("当需要重新构造Header时触发此事件")]
 13         public event System.EventHandler RebuildHeader;
 14 
 15         private System.Web.UI.WebControls.Panel pnlScroll = new System.Web.UI.WebControls.Panel();
 16 
 17         #region 扩展
 18         /// <summary>
 19         /// 设定滚动容器的宽度
 20         ///  summary>
 21         [Bindable(true)]
 22         [Category("扩展")]
 23         [DefaultValue("500px")]
 24         [Localizable(true)]
 25         [TypeConverter(typeof(UnitConverter))]
 26         public Unit ScrollWidth
 27         {
 28             get
 29             {
 30                 return pnlScroll.Width;
 31             }
 32             set
 33             {
 34                 pnlScroll.Width = value;
 35             }
 36         }
 37 
 38         /// <summary>
 39         /// 设定滚动容器的高度
 40         ///  summary>
 41         [Bindable(true)]
 42         [Category("扩展")]
 43         [DefaultValue("150px")]
 44         [Localizable(true)]
 45         [TypeConverter(typeof(UnitConverter))]
 46         public Unit ScrollHeight
 47         {
 48             get
 49             {
 50                 return pnlScroll.Height;
 51             }
 52             set
 53             {
 54                 pnlScroll.Height = value;
 55             }
 56         }
 57         #endregion
 58 
 59         protected override void OnPreRender(EventArgs e)
 60         {
 61             
 62             StringBuilder sb = new StringBuilder();              
 63             sb.Append(" function Tidy()");
 64             sb.Append(" {");
 65             sb.Append("     var gve = document.getElementById(/""+ this.UniqueID +"/"); ");            
 66             sb.Append("     if( gve.rows.length > 0 )");
 67             sb.Append("     {");
 68             sb.Append("         var a1 = document.getElementById(/"divHeaderContainer/");");
 69             sb.Append("         var table1 = document.createElement(/"table/");");
 70             sb.Append("         var tbody1 = document.createElement(/"tbody/");");
 71             sb.Append("         table1.style.cssText = /"table-layout:fixed;border-style: solid ;border-color:gray; border-width: 1px thin;/";   ");
 72             //sb.Append("         table1.style.cssText = /"table-layout:fixed;color:#CCCCFF;background-color:#003399;font-weight:bold;/";");
 73             sb.Append("         var i;");
 74             sb.Append("         var blnIfFind = false;");
 75             sb.Append("         for( i = gve.rows.length - 1; i >= 0; i-- )");
 76             sb.Append("         {");
 77             sb.Append("             if( gve.rows[i].children(0).tagName.toUpperCase() != /"TH/" && blnIfFind == false )  ");
 78             sb.Append("             {");
 79             sb.Append("                 continue;");
 80             sb.Append("             }");
 81             sb.Append("             if( blnIfFind == false )");
 82             sb.Append("             {");
 83             sb.Append("                 blnIfFind = true; ");
 84             sb.Append("             }");
 85             sb.Append("             if( tbody1.children.length == 0 )");
 86             sb.Append("             {");
 87             sb.Append("                 var newRow = gve.rows[i].cloneNode(true); ");
 88             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");            
 89             sb.Append("                 tbody1.appendChild( newRow ); ");
 90             sb.Append("             }");
 91             sb.Append("             else");
 92             sb.Append("             {");
 93             sb.Append("                 var newRow = gve.rows[i].cloneNode(true);   ");
 94             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");
 95             sb.Append("                 tbody1.insertBefore( newRow , tbody1.firstChild );");
 96             sb.Append("             }");
 97             sb.Append("         }");
 98             sb.Append("         table1.appendChild(tbody1);");
 99             sb.Append("         a1.appendChild(table1); ");
100             sb.Append("         for( i = 0; i < gve.rows.length -1; i++)");
101             sb.Append("         {");
102             sb.Append("             if( gve.rows[0].children(0).tagName.toUpperCase() != /"TH/" )");
103             sb.Append("             {");
104             sb.Append("                 gve.deleteRow(0);   ");
105             sb.Append("                 continue;");
106             sb.Append("             }");
107             sb.Append("             gve.deleteRow(0);   ");
108             sb.Append("             break; ");
109             sb.Append("         }");
110             sb.Append("     }");
111             sb.Append(" }");
112 
113             if (!Page.ClientScript.IsClientScriptBlockRegistered("Tidy"))
114             {
115                 Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Tidy", sb.ToString(),true);
116             }
117 
118             if (!Page.ClientScript.IsStartupScriptRegistered("Init"))
119             {
120                 Page.ClientScript.RegisterStartupScript(this.GetType(), "Init""<script type=/"text/javascript/">window.onload = Tidy;</script> "false);
121             }
122 
123             base.OnPreRender(e);
124         }
125 
126         protected override void Render(HtmlTextWriter writer)
127         {
128             OnRebuildHeader();         
129             base.Render(writer);
130         }
131         protected override void CreateChildControls()
132         {
133             Control parent = this.Parent;
134 
135             if (DesignMode == false)
136             {
137                 //生成头容器<DIV>
138                 System.Web.UI.HtmlControls.HtmlGenericControl div = new System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
139                 div.ID = "divHeaderContainer";
140                 div.Style.Add("width", this.Width.ToString());
141                 parent.Controls.Add(div);
142 
143                 Control gridView = this;
144                 parent.Controls.Remove(gridView);
145                  
146                 pnlScroll.Style.Add("width", this.Width.ToString());
147                 pnlScroll.Style.Add("OVERFLOW-Y""scroll");
148                 pnlScroll.Style.Add("OVERFLOW-X""hidden");
149        
150                 pnlScroll.Controls.Add(this);
151                 parent.Controls.Add(pnlScroll);
152 
153                 ChildControlsCreated = true;
154             }
155 
156             base.CreateChildControls();            
157         }
158     
159         protected virtual void OnRebuildHeader()
160         {
161             //重新构造Head
162             if (RebuildHeader != null)
163             {
164                 RebuildHeaderEventArgs args = new RebuildHeaderEventArgs();
165                 args.GridViewObject = this;
166                 args.HeaderRowObject = this.HeaderRow;
167 
168                 RebuildHeader(this, args);
169             }
170             
171         }       
172     } 

    2. 文件RebuildHeaderEventArgs.cs 代码

 1  ///  
 2     /// Author: [ ChengKing(ZhengJian) ] 
 3     /// Blog:   Http://blog.youkuaiyun.com/ChengKing
 4     /// Date:   2007/4/3
 5     /// 

 6       ///  
 7     /// 承载重构Header事件所需的参数[Author:ChengKing(ZhengJian)]
 8     /// 

 9       public   class  RebuildHeaderEventArgs : EventArgs
10      {
11           private  GridViewFixedMultiHeader _GridViewObject;
12           private  GridViewRow _HeaderRowObject;
13 
14           ///  
15         /// 存储GrivViewExtend对象本身
16         /// 

17           public  GridViewFixedMultiHeader GridViewObject
18          {
19               get
20              {
21                   return  _GridViewObject;
22              }
23               set
24              {
25                  _GridViewObject  =  value;
26              }
27          }
28 
29           ///  
30         /// 存储GrivViewExtend的HeaderRow对象
31         /// 

32           public  GridViewRow HeaderRowObject
33          {
34               get
35              {
36                   return  _HeaderRowObject;
37              }
38               set
39              {
40                  _HeaderRowObject  =  value;
41              }
42          }
43      }

   3. 测试页面文件default.aspx代码, 直接拖动一个控件到设计器就OK了. 不需要设置任何属性.

1 <div>
2    <asp:GridView ID="GridViewFixedMultiHeader1" runat="server"  asp:GridView>                  
3  div>

   4. 在新增自定义事件中增加表头行代码, 这里增加三行表头HeaderRow.
 1  ///  
 2     /// 具体重写方法, 此方法比较灵活, 可以任意设置您需要创建的格式, 比如更复杂的表格
 3     /// 另外, 可以直接从第二个参数中取得控件对象引用
 4     /// 

 5       ///  
 6       ///  
 7       protected   void  GridViewExpend1_RebuildHeader( object  sender, EventArgs e)
 8      {
 9           // 取得参数e中包含的对象的引用        
10          GridViewFixedMultiHeader currentGVE  =  ((RebuildHeaderEventArgs)e).GridViewObject;   // 到操作当前GridView的对象引用
11          GridViewRow currentHeaderRow  =  ((RebuildHeaderEventArgs)e).HeaderRowObject;  /// /到操作当前GridView's HeaderRow的对象引用
12 
13 
14           ///
15           /// /在当前HeaderRow上面增加一行
16           // 创建一个行并设置与GridViewExtend当前的头类型风格一致
17          GridViewRow willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
18          willAddHeaderRow.Font.Bold  =   true ;
19          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
20          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
21          TableCell cell  =   new  TableCell();
22          cell.Text  =   " Number " ;
23          cell.HorizontalAlign  =  HorizontalAlign.Center;
24          willAddHeaderRow.Cells.Add(cell);
25          cell  =   new  TableCell();
26          cell.Text  =   " Detail " ;
27          cell.ColumnSpan  =   2 ;
28          cell.HorizontalAlign  =  HorizontalAlign.Center;
29          willAddHeaderRow.Cells.Add(cell);
30           // 添加到GridView
31          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);
32 
33 
34           ///
35           /// /在当前HeaderRow上面再增加一行
36           // 同样创建一个行并设置与GridViewExtend当前的头类型风格一致
37          willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
38          willAddHeaderRow.Font.Bold  =   true ;
39          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
40          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
41 
42          cell  =   new  TableCell();
43          cell.Text  =   " Fruits category information " ;
44          cell.ColumnSpan  =   3 ;
45          cell.HorizontalAlign  =  HorizontalAlign.Center;
46          willAddHeaderRow.Cells.Add(cell);
47           // 添加到GridView
48          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);  
49       
50           // 还可以继续增加N个表头行;
51           // 不管增加多么, GridView控件都能够自动检测到HeaderRow的个数, 并且能够正确呈现滚动条
52           // ..;  
53           // ..; 
54      }

 

(五). 示例代码下载

        http://www.cnblogs.com/Files/MVP33650/extendgridviewfixedmultiheader.rar

 

(六). 控件开发其它相关文章:

        http://blog.youkuaiyun.com/ChengKing/category/288694.aspx

 

 

 

 

 

 

  


(一). 概述

        1. 实现GridView表头固定表体滚动效果

        2. 继承GridView的所有功能, 增加扩展功能, 表体滚动功能; 不需要另外加辅助滚动控件, 如

.

        3. 支持多行表头滚动, 此控件能够自动检测到使用者增加的表头的行数. 准确的实现表头滚动.

            有增加GridView多表头实现方案, 请看[多表头自定义控件]. 

实现原理:
    一般要实现GridView表头固定,表体滚动功能时,都是自己增加一个
控件,
然后将GridView嵌套在这个
控件里面;使用这个GridView控件就不用在页面中自己
增加个
控件了,因为它自动完成了增加
控件的功能, 具有通用性 .

(二). 运行如图

      1.  单行表头增加自动滚动效果

 

      2.  多行表头增加自动滚动效果

  

 

(三). 用法

   1. 将GridViewExpendHeader控件Dll添加引用到Web站点工程中

   2. 从工具箱拖动一个GridViewExpendHeader控件到设计器中

   3. 设置GridViewExpendHeader控件的属性.

                a.  设置属性窗口中新增的 "扩展" 类别中的两个属性,  这两个属性是指滚动区域的大小, 如下图所示:

                        

               b.  设置GridView本身的高度Height, 这个高度是指滚动区域内的GridView的实际高度, 这个高度数值设置

                     要大于ScrollHeight滚动条才能够呈现.  简单地说, 本自定义控件自动会实现一个GridView(自己)

                    的父控件

,  然后再把自己放在里面,  如果自己高度小于
高度了,  不用滚动就能够显示

                    全自己的数据, 滚动条就没有呈现的意义了.   这里讲得有点啰嗦.   .        

   4. F5运行即可

(四). 完整代码

    1. 主控件GridViewFixedMultiHeader类代码    

  1       ///   < summary >
  2       ///  Author: [ ChengKing(ZhengJian) ] 
  3       ///  Blog:   Http: // blog.youkuaiyun.com / ChengKing
  4       ///   Date :    2007 / 4 / 3
  5       ///   summary>    
  6     /// <summary>
  7     /// 主控件类, 继承GridView的所有功能
  8     ///  summary>
  9     [ToolboxData("<{0}:GridViewExpendHeader runat=server> ")]
 10     public class GridViewFixedMultiHeader : GridView 
 11     {       
 12         [Description("当需要重新构造Header时触发此事件")]
 13         public event System.EventHandler RebuildHeader;
 14 
 15         private System.Web.UI.WebControls.Panel pnlScroll = new System.Web.UI.WebControls.Panel();
 16 
 17         #region 扩展
 18         /// <summary>
 19         /// 设定滚动容器的宽度
 20         ///  summary>
 21         [Bindable(true)]
 22         [Category("扩展")]
 23         [DefaultValue("500px")]
 24         [Localizable(true)]
 25         [TypeConverter(typeof(UnitConverter))]
 26         public Unit ScrollWidth
 27         {
 28             get
 29             {
 30                 return pnlScroll.Width;
 31             }
 32             set
 33             {
 34                 pnlScroll.Width = value;
 35             }
 36         }
 37 
 38         /// <summary>
 39         /// 设定滚动容器的高度
 40         ///  summary>
 41         [Bindable(true)]
 42         [Category("扩展")]
 43         [DefaultValue("150px")]
 44         [Localizable(true)]
 45         [TypeConverter(typeof(UnitConverter))]
 46         public Unit ScrollHeight
 47         {
 48             get
 49             {
 50                 return pnlScroll.Height;
 51             }
 52             set
 53             {
 54                 pnlScroll.Height = value;
 55             }
 56         }
 57         #endregion
 58 
 59         protected override void OnPreRender(EventArgs e)
 60         {
 61             
 62             StringBuilder sb = new StringBuilder();              
 63             sb.Append(" function Tidy()");
 64             sb.Append(" {");
 65             sb.Append("     var gve = document.getElementById(/""+ this.UniqueID +"/"); ");            
 66             sb.Append("     if( gve.rows.length > 0 )");
 67             sb.Append("     {");
 68             sb.Append("         var a1 = document.getElementById(/"divHeaderContainer/");");
 69             sb.Append("         var table1 = document.createElement(/"table/");");
 70             sb.Append("         var tbody1 = document.createElement(/"tbody/");");
 71             sb.Append("         table1.style.cssText = /"table-layout:fixed;border-style: solid ;border-color:gray; border-width: 1px thin;/";   ");
 72             //sb.Append("         table1.style.cssText = /"table-layout:fixed;color:#CCCCFF;background-color:#003399;font-weight:bold;/";");
 73             sb.Append("         var i;");
 74             sb.Append("         var blnIfFind = false;");
 75             sb.Append("         for( i = gve.rows.length - 1; i >= 0; i-- )");
 76             sb.Append("         {");
 77             sb.Append("             if( gve.rows[i].children(0).tagName.toUpperCase() != /"TH/" && blnIfFind == false )  ");
 78             sb.Append("             {");
 79             sb.Append("                 continue;");
 80             sb.Append("             }");
 81             sb.Append("             if( blnIfFind == false )");
 82             sb.Append("             {");
 83             sb.Append("                 blnIfFind = true; ");
 84             sb.Append("             }");
 85             sb.Append("             if( tbody1.children.length == 0 )");
 86             sb.Append("             {");
 87             sb.Append("                 var newRow = gve.rows[i].cloneNode(true); ");
 88             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");            
 89             sb.Append("                 tbody1.appendChild( newRow ); ");
 90             sb.Append("             }");
 91             sb.Append("             else");
 92             sb.Append("             {");
 93             sb.Append("                 var newRow = gve.rows[i].cloneNode(true);   ");
 94             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");
 95             sb.Append("                 tbody1.insertBefore( newRow , tbody1.firstChild );");
 96             sb.Append("             }");
 97             sb.Append("         }");
 98             sb.Append("         table1.appendChild(tbody1);");
 99             sb.Append("         a1.appendChild(table1); ");
100             sb.Append("         for( i = 0; i < gve.rows.length -1; i++)");
101             sb.Append("         {");
102             sb.Append("             if( gve.rows[0].children(0).tagName.toUpperCase() != /"TH/" )");
103             sb.Append("             {");
104             sb.Append("                 gve.deleteRow(0);   ");
105             sb.Append("                 continue;");
106             sb.Append("             }");
107             sb.Append("             gve.deleteRow(0);   ");
108             sb.Append("             break; ");
109             sb.Append("         }");
110             sb.Append("     }");
111             sb.Append(" }");
112 
113             if (!Page.ClientScript.IsClientScriptBlockRegistered("Tidy"))
114             {
115                 Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Tidy", sb.ToString(),true);
116             }
117 
118             if (!Page.ClientScript.IsStartupScriptRegistered("Init"))
119             {
120                 Page.ClientScript.RegisterStartupScript(this.GetType(), "Init""<script type=/"text/javascript/">window.onload = Tidy;</script> "false);
121             }
122 
123             base.OnPreRender(e);
124         }
125 
126         protected override void Render(HtmlTextWriter writer)
127         {
128             OnRebuildHeader();         
129             base.Render(writer);
130         }
131         protected override void CreateChildControls()
132         {
133             Control parent = this.Parent;
134 
135             if (DesignMode == false)
136             {
137                 //生成头容器<DIV>
138                 System.Web.UI.HtmlControls.HtmlGenericControl div = new System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
139                 div.ID = "divHeaderContainer";
140                 div.Style.Add("width", this.Width.ToString());
141                 parent.Controls.Add(div);
142 
143                 Control gridView = this;
144                 parent.Controls.Remove(gridView);
145                  
146                 pnlScroll.Style.Add("width", this.Width.ToString());
147                 pnlScroll.Style.Add("OVERFLOW-Y""scroll");
148                 pnlScroll.Style.Add("OVERFLOW-X""hidden");
149        
150                 pnlScroll.Controls.Add(this);
151                 parent.Controls.Add(pnlScroll);
152 
153                 ChildControlsCreated = true;
154             }
155 
156             base.CreateChildControls();            
157         }
158     
159         protected virtual void OnRebuildHeader()
160         {
161             //重新构造Head
162             if (RebuildHeader != null)
163             {
164                 RebuildHeaderEventArgs args = new RebuildHeaderEventArgs();
165                 args.GridViewObject = this;
166                 args.HeaderRowObject = this.HeaderRow;
167 
168                 RebuildHeader(this, args);
169             }
170             
171         }       
172     } 

    2. 文件RebuildHeaderEventArgs.cs 代码

 1  ///  
 2     /// Author: [ ChengKing(ZhengJian) ] 
 3     /// Blog:   Http://blog.youkuaiyun.com/ChengKing
 4     /// Date:   2007/4/3
 5     /// 

 6       ///  
 7     /// 承载重构Header事件所需的参数[Author:ChengKing(ZhengJian)]
 8     /// 

 9       public   class  RebuildHeaderEventArgs : EventArgs
10      {
11           private  GridViewFixedMultiHeader _GridViewObject;
12           private  GridViewRow _HeaderRowObject;
13 
14           ///  
15         /// 存储GrivViewExtend对象本身
16         /// 

17           public  GridViewFixedMultiHeader GridViewObject
18          {
19               get
20              {
21                   return  _GridViewObject;
22              }
23               set
24              {
25                  _GridViewObject  =  value;
26              }
27          }
28 
29           ///  
30         /// 存储GrivViewExtend的HeaderRow对象
31         /// 

32           public  GridViewRow HeaderRowObject
33          {
34               get
35              {
36                   return  _HeaderRowObject;
37              }
38               set
39              {
40                  _HeaderRowObject  =  value;
41              }
42          }
43      }

   3. 测试页面文件default.aspx代码, 直接拖动一个控件到设计器就OK了. 不需要设置任何属性.

1 <div>
2    <asp:GridView ID="GridViewFixedMultiHeader1" runat="server"  asp:GridView>                  
3  div>

   4. 在新增自定义事件中增加表头行代码, 这里增加三行表头HeaderRow.
 1  ///  
 2     /// 具体重写方法, 此方法比较灵活, 可以任意设置您需要创建的格式, 比如更复杂的表格
 3     /// 另外, 可以直接从第二个参数中取得控件对象引用
 4     /// 

 5       ///  
 6       ///  
 7       protected   void  GridViewExpend1_RebuildHeader( object  sender, EventArgs e)
 8      {
 9           // 取得参数e中包含的对象的引用        
10          GridViewFixedMultiHeader currentGVE  =  ((RebuildHeaderEventArgs)e).GridViewObject;   // 到操作当前GridView的对象引用
11          GridViewRow currentHeaderRow  =  ((RebuildHeaderEventArgs)e).HeaderRowObject;  /// /到操作当前GridView's HeaderRow的对象引用
12 
13 
14           ///
15           /// /在当前HeaderRow上面增加一行
16           // 创建一个行并设置与GridViewExtend当前的头类型风格一致
17          GridViewRow willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
18          willAddHeaderRow.Font.Bold  =   true ;
19          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
20          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
21          TableCell cell  =   new  TableCell();
22          cell.Text  =   " Number " ;
23          cell.HorizontalAlign  =  HorizontalAlign.Center;
24          willAddHeaderRow.Cells.Add(cell);
25          cell  =   new  TableCell();
26          cell.Text  =   " Detail " ;
27          cell.ColumnSpan  =   2 ;
28          cell.HorizontalAlign  =  HorizontalAlign.Center;
29          willAddHeaderRow.Cells.Add(cell);
30           // 添加到GridView
31          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);
32 
33 
34           ///
35           /// /在当前HeaderRow上面再增加一行
36           // 同样创建一个行并设置与GridViewExtend当前的头类型风格一致
37          willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
38          willAddHeaderRow.Font.Bold  =   true ;
39          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
40          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
41 
42          cell  =   new  TableCell();
43          cell.Text  =   " Fruits category information " ;
44          cell.ColumnSpan  =   3 ;
45          cell.HorizontalAlign  =  HorizontalAlign.Center;
46          willAddHeaderRow.Cells.Add(cell);
47           // 添加到GridView
48          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);  
49       
50           // 还可以继续增加N个表头行;
51           // 不管增加多么, GridView控件都能够自动检测到HeaderRow的个数, 并且能够正确呈现滚动条
52           // ..;  
53           // ..; 
54      }

 

(五). 示例代码下载

        http://www.cnblogs.com/Files/MVP33650/extendgridviewfixedmultiheader.rar

 

(六). 控件开发其它相关文章:

        http://blog.youkuaiyun.com/ChengKing/category/288694.aspx

 

 

 

 

 

 

  


(一). 概述

        1. 实现GridView表头固定表体滚动效果

        2. 继承GridView的所有功能, 增加扩展功能, 表体滚动功能; 不需要另外加辅助滚动控件, 如

.

        3. 支持多行表头滚动, 此控件能够自动检测到使用者增加的表头的行数. 准确的实现表头滚动.

            有增加GridView多表头实现方案, 请看[多表头自定义控件]. 

实现原理:
    一般要实现GridView表头固定,表体滚动功能时,都是自己增加一个
控件,
然后将GridView嵌套在这个
控件里面;使用这个GridView控件就不用在页面中自己
增加个
控件了,因为它自动完成了增加
控件的功能, 具有通用性 .

(二). 运行如图

      1.  单行表头增加自动滚动效果

 

      2.  多行表头增加自动滚动效果

  

 

(三). 用法

   1. 将GridViewExpendHeader控件Dll添加引用到Web站点工程中

   2. 从工具箱拖动一个GridViewExpendHeader控件到设计器中

   3. 设置GridViewExpendHeader控件的属性.

                a.  设置属性窗口中新增的 "扩展" 类别中的两个属性,  这两个属性是指滚动区域的大小, 如下图所示:

                        

               b.  设置GridView本身的高度Height, 这个高度是指滚动区域内的GridView的实际高度, 这个高度数值设置

                     要大于ScrollHeight滚动条才能够呈现.  简单地说, 本自定义控件自动会实现一个GridView(自己)

                    的父控件

,  然后再把自己放在里面,  如果自己高度小于
高度了,  不用滚动就能够显示

                    全自己的数据, 滚动条就没有呈现的意义了.   这里讲得有点啰嗦.   .        

   4. F5运行即可

(四). 完整代码

    1. 主控件GridViewFixedMultiHeader类代码    

  1       ///   < summary >
  2       ///  Author: [ ChengKing(ZhengJian) ] 
  3       ///  Blog:   Http: // blog.youkuaiyun.com / ChengKing
  4       ///   Date :    2007 / 4 / 3
  5       ///   summary>    
  6     /// <summary>
  7     /// 主控件类, 继承GridView的所有功能
  8     ///  summary>
  9     [ToolboxData("<{0}:GridViewExpendHeader runat=server> ")]
 10     public class GridViewFixedMultiHeader : GridView 
 11     {       
 12         [Description("当需要重新构造Header时触发此事件")]
 13         public event System.EventHandler RebuildHeader;
 14 
 15         private System.Web.UI.WebControls.Panel pnlScroll = new System.Web.UI.WebControls.Panel();
 16 
 17         #region 扩展
 18         /// <summary>
 19         /// 设定滚动容器的宽度
 20         ///  summary>
 21         [Bindable(true)]
 22         [Category("扩展")]
 23         [DefaultValue("500px")]
 24         [Localizable(true)]
 25         [TypeConverter(typeof(UnitConverter))]
 26         public Unit ScrollWidth
 27         {
 28             get
 29             {
 30                 return pnlScroll.Width;
 31             }
 32             set
 33             {
 34                 pnlScroll.Width = value;
 35             }
 36         }
 37 
 38         /// <summary>
 39         /// 设定滚动容器的高度
 40         ///  summary>
 41         [Bindable(true)]
 42         [Category("扩展")]
 43         [DefaultValue("150px")]
 44         [Localizable(true)]
 45         [TypeConverter(typeof(UnitConverter))]
 46         public Unit ScrollHeight
 47         {
 48             get
 49             {
 50                 return pnlScroll.Height;
 51             }
 52             set
 53             {
 54                 pnlScroll.Height = value;
 55             }
 56         }
 57         #endregion
 58 
 59         protected override void OnPreRender(EventArgs e)
 60         {
 61             
 62             StringBuilder sb = new StringBuilder();              
 63             sb.Append(" function Tidy()");
 64             sb.Append(" {");
 65             sb.Append("     var gve = document.getElementById(/""+ this.UniqueID +"/"); ");            
 66             sb.Append("     if( gve.rows.length > 0 )");
 67             sb.Append("     {");
 68             sb.Append("         var a1 = document.getElementById(/"divHeaderContainer/");");
 69             sb.Append("         var table1 = document.createElement(/"table/");");
 70             sb.Append("         var tbody1 = document.createElement(/"tbody/");");
 71             sb.Append("         table1.style.cssText = /"table-layout:fixed;border-style: solid ;border-color:gray; border-width: 1px thin;/";   ");
 72             //sb.Append("         table1.style.cssText = /"table-layout:fixed;color:#CCCCFF;background-color:#003399;font-weight:bold;/";");
 73             sb.Append("         var i;");
 74             sb.Append("         var blnIfFind = false;");
 75             sb.Append("         for( i = gve.rows.length - 1; i >= 0; i-- )");
 76             sb.Append("         {");
 77             sb.Append("             if( gve.rows[i].children(0).tagName.toUpperCase() != /"TH/" && blnIfFind == false )  ");
 78             sb.Append("             {");
 79             sb.Append("                 continue;");
 80             sb.Append("             }");
 81             sb.Append("             if( blnIfFind == false )");
 82             sb.Append("             {");
 83             sb.Append("                 blnIfFind = true; ");
 84             sb.Append("             }");
 85             sb.Append("             if( tbody1.children.length == 0 )");
 86             sb.Append("             {");
 87             sb.Append("                 var newRow = gve.rows[i].cloneNode(true); ");
 88             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");            
 89             sb.Append("                 tbody1.appendChild( newRow ); ");
 90             sb.Append("             }");
 91             sb.Append("             else");
 92             sb.Append("             {");
 93             sb.Append("                 var newRow = gve.rows[i].cloneNode(true);   ");
 94             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");
 95             sb.Append("                 tbody1.insertBefore( newRow , tbody1.firstChild );");
 96             sb.Append("             }");
 97             sb.Append("         }");
 98             sb.Append("         table1.appendChild(tbody1);");
 99             sb.Append("         a1.appendChild(table1); ");
100             sb.Append("         for( i = 0; i < gve.rows.length -1; i++)");
101             sb.Append("         {");
102             sb.Append("             if( gve.rows[0].children(0).tagName.toUpperCase() != /"TH/" )");
103             sb.Append("             {");
104             sb.Append("                 gve.deleteRow(0);   ");
105             sb.Append("                 continue;");
106             sb.Append("             }");
107             sb.Append("             gve.deleteRow(0);   ");
108             sb.Append("             break; ");
109             sb.Append("         }");
110             sb.Append("     }");
111             sb.Append(" }");
112 
113             if (!Page.ClientScript.IsClientScriptBlockRegistered("Tidy"))
114             {
115                 Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Tidy", sb.ToString(),true);
116             }
117 
118             if (!Page.ClientScript.IsStartupScriptRegistered("Init"))
119             {
120                 Page.ClientScript.RegisterStartupScript(this.GetType(), "Init""<script type=/"text/javascript/">window.onload = Tidy;</script> "false);
121             }
122 
123             base.OnPreRender(e);
124         }
125 
126         protected override void Render(HtmlTextWriter writer)
127         {
128             OnRebuildHeader();         
129             base.Render(writer);
130         }
131         protected override void CreateChildControls()
132         {
133             Control parent = this.Parent;
134 
135             if (DesignMode == false)
136             {
137                 //生成头容器<DIV>
138                 System.Web.UI.HtmlControls.HtmlGenericControl div = new System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
139                 div.ID = "divHeaderContainer";
140                 div.Style.Add("width", this.Width.ToString());
141                 parent.Controls.Add(div);
142 
143                 Control gridView = this;
144                 parent.Controls.Remove(gridView);
145                  
146                 pnlScroll.Style.Add("width", this.Width.ToString());
147                 pnlScroll.Style.Add("OVERFLOW-Y""scroll");
148                 pnlScroll.Style.Add("OVERFLOW-X""hidden");
149        
150                 pnlScroll.Controls.Add(this);
151                 parent.Controls.Add(pnlScroll);
152 
153                 ChildControlsCreated = true;
154             }
155 
156             base.CreateChildControls();            
157         }
158     
159         protected virtual void OnRebuildHeader()
160         {
161             //重新构造Head
162             if (RebuildHeader != null)
163             {
164                 RebuildHeaderEventArgs args = new RebuildHeaderEventArgs();
165                 args.GridViewObject = this;
166                 args.HeaderRowObject = this.HeaderRow;
167 
168                 RebuildHeader(this, args);
169             }
170             
171         }       
172     } 

    2. 文件RebuildHeaderEventArgs.cs 代码

 1  ///  
 2     /// Author: [ ChengKing(ZhengJian) ] 
 3     /// Blog:   Http://blog.youkuaiyun.com/ChengKing
 4     /// Date:   2007/4/3
 5     /// 

 6       ///  
 7     /// 承载重构Header事件所需的参数[Author:ChengKing(ZhengJian)]
 8     /// 

 9       public   class  RebuildHeaderEventArgs : EventArgs
10      {
11           private  GridViewFixedMultiHeader _GridViewObject;
12           private  GridViewRow _HeaderRowObject;
13 
14           ///  
15         /// 存储GrivViewExtend对象本身
16         /// 

17           public  GridViewFixedMultiHeader GridViewObject
18          {
19               get
20              {
21                   return  _GridViewObject;
22              }
23               set
24              {
25                  _GridViewObject  =  value;
26              }
27          }
28 
29           ///  
30         /// 存储GrivViewExtend的HeaderRow对象
31         /// 

32           public  GridViewRow HeaderRowObject
33          {
34               get
35              {
36                   return  _HeaderRowObject;
37              }
38               set
39              {
40                  _HeaderRowObject  =  value;
41              }
42          }
43      }

   3. 测试页面文件default.aspx代码, 直接拖动一个控件到设计器就OK了. 不需要设置任何属性.

1 <div>
2    <asp:GridView ID="GridViewFixedMultiHeader1" runat="server"  asp:GridView>                  
3  div>

   4. 在新增自定义事件中增加表头行代码, 这里增加三行表头HeaderRow.
 1  ///  
 2     /// 具体重写方法, 此方法比较灵活, 可以任意设置您需要创建的格式, 比如更复杂的表格
 3     /// 另外, 可以直接从第二个参数中取得控件对象引用
 4     /// 

 5       ///  
 6       ///  
 7       protected   void  GridViewExpend1_RebuildHeader( object  sender, EventArgs e)
 8      {
 9           // 取得参数e中包含的对象的引用        
10          GridViewFixedMultiHeader currentGVE  =  ((RebuildHeaderEventArgs)e).GridViewObject;   // 到操作当前GridView的对象引用
11          GridViewRow currentHeaderRow  =  ((RebuildHeaderEventArgs)e).HeaderRowObject;  /// /到操作当前GridView's HeaderRow的对象引用
12 
13 
14           ///
15           /// /在当前HeaderRow上面增加一行
16           // 创建一个行并设置与GridViewExtend当前的头类型风格一致
17          GridViewRow willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
18          willAddHeaderRow.Font.Bold  =   true ;
19          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
20          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
21          TableCell cell  =   new  TableCell();
22          cell.Text  =   " Number " ;
23          cell.HorizontalAlign  =  HorizontalAlign.Center;
24          willAddHeaderRow.Cells.Add(cell);
25          cell  =   new  TableCell();
26          cell.Text  =   " Detail " ;
27          cell.ColumnSpan  =   2 ;
28          cell.HorizontalAlign  =  HorizontalAlign.Center;
29          willAddHeaderRow.Cells.Add(cell);
30           // 添加到GridView
31          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);
32 
33 
34           ///
35           /// /在当前HeaderRow上面再增加一行
36           // 同样创建一个行并设置与GridViewExtend当前的头类型风格一致
37          willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
38          willAddHeaderRow.Font.Bold  =   true ;
39          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
40          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
41 
42          cell  =   new  TableCell();
43          cell.Text  =   " Fruits category information " ;
44          cell.ColumnSpan  =   3 ;
45          cell.HorizontalAlign  =  HorizontalAlign.Center;
46          willAddHeaderRow.Cells.Add(cell);
47           // 添加到GridView
48          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);  
49       
50           // 还可以继续增加N个表头行;
51           // 不管增加多么, GridView控件都能够自动检测到HeaderRow的个数, 并且能够正确呈现滚动条
52           // ..;  
53           // ..; 
54      }

 

(五). 示例代码下载

        http://www.cnblogs.com/Files/MVP33650/extendgridviewfixedmultiheader.rar

 

(六). 控件开发其它相关文章:

        http://blog.youkuaiyun.com/ChengKing/category/288694.aspx

 

 

 

 

 

 

  


(一). 概述

        1. 实现GridView表头固定表体滚动效果

        2. 继承GridView的所有功能, 增加扩展功能, 表体滚动功能; 不需要另外加辅助滚动控件, 如

.

        3. 支持多行表头滚动, 此控件能够自动检测到使用者增加的表头的行数. 准确的实现表头滚动.

            有增加GridView多表头实现方案, 请看[多表头自定义控件]. 

实现原理:
    一般要实现GridView表头固定,表体滚动功能时,都是自己增加一个
控件,
然后将GridView嵌套在这个
控件里面;使用这个GridView控件就不用在页面中自己
增加个
控件了,因为它自动完成了增加
控件的功能, 具有通用性 .

(二). 运行如图

      1.  单行表头增加自动滚动效果

 

      2.  多行表头增加自动滚动效果

  

 

(三). 用法

   1. 将GridViewExpendHeader控件Dll添加引用到Web站点工程中

   2. 从工具箱拖动一个GridViewExpendHeader控件到设计器中

   3. 设置GridViewExpendHeader控件的属性.

                a.  设置属性窗口中新增的 "扩展" 类别中的两个属性,  这两个属性是指滚动区域的大小, 如下图所示:

                        

               b.  设置GridView本身的高度Height, 这个高度是指滚动区域内的GridView的实际高度, 这个高度数值设置

                     要大于ScrollHeight滚动条才能够呈现.  简单地说, 本自定义控件自动会实现一个GridView(自己)

                    的父控件

,  然后再把自己放在里面,  如果自己高度小于
高度了,  不用滚动就能够显示

                    全自己的数据, 滚动条就没有呈现的意义了.   这里讲得有点啰嗦.   .        

   4. F5运行即可

(四). 完整代码

    1. 主控件GridViewFixedMultiHeader类代码    

  1       ///   < summary >
  2       ///  Author: [ ChengKing(ZhengJian) ] 
  3       ///  Blog:   Http: // blog.youkuaiyun.com / ChengKing
  4       ///   Date :    2007 / 4 / 3
  5       ///   summary>    
  6     /// <summary>
  7     /// 主控件类, 继承GridView的所有功能
  8     ///  summary>
  9     [ToolboxData("<{0}:GridViewExpendHeader runat=server> ")]
 10     public class GridViewFixedMultiHeader : GridView 
 11     {       
 12         [Description("当需要重新构造Header时触发此事件")]
 13         public event System.EventHandler RebuildHeader;
 14 
 15         private System.Web.UI.WebControls.Panel pnlScroll = new System.Web.UI.WebControls.Panel();
 16 
 17         #region 扩展
 18         /// <summary>
 19         /// 设定滚动容器的宽度
 20         ///  summary>
 21         [Bindable(true)]
 22         [Category("扩展")]
 23         [DefaultValue("500px")]
 24         [Localizable(true)]
 25         [TypeConverter(typeof(UnitConverter))]
 26         public Unit ScrollWidth
 27         {
 28             get
 29             {
 30                 return pnlScroll.Width;
 31             }
 32             set
 33             {
 34                 pnlScroll.Width = value;
 35             }
 36         }
 37 
 38         /// <summary>
 39         /// 设定滚动容器的高度
 40         ///  summary>
 41         [Bindable(true)]
 42         [Category("扩展")]
 43         [DefaultValue("150px")]
 44         [Localizable(true)]
 45         [TypeConverter(typeof(UnitConverter))]
 46         public Unit ScrollHeight
 47         {
 48             get
 49             {
 50                 return pnlScroll.Height;
 51             }
 52             set
 53             {
 54                 pnlScroll.Height = value;
 55             }
 56         }
 57         #endregion
 58 
 59         protected override void OnPreRender(EventArgs e)
 60         {
 61             
 62             StringBuilder sb = new StringBuilder();              
 63             sb.Append(" function Tidy()");
 64             sb.Append(" {");
 65             sb.Append("     var gve = document.getElementById(/""+ this.UniqueID +"/"); ");            
 66             sb.Append("     if( gve.rows.length > 0 )");
 67             sb.Append("     {");
 68             sb.Append("         var a1 = document.getElementById(/"divHeaderContainer/");");
 69             sb.Append("         var table1 = document.createElement(/"table/");");
 70             sb.Append("         var tbody1 = document.createElement(/"tbody/");");
 71             sb.Append("         table1.style.cssText = /"table-layout:fixed;border-style: solid ;border-color:gray; border-width: 1px thin;/";   ");
 72             //sb.Append("         table1.style.cssText = /"table-layout:fixed;color:#CCCCFF;background-color:#003399;font-weight:bold;/";");
 73             sb.Append("         var i;");
 74             sb.Append("         var blnIfFind = false;");
 75             sb.Append("         for( i = gve.rows.length - 1; i >= 0; i-- )");
 76             sb.Append("         {");
 77             sb.Append("             if( gve.rows[i].children(0).tagName.toUpperCase() != /"TH/" && blnIfFind == false )  ");
 78             sb.Append("             {");
 79             sb.Append("                 continue;");
 80             sb.Append("             }");
 81             sb.Append("             if( blnIfFind == false )");
 82             sb.Append("             {");
 83             sb.Append("                 blnIfFind = true; ");
 84             sb.Append("             }");
 85             sb.Append("             if( tbody1.children.length == 0 )");
 86             sb.Append("             {");
 87             sb.Append("                 var newRow = gve.rows[i].cloneNode(true); ");
 88             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");            
 89             sb.Append("                 tbody1.appendChild( newRow ); ");
 90             sb.Append("             }");
 91             sb.Append("             else");
 92             sb.Append("             {");
 93             sb.Append("                 var newRow = gve.rows[i].cloneNode(true);   ");
 94             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");
 95             sb.Append("                 tbody1.insertBefore( newRow , tbody1.firstChild );");
 96             sb.Append("             }");
 97             sb.Append("         }");
 98             sb.Append("         table1.appendChild(tbody1);");
 99             sb.Append("         a1.appendChild(table1); ");
100             sb.Append("         for( i = 0; i < gve.rows.length -1; i++)");
101             sb.Append("         {");
102             sb.Append("             if( gve.rows[0].children(0).tagName.toUpperCase() != /"TH/" )");
103             sb.Append("             {");
104             sb.Append("                 gve.deleteRow(0);   ");
105             sb.Append("                 continue;");
106             sb.Append("             }");
107             sb.Append("             gve.deleteRow(0);   ");
108             sb.Append("             break; ");
109             sb.Append("         }");
110             sb.Append("     }");
111             sb.Append(" }");
112 
113             if (!Page.ClientScript.IsClientScriptBlockRegistered("Tidy"))
114             {
115                 Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Tidy", sb.ToString(),true);
116             }
117 
118             if (!Page.ClientScript.IsStartupScriptRegistered("Init"))
119             {
120                 Page.ClientScript.RegisterStartupScript(this.GetType(), "Init""<script type=/"text/javascript/">window.onload = Tidy;</script> "false);
121             }
122 
123             base.OnPreRender(e);
124         }
125 
126         protected override void Render(HtmlTextWriter writer)
127         {
128             OnRebuildHeader();         
129             base.Render(writer);
130         }
131         protected override void CreateChildControls()
132         {
133             Control parent = this.Parent;
134 
135             if (DesignMode == false)
136             {
137                 //生成头容器<DIV>
138                 System.Web.UI.HtmlControls.HtmlGenericControl div = new System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
139                 div.ID = "divHeaderContainer";
140                 div.Style.Add("width", this.Width.ToString());
141                 parent.Controls.Add(div);
142 
143                 Control gridView = this;
144                 parent.Controls.Remove(gridView);
145                  
146                 pnlScroll.Style.Add("width", this.Width.ToString());
147                 pnlScroll.Style.Add("OVERFLOW-Y""scroll");
148                 pnlScroll.Style.Add("OVERFLOW-X""hidden");
149        
150                 pnlScroll.Controls.Add(this);
151                 parent.Controls.Add(pnlScroll);
152 
153                 ChildControlsCreated = true;
154             }
155 
156             base.CreateChildControls();            
157         }
158     
159         protected virtual void OnRebuildHeader()
160         {
161             //重新构造Head
162             if (RebuildHeader != null)
163             {
164                 RebuildHeaderEventArgs args = new RebuildHeaderEventArgs();
165                 args.GridViewObject = this;
166                 args.HeaderRowObject = this.HeaderRow;
167 
168                 RebuildHeader(this, args);
169             }
170             
171         }       
172     } 

    2. 文件RebuildHeaderEventArgs.cs 代码

 1  ///  
 2     /// Author: [ ChengKing(ZhengJian) ] 
 3     /// Blog:   Http://blog.youkuaiyun.com/ChengKing
 4     /// Date:   2007/4/3
 5     /// 

 6       ///  
 7     /// 承载重构Header事件所需的参数[Author:ChengKing(ZhengJian)]
 8     /// 

 9       public   class  RebuildHeaderEventArgs : EventArgs
10      {
11           private  GridViewFixedMultiHeader _GridViewObject;
12           private  GridViewRow _HeaderRowObject;
13 
14           ///  
15         /// 存储GrivViewExtend对象本身
16         /// 

17           public  GridViewFixedMultiHeader GridViewObject
18          {
19               get
20              {
21                   return  _GridViewObject;
22              }
23               set
24              {
25                  _GridViewObject  =  value;
26              }
27          }
28 
29           ///  
30         /// 存储GrivViewExtend的HeaderRow对象
31         /// 

32           public  GridViewRow HeaderRowObject
33          {
34               get
35              {
36                   return  _HeaderRowObject;
37              }
38               set
39              {
40                  _HeaderRowObject  =  value;
41              }
42          }
43      }

   3. 测试页面文件default.aspx代码, 直接拖动一个控件到设计器就OK了. 不需要设置任何属性.

1 <div>
2    <asp:GridView ID="GridViewFixedMultiHeader1" runat="server"  asp:GridView>                  
3  div>

   4. 在新增自定义事件中增加表头行代码, 这里增加三行表头HeaderRow.
 1  ///  
 2     /// 具体重写方法, 此方法比较灵活, 可以任意设置您需要创建的格式, 比如更复杂的表格
 3     /// 另外, 可以直接从第二个参数中取得控件对象引用
 4     /// 

 5       ///  
 6       ///  
 7       protected   void  GridViewExpend1_RebuildHeader( object  sender, EventArgs e)
 8      {
 9           // 取得参数e中包含的对象的引用        
10          GridViewFixedMultiHeader currentGVE  =  ((RebuildHeaderEventArgs)e).GridViewObject;   // 到操作当前GridView的对象引用
11          GridViewRow currentHeaderRow  =  ((RebuildHeaderEventArgs)e).HeaderRowObject;  /// /到操作当前GridView's HeaderRow的对象引用
12 
13 
14           ///
15           /// /在当前HeaderRow上面增加一行
16           // 创建一个行并设置与GridViewExtend当前的头类型风格一致
17          GridViewRow willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
18          willAddHeaderRow.Font.Bold  =   true ;
19          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
20          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
21          TableCell cell  =   new  TableCell();
22          cell.Text  =   " Number " ;
23          cell.HorizontalAlign  =  HorizontalAlign.Center;
24          willAddHeaderRow.Cells.Add(cell);
25          cell  =   new  TableCell();
26          cell.Text  =   " Detail " ;
27          cell.ColumnSpan  =   2 ;
28          cell.HorizontalAlign  =  HorizontalAlign.Center;
29          willAddHeaderRow.Cells.Add(cell);
30           // 添加到GridView
31          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);
32 
33 
34           ///
35           /// /在当前HeaderRow上面再增加一行
36           // 同样创建一个行并设置与GridViewExtend当前的头类型风格一致
37          willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
38          willAddHeaderRow.Font.Bold  =   true ;
39          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
40          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
41 
42          cell  =   new  TableCell();
43          cell.Text  =   " Fruits category information " ;
44          cell.ColumnSpan  =   3 ;
45          cell.HorizontalAlign  =  HorizontalAlign.Center;
46          willAddHeaderRow.Cells.Add(cell);
47           // 添加到GridView
48          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);  
49       
50           // 还可以继续增加N个表头行;
51           // 不管增加多么, GridView控件都能够自动检测到HeaderRow的个数, 并且能够正确呈现滚动条
52           // ..;  
53           // ..; 
54      }

 

(五). 示例代码下载

        http://www.cnblogs.com/Files/MVP33650/extendgridviewfixedmultiheader.rar

 

(六). 控件开发其它相关文章:

        http://blog.youkuaiyun.com/ChengKing/category/288694.aspx

 

 

 

 

 

 

  


(一). 概述

        1. 实现GridView表头固定表体滚动效果

        2. 继承GridView的所有功能, 增加扩展功能, 表体滚动功能; 不需要另外加辅助滚动控件, 如

.

        3. 支持多行表头滚动, 此控件能够自动检测到使用者增加的表头的行数. 准确的实现表头滚动.

            有增加GridView多表头实现方案, 请看[多表头自定义控件]. 

实现原理:
    一般要实现GridView表头固定,表体滚动功能时,都是自己增加一个
控件,
然后将GridView嵌套在这个
控件里面;使用这个GridView控件就不用在页面中自己
增加个
控件了,因为它自动完成了增加
控件的功能, 具有通用性 .

(二). 运行如图

      1.  单行表头增加自动滚动效果

 

      2.  多行表头增加自动滚动效果

  

 

(三). 用法

   1. 将GridViewExpendHeader控件Dll添加引用到Web站点工程中

   2. 从工具箱拖动一个GridViewExpendHeader控件到设计器中

   3. 设置GridViewExpendHeader控件的属性.

                a.  设置属性窗口中新增的 "扩展" 类别中的两个属性,  这两个属性是指滚动区域的大小, 如下图所示:

                        

               b.  设置GridView本身的高度Height, 这个高度是指滚动区域内的GridView的实际高度, 这个高度数值设置

                     要大于ScrollHeight滚动条才能够呈现.  简单地说, 本自定义控件自动会实现一个GridView(自己)

                    的父控件

,  然后再把自己放在里面,  如果自己高度小于
高度了,  不用滚动就能够显示

                    全自己的数据, 滚动条就没有呈现的意义了.   这里讲得有点啰嗦.   .        

   4. F5运行即可

(四). 完整代码

    1. 主控件GridViewFixedMultiHeader类代码    

  1       ///   < summary >
  2       ///  Author: [ ChengKing(ZhengJian) ] 
  3       ///  Blog:   Http: // blog.youkuaiyun.com / ChengKing
  4       ///   Date :    2007 / 4 / 3
  5       ///   summary>    
  6     /// <summary>
  7     /// 主控件类, 继承GridView的所有功能
  8     ///  summary>
  9     [ToolboxData("<{0}:GridViewExpendHeader runat=server> ")]
 10     public class GridViewFixedMultiHeader : GridView 
 11     {       
 12         [Description("当需要重新构造Header时触发此事件")]
 13         public event System.EventHandler RebuildHeader;
 14 
 15         private System.Web.UI.WebControls.Panel pnlScroll = new System.Web.UI.WebControls.Panel();
 16 
 17         #region 扩展
 18         /// <summary>
 19         /// 设定滚动容器的宽度
 20         ///  summary>
 21         [Bindable(true)]
 22         [Category("扩展")]
 23         [DefaultValue("500px")]
 24         [Localizable(true)]
 25         [TypeConverter(typeof(UnitConverter))]
 26         public Unit ScrollWidth
 27         {
 28             get
 29             {
 30                 return pnlScroll.Width;
 31             }
 32             set
 33             {
 34                 pnlScroll.Width = value;
 35             }
 36         }
 37 
 38         /// <summary>
 39         /// 设定滚动容器的高度
 40         ///  summary>
 41         [Bindable(true)]
 42         [Category("扩展")]
 43         [DefaultValue("150px")]
 44         [Localizable(true)]
 45         [TypeConverter(typeof(UnitConverter))]
 46         public Unit ScrollHeight
 47         {
 48             get
 49             {
 50                 return pnlScroll.Height;
 51             }
 52             set
 53             {
 54                 pnlScroll.Height = value;
 55             }
 56         }
 57         #endregion
 58 
 59         protected override void OnPreRender(EventArgs e)
 60         {
 61             
 62             StringBuilder sb = new StringBuilder();              
 63             sb.Append(" function Tidy()");
 64             sb.Append(" {");
 65             sb.Append("     var gve = document.getElementById(/""+ this.UniqueID +"/"); ");            
 66             sb.Append("     if( gve.rows.length > 0 )");
 67             sb.Append("     {");
 68             sb.Append("         var a1 = document.getElementById(/"divHeaderContainer/");");
 69             sb.Append("         var table1 = document.createElement(/"table/");");
 70             sb.Append("         var tbody1 = document.createElement(/"tbody/");");
 71             sb.Append("         table1.style.cssText = /"table-layout:fixed;border-style: solid ;border-color:gray; border-width: 1px thin;/";   ");
 72             //sb.Append("         table1.style.cssText = /"table-layout:fixed;color:#CCCCFF;background-color:#003399;font-weight:bold;/";");
 73             sb.Append("         var i;");
 74             sb.Append("         var blnIfFind = false;");
 75             sb.Append("         for( i = gve.rows.length - 1; i >= 0; i-- )");
 76             sb.Append("         {");
 77             sb.Append("             if( gve.rows[i].children(0).tagName.toUpperCase() != /"TH/" && blnIfFind == false )  ");
 78             sb.Append("             {");
 79             sb.Append("                 continue;");
 80             sb.Append("             }");
 81             sb.Append("             if( blnIfFind == false )");
 82             sb.Append("             {");
 83             sb.Append("                 blnIfFind = true; ");
 84             sb.Append("             }");
 85             sb.Append("             if( tbody1.children.length == 0 )");
 86             sb.Append("             {");
 87             sb.Append("                 var newRow = gve.rows[i].cloneNode(true); ");
 88             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");            
 89             sb.Append("                 tbody1.appendChild( newRow ); ");
 90             sb.Append("             }");
 91             sb.Append("             else");
 92             sb.Append("             {");
 93             sb.Append("                 var newRow = gve.rows[i].cloneNode(true);   ");
 94             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");
 95             sb.Append("                 tbody1.insertBefore( newRow , tbody1.firstChild );");
 96             sb.Append("             }");
 97             sb.Append("         }");
 98             sb.Append("         table1.appendChild(tbody1);");
 99             sb.Append("         a1.appendChild(table1); ");
100             sb.Append("         for( i = 0; i < gve.rows.length -1; i++)");
101             sb.Append("         {");
102             sb.Append("             if( gve.rows[0].children(0).tagName.toUpperCase() != /"TH/" )");
103             sb.Append("             {");
104             sb.Append("                 gve.deleteRow(0);   ");
105             sb.Append("                 continue;");
106             sb.Append("             }");
107             sb.Append("             gve.deleteRow(0);   ");
108             sb.Append("             break; ");
109             sb.Append("         }");
110             sb.Append("     }");
111             sb.Append(" }");
112 
113             if (!Page.ClientScript.IsClientScriptBlockRegistered("Tidy"))
114             {
115                 Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Tidy", sb.ToString(),true);
116             }
117 
118             if (!Page.ClientScript.IsStartupScriptRegistered("Init"))
119             {
120                 Page.ClientScript.RegisterStartupScript(this.GetType(), "Init""<script type=/"text/javascript/">window.onload = Tidy;</script> "false);
121             }
122 
123             base.OnPreRender(e);
124         }
125 
126         protected override void Render(HtmlTextWriter writer)
127         {
128             OnRebuildHeader();         
129             base.Render(writer);
130         }
131         protected override void CreateChildControls()
132         {
133             Control parent = this.Parent;
134 
135             if (DesignMode == false)
136             {
137                 //生成头容器<DIV>
138                 System.Web.UI.HtmlControls.HtmlGenericControl div = new System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
139                 div.ID = "divHeaderContainer";
140                 div.Style.Add("width", this.Width.ToString());
141                 parent.Controls.Add(div);
142 
143                 Control gridView = this;
144                 parent.Controls.Remove(gridView);
145                  
146                 pnlScroll.Style.Add("width", this.Width.ToString());
147                 pnlScroll.Style.Add("OVERFLOW-Y""scroll");
148                 pnlScroll.Style.Add("OVERFLOW-X""hidden");
149        
150                 pnlScroll.Controls.Add(this);
151                 parent.Controls.Add(pnlScroll);
152 
153                 ChildControlsCreated = true;
154             }
155 
156             base.CreateChildControls();            
157         }
158     
159         protected virtual void OnRebuildHeader()
160         {
161             //重新构造Head
162             if (RebuildHeader != null)
163             {
164                 RebuildHeaderEventArgs args = new RebuildHeaderEventArgs();
165                 args.GridViewObject = this;
166                 args.HeaderRowObject = this.HeaderRow;
167 
168                 RebuildHeader(this, args);
169             }
170             
171         }       
172     } 

    2. 文件RebuildHeaderEventArgs.cs 代码

 1  ///  
 2     /// Author: [ ChengKing(ZhengJian) ] 
 3     /// Blog:   Http://blog.youkuaiyun.com/ChengKing
 4     /// Date:   2007/4/3
 5     /// 

 6       ///  
 7     /// 承载重构Header事件所需的参数[Author:ChengKing(ZhengJian)]
 8     /// 

 9       public   class  RebuildHeaderEventArgs : EventArgs
10      {
11           private  GridViewFixedMultiHeader _GridViewObject;
12           private  GridViewRow _HeaderRowObject;
13 
14           ///  
15         /// 存储GrivViewExtend对象本身
16         /// 

17           public  GridViewFixedMultiHeader GridViewObject
18          {
19               get
20              {
21                   return  _GridViewObject;
22              }
23               set
24              {
25                  _GridViewObject  =  value;
26              }
27          }
28 
29           ///  
30         /// 存储GrivViewExtend的HeaderRow对象
31         /// 

32           public  GridViewRow HeaderRowObject
33          {
34               get
35              {
36                   return  _HeaderRowObject;
37              }
38               set
39              {
40                  _HeaderRowObject  =  value;
41              }
42          }
43      }

   3. 测试页面文件default.aspx代码, 直接拖动一个控件到设计器就OK了. 不需要设置任何属性.

1 <div>
2    <asp:GridView ID="GridViewFixedMultiHeader1" runat="server"  asp:GridView>                  
3  div>

   4. 在新增自定义事件中增加表头行代码, 这里增加三行表头HeaderRow.
 1  ///  
 2     /// 具体重写方法, 此方法比较灵活, 可以任意设置您需要创建的格式, 比如更复杂的表格
 3     /// 另外, 可以直接从第二个参数中取得控件对象引用
 4     /// 

 5       ///  
 6       ///  
 7       protected   void  GridViewExpend1_RebuildHeader( object  sender, EventArgs e)
 8      {
 9           // 取得参数e中包含的对象的引用        
10          GridViewFixedMultiHeader currentGVE  =  ((RebuildHeaderEventArgs)e).GridViewObject;   // 到操作当前GridView的对象引用
11          GridViewRow currentHeaderRow  =  ((RebuildHeaderEventArgs)e).HeaderRowObject;  /// /到操作当前GridView's HeaderRow的对象引用
12 
13 
14           ///
15           /// /在当前HeaderRow上面增加一行
16           // 创建一个行并设置与GridViewExtend当前的头类型风格一致
17          GridViewRow willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
18          willAddHeaderRow.Font.Bold  =   true ;
19          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
20          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
21          TableCell cell  =   new  TableCell();
22          cell.Text  =   " Number " ;
23          cell.HorizontalAlign  =  HorizontalAlign.Center;
24          willAddHeaderRow.Cells.Add(cell);
25          cell  =   new  TableCell();
26          cell.Text  =   " Detail " ;
27          cell.ColumnSpan  =   2 ;
28          cell.HorizontalAlign  =  HorizontalAlign.Center;
29          willAddHeaderRow.Cells.Add(cell);
30           // 添加到GridView
31          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);
32 
33 
34           ///
35           /// /在当前HeaderRow上面再增加一行
36           // 同样创建一个行并设置与GridViewExtend当前的头类型风格一致
37          willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
38          willAddHeaderRow.Font.Bold  =   true ;
39          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
40          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
41 
42          cell  =   new  TableCell();
43          cell.Text  =   " Fruits category information " ;
44          cell.ColumnSpan  =   3 ;
45          cell.HorizontalAlign  =  HorizontalAlign.Center;
46          willAddHeaderRow.Cells.Add(cell);
47           // 添加到GridView
48          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);  
49       
50           // 还可以继续增加N个表头行;
51           // 不管增加多么, GridView控件都能够自动检测到HeaderRow的个数, 并且能够正确呈现滚动条
52           // ..;  
53           // ..; 
54      }

 

(五). 示例代码下载

        http://www.cnblogs.com/Files/MVP33650/extendgridviewfixedmultiheader.rar

 

(六). 控件开发其它相关文章:

        http://blog.youkuaiyun.com/ChengKing/category/288694.aspx

 

 

 

 

 

 

  


(一). 概述

        1. 实现GridView表头固定表体滚动效果

        2. 继承GridView的所有功能, 增加扩展功能, 表体滚动功能; 不需要另外加辅助滚动控件, 如

.

        3. 支持多行表头滚动, 此控件能够自动检测到使用者增加的表头的行数. 准确的实现表头滚动.

            有增加GridView多表头实现方案, 请看[多表头自定义控件]. 

实现原理:
    一般要实现GridView表头固定,表体滚动功能时,都是自己增加一个
控件,
然后将GridView嵌套在这个
控件里面;使用这个GridView控件就不用在页面中自己
增加个
控件了,因为它自动完成了增加
控件的功能, 具有通用性 .

(二). 运行如图

      1.  单行表头增加自动滚动效果

 

      2.  多行表头增加自动滚动效果

  

 

(三). 用法

   1. 将GridViewExpendHeader控件Dll添加引用到Web站点工程中

   2. 从工具箱拖动一个GridViewExpendHeader控件到设计器中

   3. 设置GridViewExpendHeader控件的属性.

                a.  设置属性窗口中新增的 "扩展" 类别中的两个属性,  这两个属性是指滚动区域的大小, 如下图所示:

                        

               b.  设置GridView本身的高度Height, 这个高度是指滚动区域内的GridView的实际高度, 这个高度数值设置

                     要大于ScrollHeight滚动条才能够呈现.  简单地说, 本自定义控件自动会实现一个GridView(自己)

                    的父控件

,  然后再把自己放在里面,  如果自己高度小于
高度了,  不用滚动就能够显示

                    全自己的数据, 滚动条就没有呈现的意义了.   这里讲得有点啰嗦.   .        

   4. F5运行即可

(四). 完整代码

    1. 主控件GridViewFixedMultiHeader类代码    

  1       ///   < summary >
  2       ///  Author: [ ChengKing(ZhengJian) ] 
  3       ///  Blog:   Http: // blog.youkuaiyun.com / ChengKing
  4       ///   Date :    2007 / 4 / 3
  5       ///   summary>    
  6     /// <summary>
  7     /// 主控件类, 继承GridView的所有功能
  8     ///  summary>
  9     [ToolboxData("<{0}:GridViewExpendHeader runat=server> ")]
 10     public class GridViewFixedMultiHeader : GridView 
 11     {       
 12         [Description("当需要重新构造Header时触发此事件")]
 13         public event System.EventHandler RebuildHeader;
 14 
 15         private System.Web.UI.WebControls.Panel pnlScroll = new System.Web.UI.WebControls.Panel();
 16 
 17         #region 扩展
 18         /// <summary>
 19         /// 设定滚动容器的宽度
 20         ///  summary>
 21         [Bindable(true)]
 22         [Category("扩展")]
 23         [DefaultValue("500px")]
 24         [Localizable(true)]
 25         [TypeConverter(typeof(UnitConverter))]
 26         public Unit ScrollWidth
 27         {
 28             get
 29             {
 30                 return pnlScroll.Width;
 31             }
 32             set
 33             {
 34                 pnlScroll.Width = value;
 35             }
 36         }
 37 
 38         /// <summary>
 39         /// 设定滚动容器的高度
 40         ///  summary>
 41         [Bindable(true)]
 42         [Category("扩展")]
 43         [DefaultValue("150px")]
 44         [Localizable(true)]
 45         [TypeConverter(typeof(UnitConverter))]
 46         public Unit ScrollHeight
 47         {
 48             get
 49             {
 50                 return pnlScroll.Height;
 51             }
 52             set
 53             {
 54                 pnlScroll.Height = value;
 55             }
 56         }
 57         #endregion
 58 
 59         protected override void OnPreRender(EventArgs e)
 60         {
 61             
 62             StringBuilder sb = new StringBuilder();              
 63             sb.Append(" function Tidy()");
 64             sb.Append(" {");
 65             sb.Append("     var gve = document.getElementById(/""+ this.UniqueID +"/"); ");            
 66             sb.Append("     if( gve.rows.length > 0 )");
 67             sb.Append("     {");
 68             sb.Append("         var a1 = document.getElementById(/"divHeaderContainer/");");
 69             sb.Append("         var table1 = document.createElement(/"table/");");
 70             sb.Append("         var tbody1 = document.createElement(/"tbody/");");
 71             sb.Append("         table1.style.cssText = /"table-layout:fixed;border-style: solid ;border-color:gray; border-width: 1px thin;/";   ");
 72             //sb.Append("         table1.style.cssText = /"table-layout:fixed;color:#CCCCFF;background-color:#003399;font-weight:bold;/";");
 73             sb.Append("         var i;");
 74             sb.Append("         var blnIfFind = false;");
 75             sb.Append("         for( i = gve.rows.length - 1; i >= 0; i-- )");
 76             sb.Append("         {");
 77             sb.Append("             if( gve.rows[i].children(0).tagName.toUpperCase() != /"TH/" && blnIfFind == false )  ");
 78             sb.Append("             {");
 79             sb.Append("                 continue;");
 80             sb.Append("             }");
 81             sb.Append("             if( blnIfFind == false )");
 82             sb.Append("             {");
 83             sb.Append("                 blnIfFind = true; ");
 84             sb.Append("             }");
 85             sb.Append("             if( tbody1.children.length == 0 )");
 86             sb.Append("             {");
 87             sb.Append("                 var newRow = gve.rows[i].cloneNode(true); ");
 88             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");            
 89             sb.Append("                 tbody1.appendChild( newRow ); ");
 90             sb.Append("             }");
 91             sb.Append("             else");
 92             sb.Append("             {");
 93             sb.Append("                 var newRow = gve.rows[i].cloneNode(true);   ");
 94             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");
 95             sb.Append("                 tbody1.insertBefore( newRow , tbody1.firstChild );");
 96             sb.Append("             }");
 97             sb.Append("         }");
 98             sb.Append("         table1.appendChild(tbody1);");
 99             sb.Append("         a1.appendChild(table1); ");
100             sb.Append("         for( i = 0; i < gve.rows.length -1; i++)");
101             sb.Append("         {");
102             sb.Append("             if( gve.rows[0].children(0).tagName.toUpperCase() != /"TH/" )");
103             sb.Append("             {");
104             sb.Append("                 gve.deleteRow(0);   ");
105             sb.Append("                 continue;");
106             sb.Append("             }");
107             sb.Append("             gve.deleteRow(0);   ");
108             sb.Append("             break; ");
109             sb.Append("         }");
110             sb.Append("     }");
111             sb.Append(" }");
112 
113             if (!Page.ClientScript.IsClientScriptBlockRegistered("Tidy"))
114             {
115                 Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Tidy", sb.ToString(),true);
116             }
117 
118             if (!Page.ClientScript.IsStartupScriptRegistered("Init"))
119             {
120                 Page.ClientScript.RegisterStartupScript(this.GetType(), "Init""<script type=/"text/javascript/">window.onload = Tidy;</script> "false);
121             }
122 
123             base.OnPreRender(e);
124         }
125 
126         protected override void Render(HtmlTextWriter writer)
127         {
128             OnRebuildHeader();         
129             base.Render(writer);
130         }
131         protected override void CreateChildControls()
132         {
133             Control parent = this.Parent;
134 
135             if (DesignMode == false)
136             {
137                 //生成头容器<DIV>
138                 System.Web.UI.HtmlControls.HtmlGenericControl div = new System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
139                 div.ID = "divHeaderContainer";
140                 div.Style.Add("width", this.Width.ToString());
141                 parent.Controls.Add(div);
142 
143                 Control gridView = this;
144                 parent.Controls.Remove(gridView);
145                  
146                 pnlScroll.Style.Add("width", this.Width.ToString());
147                 pnlScroll.Style.Add("OVERFLOW-Y""scroll");
148                 pnlScroll.Style.Add("OVERFLOW-X""hidden");
149        
150                 pnlScroll.Controls.Add(this);
151                 parent.Controls.Add(pnlScroll);
152 
153                 ChildControlsCreated = true;
154             }
155 
156             base.CreateChildControls();            
157         }
158     
159         protected virtual void OnRebuildHeader()
160         {
161             //重新构造Head
162             if (RebuildHeader != null)
163             {
164                 RebuildHeaderEventArgs args = new RebuildHeaderEventArgs();
165                 args.GridViewObject = this;
166                 args.HeaderRowObject = this.HeaderRow;
167 
168                 RebuildHeader(this, args);
169             }
170             
171         }       
172     } 

    2. 文件RebuildHeaderEventArgs.cs 代码

 1  ///  
 2     /// Author: [ ChengKing(ZhengJian) ] 
 3     /// Blog:   Http://blog.youkuaiyun.com/ChengKing
 4     /// Date:   2007/4/3
 5     /// 

 6       ///  
 7     /// 承载重构Header事件所需的参数[Author:ChengKing(ZhengJian)]
 8     /// 

 9       public   class  RebuildHeaderEventArgs : EventArgs
10      {
11           private  GridViewFixedMultiHeader _GridViewObject;
12           private  GridViewRow _HeaderRowObject;
13 
14           ///  
15         /// 存储GrivViewExtend对象本身
16         /// 

17           public  GridViewFixedMultiHeader GridViewObject
18          {
19               get
20              {
21                   return  _GridViewObject;
22              }
23               set
24              {
25                  _GridViewObject  =  value;
26              }
27          }
28 
29           ///  
30         /// 存储GrivViewExtend的HeaderRow对象
31         /// 

32           public  GridViewRow HeaderRowObject
33          {
34               get
35              {
36                   return  _HeaderRowObject;
37              }
38               set
39              {
40                  _HeaderRowObject  =  value;
41              }
42          }
43      }

   3. 测试页面文件default.aspx代码, 直接拖动一个控件到设计器就OK了. 不需要设置任何属性.

1 <div>
2    <asp:GridView ID="GridViewFixedMultiHeader1" runat="server"  asp:GridView>                  
3  div>

   4. 在新增自定义事件中增加表头行代码, 这里增加三行表头HeaderRow.
 1  ///  
 2     /// 具体重写方法, 此方法比较灵活, 可以任意设置您需要创建的格式, 比如更复杂的表格
 3     /// 另外, 可以直接从第二个参数中取得控件对象引用
 4     /// 

 5       ///  
 6       ///  
 7       protected   void  GridViewExpend1_RebuildHeader( object  sender, EventArgs e)
 8      {
 9           // 取得参数e中包含的对象的引用        
10          GridViewFixedMultiHeader currentGVE  =  ((RebuildHeaderEventArgs)e).GridViewObject;   // 到操作当前GridView的对象引用
11          GridViewRow currentHeaderRow  =  ((RebuildHeaderEventArgs)e).HeaderRowObject;  /// /到操作当前GridView's HeaderRow的对象引用
12 
13 
14           ///
15           /// /在当前HeaderRow上面增加一行
16           // 创建一个行并设置与GridViewExtend当前的头类型风格一致
17          GridViewRow willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
18          willAddHeaderRow.Font.Bold  =   true ;
19          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
20          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
21          TableCell cell  =   new  TableCell();
22          cell.Text  =   " Number " ;
23          cell.HorizontalAlign  =  HorizontalAlign.Center;
24          willAddHeaderRow.Cells.Add(cell);
25          cell  =   new  TableCell();
26          cell.Text  =   " Detail " ;
27          cell.ColumnSpan  =   2 ;
28          cell.HorizontalAlign  =  HorizontalAlign.Center;
29          willAddHeaderRow.Cells.Add(cell);
30           // 添加到GridView
31          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);
32 
33 
34           ///
35           /// /在当前HeaderRow上面再增加一行
36           // 同样创建一个行并设置与GridViewExtend当前的头类型风格一致
37          willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
38          willAddHeaderRow.Font.Bold  =   true ;
39          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
40          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
41 
42          cell  =   new  TableCell();
43          cell.Text  =   " Fruits category information " ;
44          cell.ColumnSpan  =   3 ;
45          cell.HorizontalAlign  =  HorizontalAlign.Center;
46          willAddHeaderRow.Cells.Add(cell);
47           // 添加到GridView
48          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);  
49       
50           // 还可以继续增加N个表头行;
51           // 不管增加多么, GridView控件都能够自动检测到HeaderRow的个数, 并且能够正确呈现滚动条
52           // ..;  
53           // ..; 
54      }

 

(五). 示例代码下载

        http://www.cnblogs.com/Files/MVP33650/extendgridviewfixedmultiheader.rar

 

(六). 控件开发其它相关文章:

        http://blog.youkuaiyun.com/ChengKing/category/288694.aspx

 

 

 

 

 

 

  


(一). 概述

        1. 实现GridView表头固定表体滚动效果

        2. 继承GridView的所有功能, 增加扩展功能, 表体滚动功能; 不需要另外加辅助滚动控件, 如

.

        3. 支持多行表头滚动, 此控件能够自动检测到使用者增加的表头的行数. 准确的实现表头滚动.

            有增加GridView多表头实现方案, 请看[多表头自定义控件]. 

实现原理:
    一般要实现GridView表头固定,表体滚动功能时,都是自己增加一个
控件,
然后将GridView嵌套在这个
控件里面;使用这个GridView控件就不用在页面中自己
增加个
控件了,因为它自动完成了增加
控件的功能, 具有通用性 .

(二). 运行如图

      1.  单行表头增加自动滚动效果

 

      2.  多行表头增加自动滚动效果

  

 

(三). 用法

   1. 将GridViewExpendHeader控件Dll添加引用到Web站点工程中

   2. 从工具箱拖动一个GridViewExpendHeader控件到设计器中

   3. 设置GridViewExpendHeader控件的属性.

                a.  设置属性窗口中新增的 "扩展" 类别中的两个属性,  这两个属性是指滚动区域的大小, 如下图所示:

                        

               b.  设置GridView本身的高度Height, 这个高度是指滚动区域内的GridView的实际高度, 这个高度数值设置

                     要大于ScrollHeight滚动条才能够呈现.  简单地说, 本自定义控件自动会实现一个GridView(自己)

                    的父控件

,  然后再把自己放在里面,  如果自己高度小于
高度了,  不用滚动就能够显示

                    全自己的数据, 滚动条就没有呈现的意义了.   这里讲得有点啰嗦.   .        

   4. F5运行即可

(四). 完整代码

    1. 主控件GridViewFixedMultiHeader类代码    

  1       ///   < summary >
  2       ///  Author: [ ChengKing(ZhengJian) ] 
  3       ///  Blog:   Http: // blog.youkuaiyun.com / ChengKing
  4       ///   Date :    2007 / 4 / 3
  5       ///   summary>    
  6     /// <summary>
  7     /// 主控件类, 继承GridView的所有功能
  8     ///  summary>
  9     [ToolboxData("<{0}:GridViewExpendHeader runat=server> ")]
 10     public class GridViewFixedMultiHeader : GridView 
 11     {       
 12         [Description("当需要重新构造Header时触发此事件")]
 13         public event System.EventHandler RebuildHeader;
 14 
 15         private System.Web.UI.WebControls.Panel pnlScroll = new System.Web.UI.WebControls.Panel();
 16 
 17         #region 扩展
 18         /// <summary>
 19         /// 设定滚动容器的宽度
 20         ///  summary>
 21         [Bindable(true)]
 22         [Category("扩展")]
 23         [DefaultValue("500px")]
 24         [Localizable(true)]
 25         [TypeConverter(typeof(UnitConverter))]
 26         public Unit ScrollWidth
 27         {
 28             get
 29             {
 30                 return pnlScroll.Width;
 31             }
 32             set
 33             {
 34                 pnlScroll.Width = value;
 35             }
 36         }
 37 
 38         /// <summary>
 39         /// 设定滚动容器的高度
 40         ///  summary>
 41         [Bindable(true)]
 42         [Category("扩展")]
 43         [DefaultValue("150px")]
 44         [Localizable(true)]
 45         [TypeConverter(typeof(UnitConverter))]
 46         public Unit ScrollHeight
 47         {
 48             get
 49             {
 50                 return pnlScroll.Height;
 51             }
 52             set
 53             {
 54                 pnlScroll.Height = value;
 55             }
 56         }
 57         #endregion
 58 
 59         protected override void OnPreRender(EventArgs e)
 60         {
 61             
 62             StringBuilder sb = new StringBuilder();              
 63             sb.Append(" function Tidy()");
 64             sb.Append(" {");
 65             sb.Append("     var gve = document.getElementById(/""+ this.UniqueID +"/"); ");            
 66             sb.Append("     if( gve.rows.length > 0 )");
 67             sb.Append("     {");
 68             sb.Append("         var a1 = document.getElementById(/"divHeaderContainer/");");
 69             sb.Append("         var table1 = document.createElement(/"table/");");
 70             sb.Append("         var tbody1 = document.createElement(/"tbody/");");
 71             sb.Append("         table1.style.cssText = /"table-layout:fixed;border-style: solid ;border-color:gray; border-width: 1px thin;/";   ");
 72             //sb.Append("         table1.style.cssText = /"table-layout:fixed;color:#CCCCFF;background-color:#003399;font-weight:bold;/";");
 73             sb.Append("         var i;");
 74             sb.Append("         var blnIfFind = false;");
 75             sb.Append("         for( i = gve.rows.length - 1; i >= 0; i-- )");
 76             sb.Append("         {");
 77             sb.Append("             if( gve.rows[i].children(0).tagName.toUpperCase() != /"TH/" && blnIfFind == false )  ");
 78             sb.Append("             {");
 79             sb.Append("                 continue;");
 80             sb.Append("             }");
 81             sb.Append("             if( blnIfFind == false )");
 82             sb.Append("             {");
 83             sb.Append("                 blnIfFind = true; ");
 84             sb.Append("             }");
 85             sb.Append("             if( tbody1.children.length == 0 )");
 86             sb.Append("             {");
 87             sb.Append("                 var newRow = gve.rows[i].cloneNode(true); ");
 88             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");            
 89             sb.Append("                 tbody1.appendChild( newRow ); ");
 90             sb.Append("             }");
 91             sb.Append("             else");
 92             sb.Append("             {");
 93             sb.Append("                 var newRow = gve.rows[i].cloneNode(true);   ");
 94             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");
 95             sb.Append("                 tbody1.insertBefore( newRow , tbody1.firstChild );");
 96             sb.Append("             }");
 97             sb.Append("         }");
 98             sb.Append("         table1.appendChild(tbody1);");
 99             sb.Append("         a1.appendChild(table1); ");
100             sb.Append("         for( i = 0; i < gve.rows.length -1; i++)");
101             sb.Append("         {");
102             sb.Append("             if( gve.rows[0].children(0).tagName.toUpperCase() != /"TH/" )");
103             sb.Append("             {");
104             sb.Append("                 gve.deleteRow(0);   ");
105             sb.Append("                 continue;");
106             sb.Append("             }");
107             sb.Append("             gve.deleteRow(0);   ");
108             sb.Append("             break; ");
109             sb.Append("         }");
110             sb.Append("     }");
111             sb.Append(" }");
112 
113             if (!Page.ClientScript.IsClientScriptBlockRegistered("Tidy"))
114             {
115                 Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Tidy", sb.ToString(),true);
116             }
117 
118             if (!Page.ClientScript.IsStartupScriptRegistered("Init"))
119             {
120                 Page.ClientScript.RegisterStartupScript(this.GetType(), "Init""<script type=/"text/javascript/">window.onload = Tidy;</script> "false);
121             }
122 
123             base.OnPreRender(e);
124         }
125 
126         protected override void Render(HtmlTextWriter writer)
127         {
128             OnRebuildHeader();         
129             base.Render(writer);
130         }
131         protected override void CreateChildControls()
132         {
133             Control parent = this.Parent;
134 
135             if (DesignMode == false)
136             {
137                 //生成头容器<DIV>
138                 System.Web.UI.HtmlControls.HtmlGenericControl div = new System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
139                 div.ID = "divHeaderContainer";
140                 div.Style.Add("width", this.Width.ToString());
141                 parent.Controls.Add(div);
142 
143                 Control gridView = this;
144                 parent.Controls.Remove(gridView);
145                  
146                 pnlScroll.Style.Add("width", this.Width.ToString());
147                 pnlScroll.Style.Add("OVERFLOW-Y""scroll");
148                 pnlScroll.Style.Add("OVERFLOW-X""hidden");
149        
150                 pnlScroll.Controls.Add(this);
151                 parent.Controls.Add(pnlScroll);
152 
153                 ChildControlsCreated = true;
154             }
155 
156             base.CreateChildControls();            
157         }
158     
159         protected virtual void OnRebuildHeader()
160         {
161             //重新构造Head
162             if (RebuildHeader != null)
163             {
164                 RebuildHeaderEventArgs args = new RebuildHeaderEventArgs();
165                 args.GridViewObject = this;
166                 args.HeaderRowObject = this.HeaderRow;
167 
168                 RebuildHeader(this, args);
169             }
170             
171         }       
172     } 

    2. 文件RebuildHeaderEventArgs.cs 代码

 1  ///  
 2     /// Author: [ ChengKing(ZhengJian) ] 
 3     /// Blog:   Http://blog.youkuaiyun.com/ChengKing
 4     /// Date:   2007/4/3
 5     /// 

 6       ///  
 7     /// 承载重构Header事件所需的参数[Author:ChengKing(ZhengJian)]
 8     /// 

 9       public   class  RebuildHeaderEventArgs : EventArgs
10      {
11           private  GridViewFixedMultiHeader _GridViewObject;
12           private  GridViewRow _HeaderRowObject;
13 
14           ///  
15         /// 存储GrivViewExtend对象本身
16         /// 

17           public  GridViewFixedMultiHeader GridViewObject
18          {
19               get
20              {
21                   return  _GridViewObject;
22              }
23               set
24              {
25                  _GridViewObject  =  value;
26              }
27          }
28 
29           ///  
30         /// 存储GrivViewExtend的HeaderRow对象
31         /// 

32           public  GridViewRow HeaderRowObject
33          {
34               get
35              {
36                   return  _HeaderRowObject;
37              }
38               set
39              {
40                  _HeaderRowObject  =  value;
41              }
42          }
43      }

   3. 测试页面文件default.aspx代码, 直接拖动一个控件到设计器就OK了. 不需要设置任何属性.

1 <div>
2    <asp:GridView ID="GridViewFixedMultiHeader1" runat="server"  asp:GridView>                  
3  div>

   4. 在新增自定义事件中增加表头行代码, 这里增加三行表头HeaderRow.
 1  ///  
 2     /// 具体重写方法, 此方法比较灵活, 可以任意设置您需要创建的格式, 比如更复杂的表格
 3     /// 另外, 可以直接从第二个参数中取得控件对象引用
 4     /// 

 5       ///  
 6       ///  
 7       protected   void  GridViewExpend1_RebuildHeader( object  sender, EventArgs e)
 8      {
 9           // 取得参数e中包含的对象的引用        
10          GridViewFixedMultiHeader currentGVE  =  ((RebuildHeaderEventArgs)e).GridViewObject;   // 到操作当前GridView的对象引用
11          GridViewRow currentHeaderRow  =  ((RebuildHeaderEventArgs)e).HeaderRowObject;  /// /到操作当前GridView's HeaderRow的对象引用
12 
13 
14           ///
15           /// /在当前HeaderRow上面增加一行
16           // 创建一个行并设置与GridViewExtend当前的头类型风格一致
17          GridViewRow willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
18          willAddHeaderRow.Font.Bold  =   true ;
19          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
20          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
21          TableCell cell  =   new  TableCell();
22          cell.Text  =   " Number " ;
23          cell.HorizontalAlign  =  HorizontalAlign.Center;
24          willAddHeaderRow.Cells.Add(cell);
25          cell  =   new  TableCell();
26          cell.Text  =   " Detail " ;
27          cell.ColumnSpan  =   2 ;
28          cell.HorizontalAlign  =  HorizontalAlign.Center;
29          willAddHeaderRow.Cells.Add(cell);
30           // 添加到GridView
31          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);
32 
33 
34           ///
35           /// /在当前HeaderRow上面再增加一行
36           // 同样创建一个行并设置与GridViewExtend当前的头类型风格一致
37          willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
38          willAddHeaderRow.Font.Bold  =   true ;
39          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
40          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
41 
42          cell  =   new  TableCell();
43          cell.Text  =   " Fruits category information " ;
44          cell.ColumnSpan  =   3 ;
45          cell.HorizontalAlign  =  HorizontalAlign.Center;
46          willAddHeaderRow.Cells.Add(cell);
47           // 添加到GridView
48          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);  
49       
50           // 还可以继续增加N个表头行;
51           // 不管增加多么, GridView控件都能够自动检测到HeaderRow的个数, 并且能够正确呈现滚动条
52           // ..;  
53           // ..; 
54      }

 

(五). 示例代码下载

        http://www.cnblogs.com/Files/MVP33650/extendgridviewfixedmultiheader.rar

 

(六). 控件开发其它相关文章:

        http://blog.youkuaiyun.com/ChengKing/category/288694.aspx

 

 

 

 

 

 

  


(一). 概述

        1. 实现GridView表头固定表体滚动效果

        2. 继承GridView的所有功能, 增加扩展功能, 表体滚动功能; 不需要另外加辅助滚动控件, 如

.

        3. 支持多行表头滚动, 此控件能够自动检测到使用者增加的表头的行数. 准确的实现表头滚动.

            有增加GridView多表头实现方案, 请看[多表头自定义控件]. 

实现原理:
    一般要实现GridView表头固定,表体滚动功能时,都是自己增加一个
控件,
然后将GridView嵌套在这个
控件里面; 使用这个 GridView 控件就不用在页面中自己
增加个
控件了, 因为它自动完成了增加
控件的功能, 具有通用性 .

(二). 运行如图

      1.  单行表头增加自动滚动效果

 

      2.  多行表头增加自动滚动效果

  

 

(三). 用法

   1. 将GridViewExpendHeader控件Dll添加引用到Web站点工程中

   2. 从工具箱拖动一个GridViewExpendHeader控件到设计器中

   3. 设置GridViewExpendHeader控件的属性.

                a.  设置属性窗口中新增的 "扩展" 类别中的两个属性,  这两个属性是指滚动区域的大小, 如下图所示:

                        

               b.  设置GridView本身的高度Height, 这个高度是指滚动区域内的GridView的实际高度, 这个高度数值设置

                     要大于ScrollHeight滚动条才能够呈现.  简单地说, 本自定义控件自动会实现一个GridView(自己)

                    的父控件

,  然后再把自己放在里面,  如果自己高度小于
高度了,  不用滚动就能够显示

                    全自己的数据, 滚动条就没有呈现的意义了.   这里讲得有点啰嗦.   .        

   4. F5运行即可

(四). 完整代码

    1. 主控件GridViewFixedMultiHeader类代码    

  1       ///   < summary >
  2       ///  Author: [ ChengKing(ZhengJian) ] 
  3       ///  Blog:   Http: // blog.youkuaiyun.com / ChengKing
  4       ///   Date :    2007 / 4 / 3
  5       ///   summary>    
  6     /// <summary>
  7     /// 主控件类, 继承GridView的所有功能
  8     ///  summary>
  9     [ToolboxData("<{0}:GridViewExpendHeader runat=server> ")]
 10     public class GridViewFixedMultiHeader : GridView 
 11     {       
 12         [Description("当需要重新构造Header时触发此事件")]
 13         public event System.EventHandler RebuildHeader;
 14 
 15         private System.Web.UI.WebControls.Panel pnlScroll = new System.Web.UI.WebControls.Panel();
 16 
 17         #region 扩展
 18         /// <summary>
 19         /// 设定滚动容器的宽度
 20         ///  summary>
 21         [Bindable(true)]
 22         [Category("扩展")]
 23         [DefaultValue("500px")]
 24         [Localizable(true)]
 25         [TypeConverter(typeof(UnitConverter))]
 26         public Unit ScrollWidth
 27         {
 28             get
 29             {
 30                 return pnlScroll.Width;
 31             }
 32             set
 33             {
 34                 pnlScroll.Width = value;
 35             }
 36         }
 37 
 38         /// <summary>
 39         /// 设定滚动容器的高度
 40         ///  summary>
 41         [Bindable(true)]
 42         [Category("扩展")]
 43         [DefaultValue("150px")]
 44         [Localizable(true)]
 45         [TypeConverter(typeof(UnitConverter))]
 46         public Unit ScrollHeight
 47         {
 48             get
 49             {
 50                 return pnlScroll.Height;
 51             }
 52             set
 53             {
 54                 pnlScroll.Height = value;
 55             }
 56         }
 57         #endregion
 58 
 59         protected override void OnPreRender(EventArgs e)
 60         {
 61             
 62             StringBuilder sb = new StringBuilder();              
 63             sb.Append(" function Tidy()");
 64             sb.Append(" {");
 65             sb.Append("     var gve = document.getElementById(/""+ this.UniqueID +"/"); ");            
 66             sb.Append("     if( gve.rows.length > 0 )");
 67             sb.Append("     {");
 68             sb.Append("         var a1 = document.getElementById(/"divHeaderContainer/");");
 69             sb.Append("         var table1 = document.createElement(/"table/");");
 70             sb.Append("         var tbody1 = document.createElement(/"tbody/");");
 71             sb.Append("         table1.style.cssText = /"table-layout:fixed;border-style: solid ;border-color:gray; border-width: 1px thin;/";   ");
 72             //sb.Append("         table1.style.cssText = /"table-layout:fixed;color:#CCCCFF;background-color:#003399;font-weight:bold;/";");
 73             sb.Append("         var i;");
 74             sb.Append("         var blnIfFind = false;");
 75             sb.Append("         for( i = gve.rows.length - 1; i >= 0; i-- )");
 76             sb.Append("         {");
 77             sb.Append("             if( gve.rows[i].children(0).tagName.toUpperCase() != /"TH/" && blnIfFind == false )  ");
 78             sb.Append("             {");
 79             sb.Append("                 continue;");
 80             sb.Append("             }");
 81             sb.Append("             if( blnIfFind == false )");
 82             sb.Append("             {");
 83             sb.Append("                 blnIfFind = true; ");
 84             sb.Append("             }");
 85             sb.Append("             if( tbody1.children.length == 0 )");
 86             sb.Append("             {");
 87             sb.Append("                 var newRow = gve.rows[i].cloneNode(true); ");
 88             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");            
 89             sb.Append("                 tbody1.appendChild( newRow ); ");
 90             sb.Append("             }");
 91             sb.Append("             else");
 92             sb.Append("             {");
 93             sb.Append("                 var newRow = gve.rows[i].cloneNode(true);   ");
 94             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");
 95             sb.Append("                 tbody1.insertBefore( newRow , tbody1.firstChild );");
 96             sb.Append("             }");
 97             sb.Append("         }");
 98             sb.Append("         table1.appendChild(tbody1);");
 99             sb.Append("         a1.appendChild(table1); ");
100             sb.Append("         for( i = 0; i < gve.rows.length -1; i++)");
101             sb.Append("         {");
102             sb.Append("             if( gve.rows[0].children(0).tagName.toUpperCase() != /"TH/" )");
103             sb.Append("             {");
104             sb.Append("                 gve.deleteRow(0);   ");
105             sb.Append("                 continue;");
106             sb.Append("             }");
107             sb.Append("             gve.deleteRow(0);   ");
108             sb.Append("             break; ");
109             sb.Append("         }");
110             sb.Append("     }");
111             sb.Append(" }");
112 
113             if (!Page.ClientScript.IsClientScriptBlockRegistered("Tidy"))
114             {
115                 Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Tidy", sb.ToString(),true);
116             }
117 
118             if (!Page.ClientScript.IsStartupScriptRegistered("Init"))
119             {
120                 Page.ClientScript.RegisterStartupScript(this.GetType(), "Init""<script type=/"text/javascript/">window.onload = Tidy;</script> "false);
121             }
122 
123             base.OnPreRender(e);
124         }
125 
126         protected override void Render(HtmlTextWriter writer)
127         {
128             OnRebuildHeader();         
129             base.Render(writer);
130         }
131         protected override void CreateChildControls()
132         {
133             Control parent = this.Parent;
134 
135             if (DesignMode == false)
136             {
137                 //生成头容器<DIV>
138                 System.Web.UI.HtmlControls.HtmlGenericControl div = new System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
139                 div.ID = "divHeaderContainer";
140                 div.Style.Add("width", this.Width.ToString());
141                 parent.Controls.Add(div);
142 
143                 Control gridView = this;
144                 parent.Controls.Remove(gridView);
145                  
146                 pnlScroll.Style.Add("width", this.Width.ToString());
147                 pnlScroll.Style.Add("OVERFLOW-Y""scroll");
148                 pnlScroll.Style.Add("OVERFLOW-X""hidden");
149        
150                 pnlScroll.Controls.Add(this);
151                 parent.Controls.Add(pnlScroll);
152 
153                 ChildControlsCreated = true;
154             }
155 
156             base.CreateChildControls();            
157         }
158     
159         protected virtual void OnRebuildHeader()
160         {
161             //重新构造Head
162             if (RebuildHeader != null)
163             {
164                 RebuildHeaderEventArgs args = new RebuildHeaderEventArgs();
165                 args.GridViewObject = this;
166                 args.HeaderRowObject = this.HeaderRow;
167 
168                 RebuildHeader(this, args);
169             }
170             
171         }       
172     } 

    2. 文件RebuildHeaderEventArgs.cs 代码

 1  ///  
 2     /// Author: [ ChengKing(ZhengJian) ] 
 3     /// Blog:   Http://blog.youkuaiyun.com/ChengKing
 4     /// Date:   2007/4/3
 5     /// 

 6       ///  
 7     /// 承载重构Header事件所需的参数[Author:ChengKing(ZhengJian)]
 8     /// 

 9       public   class  RebuildHeaderEventArgs : EventArgs
10      {
11           private  GridViewFixedMultiHeader _GridViewObject;
12           private  GridViewRow _HeaderRowObject;
13 
14           ///  
15         /// 存储GrivViewExtend对象本身
16         /// 

17           public  GridViewFixedMultiHeader GridViewObject
18          {
19               get
20              {
21                   return  _GridViewObject;
22              }
23               set
24              {
25                  _GridViewObject  =  value;
26              }
27          }
28 
29           ///  
30         /// 存储GrivViewExtend的HeaderRow对象
31         /// 

32           public  GridViewRow HeaderRowObject
33          {
34               get
35              {
36                   return  _HeaderRowObject;
37              }
38               set
39              {
40                  _HeaderRowObject  =  value;
41              }
42          }
43      }

   3. 测试页面文件default.aspx代码, 直接拖动一个控件到设计器就OK了. 不需要设置任何属性.

1 <div>
2    <asp:GridView ID="GridViewFixedMultiHeader1" runat="server"  asp:GridView>                  
3  div>

   4. 在新增自定义事件中增加表头行代码, 这里增加三行表头HeaderRow.
 1  ///  
 2     /// 具体重写方法, 此方法比较灵活, 可以任意设置您需要创建的格式, 比如更复杂的表格
 3     /// 另外, 可以直接从第二个参数中取得控件对象引用
 4     /// 

 5       ///  
 6       ///  
 7       protected   void  GridViewExpend1_RebuildHeader( object  sender, EventArgs e)
 8      {
 9           // 取得参数e中包含的对象的引用        
10          GridViewFixedMultiHeader currentGVE  =  ((RebuildHeaderEventArgs)e).GridViewObject;   // 到操作当前GridView的对象引用
11          GridViewRow currentHeaderRow  =  ((RebuildHeaderEventArgs)e).HeaderRowObject;  /// /到操作当前GridView's HeaderRow的对象引用
12 
13 
14           ///
15           /// /在当前HeaderRow上面增加一行
16           // 创建一个行并设置与GridViewExtend当前的头类型风格一致
17          GridViewRow willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
18          willAddHeaderRow.Font.Bold  =   true ;
19          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
20          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
21          TableCell cell  =   new  TableCell();
22          cell.Text  =   " Number " ;
23          cell.HorizontalAlign  =  HorizontalAlign.Center;
24          willAddHeaderRow.Cells.Add(cell);
25          cell  =   new  TableCell();
26          cell.Text  =   " Detail " ;
27          cell.ColumnSpan  =   2 ;
28          cell.HorizontalAlign  =  HorizontalAlign.Center;
29          willAddHeaderRow.Cells.Add(cell);
30           // 添加到GridView
31          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);
32 
33 
34           ///
35           /// /在当前HeaderRow上面再增加一行
36           // 同样创建一个行并设置与GridViewExtend当前的头类型风格一致
37          willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
38          willAddHeaderRow.Font.Bold  =   true ;
39          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
40          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
41 
42          cell  =   new  TableCell();
43          cell.Text  =   " Fruits category information " ;
44          cell.ColumnSpan  =   3 ;
45          cell.HorizontalAlign  =  HorizontalAlign.Center;
46          willAddHeaderRow.Cells.Add(cell);
47           // 添加到GridView
48          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);  
49       
50           // 还可以继续增加N个表头行;
51           // 不管增加多么, GridView控件都能够自动检测到HeaderRow的个数, 并且能够正确呈现滚动条
52           // ..;  
53           // ..; 
54      }

 

(五). 示例代码下载

        http://www.cnblogs.com/Files/MVP33650/extendgridviewfixedmultiheader.rar

 

(六). 控件开发其它相关文章:

        http://blog.youkuaiyun.com/ChengKing/category/288694.aspx

 

 

 

 

 

 

  


(一). 概述

        1. 实现GridView表头固定表体滚动效果

        2. 继承GridView的所有功能, 增加扩展功能, 表体滚动功能; 不需要另外加辅助滚动控件, 如

.

        3. 支持多行表头滚动, 此控件能够自动检测到使用者增加的表头的行数. 准确的实现表头滚动.

            有增加GridView多表头实现方案, 请看[多表头自定义控件]. 

实现原理:
    一般要实现GridView表头固定,表体滚动功能时,都是自己增加一个
控件,
然后将GridView嵌套在这个
控件里面; 使用这个 GridView 控件就不用在页面中自己
增加个
控件了, 因为它自动完成了增加
控件的功能, 具有通用性 .

(二). 运行如图

      1.  单行表头增加自动滚动效果

 

      2.  多行表头增加自动滚动效果

  

 

(三). 用法

   1. 将GridViewExpendHeader控件Dll添加引用到Web站点工程中

   2. 从工具箱拖动一个GridViewExpendHeader控件到设计器中

   3. 设置GridViewExpendHeader控件的属性.

                a.  设置属性窗口中新增的 "扩展" 类别中的两个属性,  这两个属性是指滚动区域的大小, 如下图所示:

                        

               b.  设置GridView本身的高度Height, 这个高度是指滚动区域内的GridView的实际高度, 这个高度数值设置

                     要大于ScrollHeight滚动条才能够呈现.  简单地说, 本自定义控件自动会实现一个GridView(自己)

                    的父控件

,  然后再把自己放在里面,  如果自己高度小于
高度了,  不用滚动就能够显示

                    全自己的数据, 滚动条就没有呈现的意义了.   这里讲得有点啰嗦.   .        

   4. F5运行即可

(四). 完整代码

    1. 主控件GridViewFixedMultiHeader类代码    

  1       ///   < summary >
  2       ///  Author: [ ChengKing(ZhengJian) ] 
  3       ///  Blog:   Http: // blog.youkuaiyun.com / ChengKing
  4       ///   Date :    2007 / 4 / 3
  5       ///   summary>    
  6     /// <summary>
  7     /// 主控件类, 继承GridView的所有功能
  8     ///  summary>
  9     [ToolboxData("<{0}:GridViewExpendHeader runat=server> ")]
 10     public class GridViewFixedMultiHeader : GridView 
 11     {       
 12         [Description("当需要重新构造Header时触发此事件")]
 13         public event System.EventHandler RebuildHeader;
 14 
 15         private System.Web.UI.WebControls.Panel pnlScroll = new System.Web.UI.WebControls.Panel();
 16 
 17         #region 扩展
 18         /// <summary>
 19         /// 设定滚动容器的宽度
 20         ///  summary>
 21         [Bindable(true)]
 22         [Category("扩展")]
 23         [DefaultValue("500px")]
 24         [Localizable(true)]
 25         [TypeConverter(typeof(UnitConverter))]
 26         public Unit ScrollWidth
 27         {
 28             get
 29             {
 30                 return pnlScroll.Width;
 31             }
 32             set
 33             {
 34                 pnlScroll.Width = value;
 35             }
 36         }
 37 
 38         /// <summary>
 39         /// 设定滚动容器的高度
 40         ///  summary>
 41         [Bindable(true)]
 42         [Category("扩展")]
 43         [DefaultValue("150px")]
 44         [Localizable(true)]
 45         [TypeConverter(typeof(UnitConverter))]
 46         public Unit ScrollHeight
 47         {
 48             get
 49             {
 50                 return pnlScroll.Height;
 51             }
 52             set
 53             {
 54                 pnlScroll.Height = value;
 55             }
 56         }
 57         #endregion
 58 
 59         protected override void OnPreRender(EventArgs e)
 60         {
 61             
 62             StringBuilder sb = new StringBuilder();              
 63             sb.Append(" function Tidy()");
 64             sb.Append(" {");
 65             sb.Append("     var gve = document.getElementById(/""+ this.UniqueID +"/"); ");            
 66             sb.Append("     if( gve.rows.length > 0 )");
 67             sb.Append("     {");
 68             sb.Append("         var a1 = document.getElementById(/"divHeaderContainer/");");
 69             sb.Append("         var table1 = document.createElement(/"table/");");
 70             sb.Append("         var tbody1 = document.createElement(/"tbody/");");
 71             sb.Append("         table1.style.cssText = /"table-layout:fixed;border-style: solid ;border-color:gray; border-width: 1px thin;/";   ");
 72             //sb.Append("         table1.style.cssText = /"table-layout:fixed;color:#CCCCFF;background-color:#003399;font-weight:bold;/";");
 73             sb.Append("         var i;");
 74             sb.Append("         var blnIfFind = false;");
 75             sb.Append("         for( i = gve.rows.length - 1; i >= 0; i-- )");
 76             sb.Append("         {");
 77             sb.Append("             if( gve.rows[i].children(0).tagName.toUpperCase() != /"TH/" && blnIfFind == false )  ");
 78             sb.Append("             {");
 79             sb.Append("                 continue;");
 80             sb.Append("             }");
 81             sb.Append("             if( blnIfFind == false )");
 82             sb.Append("             {");
 83             sb.Append("                 blnIfFind = true; ");
 84             sb.Append("             }");
 85             sb.Append("             if( tbody1.children.length == 0 )");
 86             sb.Append("             {");
 87             sb.Append("                 var newRow = gve.rows[i].cloneNode(true); ");
 88             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");            
 89             sb.Append("                 tbody1.appendChild( newRow ); ");
 90             sb.Append("             }");
 91             sb.Append("             else");
 92             sb.Append("             {");
 93             sb.Append("                 var newRow = gve.rows[i].cloneNode(true);   ");
 94             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");
 95             sb.Append("                 tbody1.insertBefore( newRow , tbody1.firstChild );");
 96             sb.Append("             }");
 97             sb.Append("         }");
 98             sb.Append("         table1.appendChild(tbody1);");
 99             sb.Append("         a1.appendChild(table1); ");
100             sb.Append("         for( i = 0; i < gve.rows.length -1; i++)");
101             sb.Append("         {");
102             sb.Append("             if( gve.rows[0].children(0).tagName.toUpperCase() != /"TH/" )");
103             sb.Append("             {");
104             sb.Append("                 gve.deleteRow(0);   ");
105             sb.Append("                 continue;");
106             sb.Append("             }");
107             sb.Append("             gve.deleteRow(0);   ");
108             sb.Append("             break; ");
109             sb.Append("         }");
110             sb.Append("     }");
111             sb.Append(" }");
112 
113             if (!Page.ClientScript.IsClientScriptBlockRegistered("Tidy"))
114             {
115                 Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Tidy", sb.ToString(),true);
116             }
117 
118             if (!Page.ClientScript.IsStartupScriptRegistered("Init"))
119             {
120                 Page.ClientScript.RegisterStartupScript(this.GetType(), "Init""<script type=/"text/javascript/">window.onload = Tidy;</script> "false);
121             }
122 
123             base.OnPreRender(e);
124         }
125 
126         protected override void Render(HtmlTextWriter writer)
127         {
128             OnRebuildHeader();         
129             base.Render(writer);
130         }
131         protected override void CreateChildControls()
132         {
133             Control parent = this.Parent;
134 
135             if (DesignMode == false)
136             {
137                 //生成头容器<DIV>
138                 System.Web.UI.HtmlControls.HtmlGenericControl div = new System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
139                 div.ID = "divHeaderContainer";
140                 div.Style.Add("width", this.Width.ToString());
141                 parent.Controls.Add(div);
142 
143                 Control gridView = this;
144                 parent.Controls.Remove(gridView);
145                  
146                 pnlScroll.Style.Add("width", this.Width.ToString());
147                 pnlScroll.Style.Add("OVERFLOW-Y""scroll");
148                 pnlScroll.Style.Add("OVERFLOW-X""hidden");
149        
150                 pnlScroll.Controls.Add(this);
151                 parent.Controls.Add(pnlScroll);
152 
153                 ChildControlsCreated = true;
154             }
155 
156             base.CreateChildControls();            
157         }
158     
159         protected virtual void OnRebuildHeader()
160         {
161             //重新构造Head
162             if (RebuildHeader != null)
163             {
164                 RebuildHeaderEventArgs args = new RebuildHeaderEventArgs();
165                 args.GridViewObject = this;
166                 args.HeaderRowObject = this.HeaderRow;
167 
168                 RebuildHeader(this, args);
169             }
170             
171         }       
172     } 

    2. 文件RebuildHeaderEventArgs.cs 代码

 1  ///  
 2     /// Author: [ ChengKing(ZhengJian) ] 
 3     /// Blog:   Http://blog.youkuaiyun.com/ChengKing
 4     /// Date:   2007/4/3
 5     /// 

 6       ///  
 7     /// 承载重构Header事件所需的参数[Author:ChengKing(ZhengJian)]
 8     /// 

 9       public   class  RebuildHeaderEventArgs : EventArgs
10      {
11           private  GridViewFixedMultiHeader _GridViewObject;
12           private  GridViewRow _HeaderRowObject;
13 
14           ///  
15         /// 存储GrivViewExtend对象本身
16         /// 

17           public  GridViewFixedMultiHeader GridViewObject
18          {
19               get
20              {
21                   return  _GridViewObject;
22              }
23               set
24              {
25                  _GridViewObject  =  value;
26              }
27          }
28 
29           ///  
30         /// 存储GrivViewExtend的HeaderRow对象
31         /// 

32           public  GridViewRow HeaderRowObject
33          {
34               get
35              {
36                   return  _HeaderRowObject;
37              }
38               set
39              {
40                  _HeaderRowObject  =  value;
41              }
42          }
43      }

   3. 测试页面文件default.aspx代码, 直接拖动一个控件到设计器就OK了. 不需要设置任何属性.

1 <div>
2    <asp:GridView ID="GridViewFixedMultiHeader1" runat="server"  asp:GridView>                  
3  div>

   4. 在新增自定义事件中增加表头行代码, 这里增加三行表头HeaderRow.
 1  ///  
 2     /// 具体重写方法, 此方法比较灵活, 可以任意设置您需要创建的格式, 比如更复杂的表格
 3     /// 另外, 可以直接从第二个参数中取得控件对象引用
 4     /// 

 5       ///  
 6       ///  
 7       protected   void  GridViewExpend1_RebuildHeader( object  sender, EventArgs e)
 8      {
 9           // 取得参数e中包含的对象的引用        
10          GridViewFixedMultiHeader currentGVE  =  ((RebuildHeaderEventArgs)e).GridViewObject;   // 到操作当前GridView的对象引用
11          GridViewRow currentHeaderRow  =  ((RebuildHeaderEventArgs)e).HeaderRowObject;  /// /到操作当前GridView's HeaderRow的对象引用
12 
13 
14           ///
15           /// /在当前HeaderRow上面增加一行
16           // 创建一个行并设置与GridViewExtend当前的头类型风格一致
17          GridViewRow willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
18          willAddHeaderRow.Font.Bold  =   true ;
19          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
20          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
21          TableCell cell  =   new  TableCell();
22          cell.Text  =   " Number " ;
23          cell.HorizontalAlign  =  HorizontalAlign.Center;
24          willAddHeaderRow.Cells.Add(cell);
25          cell  =   new  TableCell();
26          cell.Text  =   " Detail " ;
27          cell.ColumnSpan  =   2 ;
28          cell.HorizontalAlign  =  HorizontalAlign.Center;
29          willAddHeaderRow.Cells.Add(cell);
30           // 添加到GridView
31          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);
32 
33 
34           ///
35           /// /在当前HeaderRow上面再增加一行
36           // 同样创建一个行并设置与GridViewExtend当前的头类型风格一致
37          willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
38          willAddHeaderRow.Font.Bold  =   true ;
39          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
40          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
41 
42          cell  =   new  TableCell();
43          cell.Text  =   " Fruits category information " ;
44          cell.ColumnSpan  =   3 ;
45          cell.HorizontalAlign  =  HorizontalAlign.Center;
46          willAddHeaderRow.Cells.Add(cell);
47           // 添加到GridView
48          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);  
49       
50           // 还可以继续增加N个表头行;
51           // 不管增加多么, GridView控件都能够自动检测到HeaderRow的个数, 并且能够正确呈现滚动条
52           // ..;  
53           // ..; 
54      }

 

(五). 示例代码下载

        http://www.cnblogs.com/Files/MVP33650/extendgridviewfixedmultiheader.rar

 

(六). 控件开发其它相关文章:

        http://blog.youkuaiyun.com/ChengKing/category/288694.aspx

 

 

 

 

 

 

  


(一). 概述

        1. 实现GridView表头固定表体滚动效果

        2. 继承GridView的所有功能, 增加扩展功能, 表体滚动功能; 不需要另外加辅助滚动控件, 如

.

        3. 支持多行表头滚动, 此控件能够自动检测到使用者增加的表头的行数. 准确的实现表头滚动.

            有增加GridView多表头实现方案, 请看[多表头自定义控件]. 

实现原理:
    一般要实现GridView表头固定,表体滚动功能时,都是自己增加一个
控件,
然后将GridView嵌套在这个
控件里面; 使用这个 GridView 控件就不用在页面中自己
增加个
控件了, 因为它自动完成了增加
控件的功能, 具有通用性 .

(二). 运行如图

      1.  单行表头增加自动滚动效果

 

      2.  多行表头增加自动滚动效果

  

 

(三). 用法

   1. 将GridViewExpendHeader控件Dll添加引用到Web站点工程中

   2. 从工具箱拖动一个GridViewExpendHeader控件到设计器中

   3. 设置GridViewExpendHeader控件的属性.

                a.  设置属性窗口中新增的 "扩展" 类别中的两个属性,  这两个属性是指滚动区域的大小, 如下图所示:

                        

               b.  设置GridView本身的高度Height, 这个高度是指滚动区域内的GridView的实际高度, 这个高度数值设置

                     要大于ScrollHeight滚动条才能够呈现.  简单地说, 本自定义控件自动会实现一个GridView(自己)

                    的父控件

,  然后再把自己放在里面,  如果自己高度小于
高度了,  不用滚动就能够显示

                    全自己的数据, 滚动条就没有呈现的意义了.   这里讲得有点啰嗦.   .        

   4. F5运行即可

(四). 完整代码

    1. 主控件GridViewFixedMultiHeader类代码    

  1       ///   < summary >
  2       ///  Author: [ ChengKing(ZhengJian) ] 
  3       ///  Blog:   Http: // blog.youkuaiyun.com / ChengKing
  4       ///   Date :    2007 / 4 / 3
  5       ///   summary>    
  6     /// <summary>
  7     /// 主控件类, 继承GridView的所有功能
  8     ///  summary>
  9     [ToolboxData("<{0}:GridViewExpendHeader runat=server> ")]
 10     public class GridViewFixedMultiHeader : GridView 
 11     {       
 12         [Description("当需要重新构造Header时触发此事件")]
 13         public event System.EventHandler RebuildHeader;
 14 
 15         private System.Web.UI.WebControls.Panel pnlScroll = new System.Web.UI.WebControls.Panel();
 16 
 17         #region 扩展
 18         /// <summary>
 19         /// 设定滚动容器的宽度
 20         ///  summary>
 21         [Bindable(true)]
 22         [Category("扩展")]
 23         [DefaultValue("500px")]
 24         [Localizable(true)]
 25         [TypeConverter(typeof(UnitConverter))]
 26         public Unit ScrollWidth
 27         {
 28             get
 29             {
 30                 return pnlScroll.Width;
 31             }
 32             set
 33             {
 34                 pnlScroll.Width = value;
 35             }
 36         }
 37 
 38         /// <summary>
 39         /// 设定滚动容器的高度
 40         ///  summary>
 41         [Bindable(true)]
 42         [Category("扩展")]
 43         [DefaultValue("150px")]
 44         [Localizable(true)]
 45         [TypeConverter(typeof(UnitConverter))]
 46         public Unit ScrollHeight
 47         {
 48             get
 49             {
 50                 return pnlScroll.Height;
 51             }
 52             set
 53             {
 54                 pnlScroll.Height = value;
 55             }
 56         }
 57         #endregion
 58 
 59         protected override void OnPreRender(EventArgs e)
 60         {
 61             
 62             StringBuilder sb = new StringBuilder();              
 63             sb.Append(" function Tidy()");
 64             sb.Append(" {");
 65             sb.Append("     var gve = document.getElementById(/""+ this.UniqueID +"/"); ");            
 66             sb.Append("     if( gve.rows.length > 0 )");
 67             sb.Append("     {");
 68             sb.Append("         var a1 = document.getElementById(/"divHeaderContainer/");");
 69             sb.Append("         var table1 = document.createElement(/"table/");");
 70             sb.Append("         var tbody1 = document.createElement(/"tbody/");");
 71             sb.Append("         table1.style.cssText = /"table-layout:fixed;border-style: solid ;border-color:gray; border-width: 1px thin;/";   ");
 72             //sb.Append("         table1.style.cssText = /"table-layout:fixed;color:#CCCCFF;background-color:#003399;font-weight:bold;/";");
 73             sb.Append("         var i;");
 74             sb.Append("         var blnIfFind = false;");
 75             sb.Append("         for( i = gve.rows.length - 1; i >= 0; i-- )");
 76             sb.Append("         {");
 77             sb.Append("             if( gve.rows[i].children(0).tagName.toUpperCase() != /"TH/" && blnIfFind == false )  ");
 78             sb.Append("             {");
 79             sb.Append("                 continue;");
 80             sb.Append("             }");
 81             sb.Append("             if( blnIfFind == false )");
 82             sb.Append("             {");
 83             sb.Append("                 blnIfFind = true; ");
 84             sb.Append("             }");
 85             sb.Append("             if( tbody1.children.length == 0 )");
 86             sb.Append("             {");
 87             sb.Append("                 var newRow = gve.rows[i].cloneNode(true); ");
 88             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");            
 89             sb.Append("                 tbody1.appendChild( newRow ); ");
 90             sb.Append("             }");
 91             sb.Append("             else");
 92             sb.Append("             {");
 93             sb.Append("                 var newRow = gve.rows[i].cloneNode(true);   ");
 94             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");
 95             sb.Append("                 tbody1.insertBefore( newRow , tbody1.firstChild );");
 96             sb.Append("             }");
 97             sb.Append("         }");
 98             sb.Append("         table1.appendChild(tbody1);");
 99             sb.Append("         a1.appendChild(table1); ");
100             sb.Append("         for( i = 0; i < gve.rows.length -1; i++)");
101             sb.Append("         {");
102             sb.Append("             if( gve.rows[0].children(0).tagName.toUpperCase() != /"TH/" )");
103             sb.Append("             {");
104             sb.Append("                 gve.deleteRow(0);   ");
105             sb.Append("                 continue;");
106             sb.Append("             }");
107             sb.Append("             gve.deleteRow(0);   ");
108             sb.Append("             break; ");
109             sb.Append("         }");
110             sb.Append("     }");
111             sb.Append(" }");
112 
113             if (!Page.ClientScript.IsClientScriptBlockRegistered("Tidy"))
114             {
115                 Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Tidy", sb.ToString(),true);
116             }
117 
118             if (!Page.ClientScript.IsStartupScriptRegistered("Init"))
119             {
120                 Page.ClientScript.RegisterStartupScript(this.GetType(), "Init""<script type=/"text/javascript/">window.onload = Tidy;</script> "false);
121             }
122 
123             base.OnPreRender(e);
124         }
125 
126         protected override void Render(HtmlTextWriter writer)
127         {
128             OnRebuildHeader();         
129             base.Render(writer);
130         }
131         protected override void CreateChildControls()
132         {
133             Control parent = this.Parent;
134 
135             if (DesignMode == false)
136             {
137                 //生成头容器<DIV>
138                 System.Web.UI.HtmlControls.HtmlGenericControl div = new System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
139                 div.ID = "divHeaderContainer";
140                 div.Style.Add("width", this.Width.ToString());
141                 parent.Controls.Add(div);
142 
143                 Control gridView = this;
144                 parent.Controls.Remove(gridView);
145                  
146                 pnlScroll.Style.Add("width", this.Width.ToString());
147                 pnlScroll.Style.Add("OVERFLOW-Y""scroll");
148                 pnlScroll.Style.Add("OVERFLOW-X""hidden");
149        
150                 pnlScroll.Controls.Add(this);
151                 parent.Controls.Add(pnlScroll);
152 
153                 ChildControlsCreated = true;
154             }
155 
156             base.CreateChildControls();            
157         }
158     
159         protected virtual void OnRebuildHeader()
160         {
161             //重新构造Head
162             if (RebuildHeader != null)
163             {
164                 RebuildHeaderEventArgs args = new RebuildHeaderEventArgs();
165                 args.GridViewObject = this;
166                 args.HeaderRowObject = this.HeaderRow;
167 
168                 RebuildHeader(this, args);
169             }
170             
171         }       
172     } 

    2. 文件RebuildHeaderEventArgs.cs 代码

 1  ///  
 2     /// Author: [ ChengKing(ZhengJian) ] 
 3     /// Blog:   Http://blog.youkuaiyun.com/ChengKing
 4     /// Date:   2007/4/3
 5     /// 

 6       ///  
 7     /// 承载重构Header事件所需的参数[Author:ChengKing(ZhengJian)]
 8     /// 

 9       public   class  RebuildHeaderEventArgs : EventArgs
10      {
11           private  GridViewFixedMultiHeader _GridViewObject;
12           private  GridViewRow _HeaderRowObject;
13 
14           ///  
15         /// 存储GrivViewExtend对象本身
16         /// 

17           public  GridViewFixedMultiHeader GridViewObject
18          {
19               get
20              {
21                   return  _GridViewObject;
22              }
23               set
24              {
25                  _GridViewObject  =  value;
26              }
27          }
28 
29           ///  
30         /// 存储GrivViewExtend的HeaderRow对象
31         /// 

32           public  GridViewRow HeaderRowObject
33          {
34               get
35              {
36                   return  _HeaderRowObject;
37              }
38               set
39              {
40                  _HeaderRowObject  =  value;
41              }
42          }
43      }

   3. 测试页面文件default.aspx代码, 直接拖动一个控件到设计器就OK了. 不需要设置任何属性.

1 <div>
2    <asp:GridView ID="GridViewFixedMultiHeader1" runat="server"  asp:GridView>                  
3  div>

   4. 在新增自定义事件中增加表头行代码, 这里增加三行表头HeaderRow.
 1  ///  
 2     /// 具体重写方法, 此方法比较灵活, 可以任意设置您需要创建的格式, 比如更复杂的表格
 3     /// 另外, 可以直接从第二个参数中取得控件对象引用
 4     /// 

 5       ///  
 6       ///  
 7       protected   void  GridViewExpend1_RebuildHeader( object  sender, EventArgs e)
 8      {
 9           // 取得参数e中包含的对象的引用        
10          GridViewFixedMultiHeader currentGVE  =  ((RebuildHeaderEventArgs)e).GridViewObject;   // 到操作当前GridView的对象引用
11          GridViewRow currentHeaderRow  =  ((RebuildHeaderEventArgs)e).HeaderRowObject;  /// /到操作当前GridView's HeaderRow的对象引用
12 
13 
14           ///
15           /// /在当前HeaderRow上面增加一行
16           // 创建一个行并设置与GridViewExtend当前的头类型风格一致
17          GridViewRow willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
18          willAddHeaderRow.Font.Bold  =   true ;
19          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
20          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
21          TableCell cell  =   new  TableCell();
22          cell.Text  =   " Number " ;
23          cell.HorizontalAlign  =  HorizontalAlign.Center;
24          willAddHeaderRow.Cells.Add(cell);
25          cell  =   new  TableCell();
26          cell.Text  =   " Detail " ;
27          cell.ColumnSpan  =   2 ;
28          cell.HorizontalAlign  =  HorizontalAlign.Center;
29          willAddHeaderRow.Cells.Add(cell);
30           // 添加到GridView
31          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);
32 
33 
34           ///
35           /// /在当前HeaderRow上面再增加一行
36           // 同样创建一个行并设置与GridViewExtend当前的头类型风格一致
37          willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
38          willAddHeaderRow.Font.Bold  =   true ;
39          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
40          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
41 
42          cell  =   new  TableCell();
43          cell.Text  =   " Fruits category information " ;
44          cell.ColumnSpan  =   3 ;
45          cell.HorizontalAlign  =  HorizontalAlign.Center;
46          willAddHeaderRow.Cells.Add(cell);
47           // 添加到GridView
48          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);  
49       
50           // 还可以继续增加N个表头行;
51           // 不管增加多么, GridView控件都能够自动检测到HeaderRow的个数, 并且能够正确呈现滚动条
52           // ..;  
53           // ..; 
54      }

 

(五). 示例代码下载

        http://www.cnblogs.com/Files/MVP33650/extendgridviewfixedmultiheader.rar

 

(六). 控件开发其它相关文章:

        http://blog.youkuaiyun.com/ChengKing/category/288694.aspx

 

 

 

 

 

 

  


(一). 概述

        1. 实现GridView表头固定表体滚动效果

        2. 继承GridView的所有功能, 增加扩展功能, 表体滚动功能; 不需要另外加辅助滚动控件, 如

.

        3. 支持多行表头滚动, 此控件能够自动检测到使用者增加的表头的行数. 准确的实现表头滚动.

            有增加GridView多表头实现方案, 请看[多表头自定义控件]. 

实现原理:
    一般要实现GridView表头固定,表体滚动功能时,都是自己增加一个
控件,
然后将GridView嵌套在这个
控件里面; 使用这个 GridView 控件就不用在页面中自己
增加个
控件了, 因为它自动完成了增加
控件的功能, 具有通用性 .

(二). 运行如图

      1.  单行表头增加自动滚动效果

 

      2.  多行表头增加自动滚动效果

  

 

(三). 用法

   1. 将GridViewExpendHeader控件Dll添加引用到Web站点工程中

   2. 从工具箱拖动一个GridViewExpendHeader控件到设计器中

   3. 设置GridViewExpendHeader控件的属性.

                a.  设置属性窗口中新增的 "扩展" 类别中的两个属性,  这两个属性是指滚动区域的大小, 如下图所示:

                        

               b.  设置GridView本身的高度Height, 这个高度是指滚动区域内的GridView的实际高度, 这个高度数值设置

                     要大于ScrollHeight滚动条才能够呈现.  简单地说, 本自定义控件自动会实现一个GridView(自己)

                    的父控件

,  然后再把自己放在里面,  如果自己高度小于
高度了,  不用滚动就能够显示

                    全自己的数据, 滚动条就没有呈现的意义了.   这里讲得有点啰嗦.   .        

   4. F5运行即可

(四). 完整代码

    1. 主控件GridViewFixedMultiHeader类代码    

  1       ///   < summary >
  2       ///  Author: [ ChengKing(ZhengJian) ] 
  3       ///  Blog:   Http: // blog.youkuaiyun.com / ChengKing
  4       ///   Date :    2007 / 4 / 3
  5       ///   summary>    
  6     /// <summary>
  7     /// 主控件类, 继承GridView的所有功能
  8     ///  summary>
  9     [ToolboxData("<{0}:GridViewExpendHeader runat=server> ")]
 10     public class GridViewFixedMultiHeader : GridView 
 11     {       
 12         [Description("当需要重新构造Header时触发此事件")]
 13         public event System.EventHandler RebuildHeader;
 14 
 15         private System.Web.UI.WebControls.Panel pnlScroll = new System.Web.UI.WebControls.Panel();
 16 
 17         #region 扩展
 18         /// <summary>
 19         /// 设定滚动容器的宽度
 20         ///  summary>
 21         [Bindable(true)]
 22         [Category("扩展")]
 23         [DefaultValue("500px")]
 24         [Localizable(true)]
 25         [TypeConverter(typeof(UnitConverter))]
 26         public Unit ScrollWidth
 27         {
 28             get
 29             {
 30                 return pnlScroll.Width;
 31             }
 32             set
 33             {
 34                 pnlScroll.Width = value;
 35             }
 36         }
 37 
 38         /// <summary>
 39         /// 设定滚动容器的高度
 40         ///  summary>
 41         [Bindable(true)]
 42         [Category("扩展")]
 43         [DefaultValue("150px")]
 44         [Localizable(true)]
 45         [TypeConverter(typeof(UnitConverter))]
 46         public Unit ScrollHeight
 47         {
 48             get
 49             {
 50                 return pnlScroll.Height;
 51             }
 52             set
 53             {
 54                 pnlScroll.Height = value;
 55             }
 56         }
 57         #endregion
 58 
 59         protected override void OnPreRender(EventArgs e)
 60         {
 61             
 62             StringBuilder sb = new StringBuilder();              
 63             sb.Append(" function Tidy()");
 64             sb.Append(" {");
 65             sb.Append("     var gve = document.getElementById(/""+ this.UniqueID +"/"); ");            
 66             sb.Append("     if( gve.rows.length > 0 )");
 67             sb.Append("     {");
 68             sb.Append("         var a1 = document.getElementById(/"divHeaderContainer/");");
 69             sb.Append("         var table1 = document.createElement(/"table/");");
 70             sb.Append("         var tbody1 = document.createElement(/"tbody/");");
 71             sb.Append("         table1.style.cssText = /"table-layout:fixed;border-style: solid ;border-color:gray; border-width: 1px thin;/";   ");
 72             //sb.Append("         table1.style.cssText = /"table-layout:fixed;color:#CCCCFF;background-color:#003399;font-weight:bold;/";");
 73             sb.Append("         var i;");
 74             sb.Append("         var blnIfFind = false;");
 75             sb.Append("         for( i = gve.rows.length - 1; i >= 0; i-- )");
 76             sb.Append("         {");
 77             sb.Append("             if( gve.rows[i].children(0).tagName.toUpperCase() != /"TH/" && blnIfFind == false )  ");
 78             sb.Append("             {");
 79             sb.Append("                 continue;");
 80             sb.Append("             }");
 81             sb.Append("             if( blnIfFind == false )");
 82             sb.Append("             {");
 83             sb.Append("                 blnIfFind = true; ");
 84             sb.Append("             }");
 85             sb.Append("             if( tbody1.children.length == 0 )");
 86             sb.Append("             {");
 87             sb.Append("                 var newRow = gve.rows[i].cloneNode(true); ");
 88             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");            
 89             sb.Append("                 tbody1.appendChild( newRow ); ");
 90             sb.Append("             }");
 91             sb.Append("             else");
 92             sb.Append("             {");
 93             sb.Append("                 var newRow = gve.rows[i].cloneNode(true);   ");
 94             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");
 95             sb.Append("                 tbody1.insertBefore( newRow , tbody1.firstChild );");
 96             sb.Append("             }");
 97             sb.Append("         }");
 98             sb.Append("         table1.appendChild(tbody1);");
 99             sb.Append("         a1.appendChild(table1); ");
100             sb.Append("         for( i = 0; i < gve.rows.length -1; i++)");
101             sb.Append("         {");
102             sb.Append("             if( gve.rows[0].children(0).tagName.toUpperCase() != /"TH/" )");
103             sb.Append("             {");
104             sb.Append("                 gve.deleteRow(0);   ");
105             sb.Append("                 continue;");
106             sb.Append("             }");
107             sb.Append("             gve.deleteRow(0);   ");
108             sb.Append("             break; ");
109             sb.Append("         }");
110             sb.Append("     }");
111             sb.Append(" }");
112 
113             if (!Page.ClientScript.IsClientScriptBlockRegistered("Tidy"))
114             {
115                 Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Tidy", sb.ToString(),true);
116             }
117 
118             if (!Page.ClientScript.IsStartupScriptRegistered("Init"))
119             {
120                 Page.ClientScript.RegisterStartupScript(this.GetType(), "Init""<script type=/"text/javascript/">window.onload = Tidy;</script> "false);
121             }
122 
123             base.OnPreRender(e);
124         }
125 
126         protected override void Render(HtmlTextWriter writer)
127         {
128             OnRebuildHeader();         
129             base.Render(writer);
130         }
131         protected override void CreateChildControls()
132         {
133             Control parent = this.Parent;
134 
135             if (DesignMode == false)
136             {
137                 //生成头容器<DIV>
138                 System.Web.UI.HtmlControls.HtmlGenericControl div = new System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
139                 div.ID = "divHeaderContainer";
140                 div.Style.Add("width", this.Width.ToString());
141                 parent.Controls.Add(div);
142 
143                 Control gridView = this;
144                 parent.Controls.Remove(gridView);
145                  
146                 pnlScroll.Style.Add("width", this.Width.ToString());
147                 pnlScroll.Style.Add("OVERFLOW-Y""scroll");
148                 pnlScroll.Style.Add("OVERFLOW-X""hidden");
149        
150                 pnlScroll.Controls.Add(this);
151                 parent.Controls.Add(pnlScroll);
152 
153                 ChildControlsCreated = true;
154             }
155 
156             base.CreateChildControls();            
157         }
158     
159         protected virtual void OnRebuildHeader()
160         {
161             //重新构造Head
162             if (RebuildHeader != null)
163             {
164                 RebuildHeaderEventArgs args = new RebuildHeaderEventArgs();
165                 args.GridViewObject = this;
166                 args.HeaderRowObject = this.HeaderRow;
167 
168                 RebuildHeader(this, args);
169             }
170             
171         }       
172     } 

    2. 文件RebuildHeaderEventArgs.cs 代码

 1  ///  
 2     /// Author: [ ChengKing(ZhengJian) ] 
 3     /// Blog:   Http://blog.youkuaiyun.com/ChengKing
 4     /// Date:   2007/4/3
 5     /// 

 6       ///  
 7     /// 承载重构Header事件所需的参数[Author:ChengKing(ZhengJian)]
 8     /// 

 9       public   class  RebuildHeaderEventArgs : EventArgs
10      {
11           private  GridViewFixedMultiHeader _GridViewObject;
12           private  GridViewRow _HeaderRowObject;
13 
14           ///  
15         /// 存储GrivViewExtend对象本身
16         /// 

17           public  GridViewFixedMultiHeader GridViewObject
18          {
19               get
20              {
21                   return  _GridViewObject;
22              }
23               set
24              {
25                  _GridViewObject  =  value;
26              }
27          }
28 
29           ///  
30         /// 存储GrivViewExtend的HeaderRow对象
31         /// 

32           public  GridViewRow HeaderRowObject
33          {
34               get
35              {
36                   return  _HeaderRowObject;
37              }
38               set
39              {
40                  _HeaderRowObject  =  value;
41              }
42          }
43      }

   3. 测试页面文件default.aspx代码, 直接拖动一个控件到设计器就OK了. 不需要设置任何属性.

1 <div>
2    <asp:GridView ID="GridViewFixedMultiHeader1" runat="server"  asp:GridView>                  
3  div>

   4. 在新增自定义事件中增加表头行代码, 这里增加三行表头HeaderRow.
 1  ///  
 2     /// 具体重写方法, 此方法比较灵活, 可以任意设置您需要创建的格式, 比如更复杂的表格
 3     /// 另外, 可以直接从第二个参数中取得控件对象引用
 4     /// 

 5       ///  
 6       ///  
 7       protected   void  GridViewExpend1_RebuildHeader( object  sender, EventArgs e)
 8      {
 9           // 取得参数e中包含的对象的引用        
10          GridViewFixedMultiHeader currentGVE  =  ((RebuildHeaderEventArgs)e).GridViewObject;   // 到操作当前GridView的对象引用
11          GridViewRow currentHeaderRow  =  ((RebuildHeaderEventArgs)e).HeaderRowObject;  /// /到操作当前GridView's HeaderRow的对象引用
12 
13 
14           ///
15           /// /在当前HeaderRow上面增加一行
16           // 创建一个行并设置与GridViewExtend当前的头类型风格一致
17          GridViewRow willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
18          willAddHeaderRow.Font.Bold  =   true ;
19          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
20          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
21          TableCell cell  =   new  TableCell();
22          cell.Text  =   " Number " ;
23          cell.HorizontalAlign  =  HorizontalAlign.Center;
24          willAddHeaderRow.Cells.Add(cell);
25          cell  =   new  TableCell();
26          cell.Text  =   " Detail " ;
27          cell.ColumnSpan  =   2 ;
28          cell.HorizontalAlign  =  HorizontalAlign.Center;
29          willAddHeaderRow.Cells.Add(cell);
30           // 添加到GridView
31          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);
32 
33 
34           ///
35           /// /在当前HeaderRow上面再增加一行
36           // 同样创建一个行并设置与GridViewExtend当前的头类型风格一致
37          willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
38          willAddHeaderRow.Font.Bold  =   true ;
39          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
40          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
41 
42          cell  =   new  TableCell();
43          cell.Text  =   " Fruits category information " ;
44          cell.ColumnSpan  =   3 ;
45          cell.HorizontalAlign  =  HorizontalAlign.Center;
46          willAddHeaderRow.Cells.Add(cell);
47           // 添加到GridView
48          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);  
49       
50           // 还可以继续增加N个表头行;
51           // 不管增加多么, GridView控件都能够自动检测到HeaderRow的个数, 并且能够正确呈现滚动条
52           // ..;  
53           // ..; 
54      }

 

(五). 示例代码下载

        http://www.cnblogs.com/Files/MVP33650/extendgridviewfixedmultiheader.rar

 

(六). 控件开发其它相关文章:

        http://blog.youkuaiyun.com/ChengKing/category/288694.aspx

 

 

 

 

 

 

  


(一). 概述

        1. 实现GridView表头固定表体滚动效果

        2. 继承GridView的所有功能, 增加扩展功能, 表体滚动功能; 不需要另外加辅助滚动控件, 如

.

        3. 支持多行表头滚动, 此控件能够自动检测到使用者增加的表头的行数. 准确的实现表头滚动.

            有增加GridView多表头实现方案, 请看[多表头自定义控件]. 

实现原理:
    一般要实现GridView表头固定,表体滚动功能时,都是自己增加一个
控件,
然后将GridView嵌套在这个
控件里面; 使用这个 GridView 控件就不用在页面中自己
增加个
控件了, 因为它自动完成了增加
控件的功能, 具有通用性 .

(二). 运行如图

      1.  单行表头增加自动滚动效果

 

      2.  多行表头增加自动滚动效果

  

 

(三). 用法

   1. 将GridViewExpendHeader控件Dll添加引用到Web站点工程中

   2. 从工具箱拖动一个GridViewExpendHeader控件到设计器中

   3. 设置GridViewExpendHeader控件的属性.

                a.  设置属性窗口中新增的 "扩展" 类别中的两个属性,  这两个属性是指滚动区域的大小, 如下图所示:

                        

               b.  设置GridView本身的高度Height, 这个高度是指滚动区域内的GridView的实际高度, 这个高度数值设置

                     要大于ScrollHeight滚动条才能够呈现.  简单地说, 本自定义控件自动会实现一个GridView(自己)

                    的父控件

,  然后再把自己放在里面,  如果自己高度小于
高度了,  不用滚动就能够显示

                    全自己的数据, 滚动条就没有呈现的意义了.   这里讲得有点啰嗦.   .        

   4. F5运行即可

(四). 完整代码

    1. 主控件GridViewFixedMultiHeader类代码    

  1       ///   < summary >
  2       ///  Author: [ ChengKing(ZhengJian) ] 
  3       ///  Blog:   Http: // blog.youkuaiyun.com / ChengKing
  4       ///   Date :    2007 / 4 / 3
  5       ///   summary>    
  6     /// <summary>
  7     /// 主控件类, 继承GridView的所有功能
  8     ///  summary>
  9     [ToolboxData("<{0}:GridViewExpendHeader runat=server> ")]
 10     public class GridViewFixedMultiHeader : GridView 
 11     {       
 12         [Description("当需要重新构造Header时触发此事件")]
 13         public event System.EventHandler RebuildHeader;
 14 
 15         private System.Web.UI.WebControls.Panel pnlScroll = new System.Web.UI.WebControls.Panel();
 16 
 17         #region 扩展
 18         /// <summary>
 19         /// 设定滚动容器的宽度
 20         ///  summary>
 21         [Bindable(true)]
 22         [Category("扩展")]
 23         [DefaultValue("500px")]
 24         [Localizable(true)]
 25         [TypeConverter(typeof(UnitConverter))]
 26         public Unit ScrollWidth
 27         {
 28             get
 29             {
 30                 return pnlScroll.Width;
 31             }
 32             set
 33             {
 34                 pnlScroll.Width = value;
 35             }
 36         }
 37 
 38         /// <summary>
 39         /// 设定滚动容器的高度
 40         ///  summary>
 41         [Bindable(true)]
 42         [Category("扩展")]
 43         [DefaultValue("150px")]
 44         [Localizable(true)]
 45         [TypeConverter(typeof(UnitConverter))]
 46         public Unit ScrollHeight
 47         {
 48             get
 49             {
 50                 return pnlScroll.Height;
 51             }
 52             set
 53             {
 54                 pnlScroll.Height = value;
 55             }
 56         }
 57         #endregion
 58 
 59         protected override void OnPreRender(EventArgs e)
 60         {
 61             
 62             StringBuilder sb = new StringBuilder();              
 63             sb.Append(" function Tidy()");
 64             sb.Append(" {");
 65             sb.Append("     var gve = document.getElementById(/""+ this.UniqueID +"/"); ");            
 66             sb.Append("     if( gve.rows.length > 0 )");
 67             sb.Append("     {");
 68             sb.Append("         var a1 = document.getElementById(/"divHeaderContainer/");");
 69             sb.Append("         var table1 = document.createElement(/"table/");");
 70             sb.Append("         var tbody1 = document.createElement(/"tbody/");");
 71             sb.Append("         table1.style.cssText = /"table-layout:fixed;border-style: solid ;border-color:gray; border-width: 1px thin;/";   ");
 72             //sb.Append("         table1.style.cssText = /"table-layout:fixed;color:#CCCCFF;background-color:#003399;font-weight:bold;/";");
 73             sb.Append("         var i;");
 74             sb.Append("         var blnIfFind = false;");
 75             sb.Append("         for( i = gve.rows.length - 1; i >= 0; i-- )");
 76             sb.Append("         {");
 77             sb.Append("             if( gve.rows[i].children(0).tagName.toUpperCase() != /"TH/" && blnIfFind == false )  ");
 78             sb.Append("             {");
 79             sb.Append("                 continue;");
 80             sb.Append("             }");
 81             sb.Append("             if( blnIfFind == false )");
 82             sb.Append("             {");
 83             sb.Append("                 blnIfFind = true; ");
 84             sb.Append("             }");
 85             sb.Append("             if( tbody1.children.length == 0 )");
 86             sb.Append("             {");
 87             sb.Append("                 var newRow = gve.rows[i].cloneNode(true); ");
 88             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");            
 89             sb.Append("                 tbody1.appendChild( newRow ); ");
 90             sb.Append("             }");
 91             sb.Append("             else");
 92             sb.Append("             {");
 93             sb.Append("                 var newRow = gve.rows[i].cloneNode(true);   ");
 94             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");
 95             sb.Append("                 tbody1.insertBefore( newRow , tbody1.firstChild );");
 96             sb.Append("             }");
 97             sb.Append("         }");
 98             sb.Append("         table1.appendChild(tbody1);");
 99             sb.Append("         a1.appendChild(table1); ");
100             sb.Append("         for( i = 0; i < gve.rows.length -1; i++)");
101             sb.Append("         {");
102             sb.Append("             if( gve.rows[0].children(0).tagName.toUpperCase() != /"TH/" )");
103             sb.Append("             {");
104             sb.Append("                 gve.deleteRow(0);   ");
105             sb.Append("                 continue;");
106             sb.Append("             }");
107             sb.Append("             gve.deleteRow(0);   ");
108             sb.Append("             break; ");
109             sb.Append("         }");
110             sb.Append("     }");
111             sb.Append(" }");
112 
113             if (!Page.ClientScript.IsClientScriptBlockRegistered("Tidy"))
114             {
115                 Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Tidy", sb.ToString(),true);
116             }
117 
118             if (!Page.ClientScript.IsStartupScriptRegistered("Init"))
119             {
120                 Page.ClientScript.RegisterStartupScript(this.GetType(), "Init""<script type=/"text/javascript/">window.onload = Tidy;</script> "false);
121             }
122 
123             base.OnPreRender(e);
124         }
125 
126         protected override void Render(HtmlTextWriter writer)
127         {
128             OnRebuildHeader();         
129             base.Render(writer);
130         }
131         protected override void CreateChildControls()
132         {
133             Control parent = this.Parent;
134 
135             if (DesignMode == false)
136             {
137                 //生成头容器<DIV>
138                 System.Web.UI.HtmlControls.HtmlGenericControl div = new System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
139                 div.ID = "divHeaderContainer";
140                 div.Style.Add("width", this.Width.ToString());
141                 parent.Controls.Add(div);
142 
143                 Control gridView = this;
144                 parent.Controls.Remove(gridView);
145                  
146                 pnlScroll.Style.Add("width", this.Width.ToString());
147                 pnlScroll.Style.Add("OVERFLOW-Y""scroll");
148                 pnlScroll.Style.Add("OVERFLOW-X""hidden");
149        
150                 pnlScroll.Controls.Add(this);
151                 parent.Controls.Add(pnlScroll);
152 
153                 ChildControlsCreated = true;
154             }
155 
156             base.CreateChildControls();            
157         }
158     
159         protected virtual void OnRebuildHeader()
160         {
161             //重新构造Head
162             if (RebuildHeader != null)
163             {
164                 RebuildHeaderEventArgs args = new RebuildHeaderEventArgs();
165                 args.GridViewObject = this;
166                 args.HeaderRowObject = this.HeaderRow;
167 
168                 RebuildHeader(this, args);
169             }
170             
171         }       
172     } 

    2. 文件RebuildHeaderEventArgs.cs 代码

 1  ///  
 2     /// Author: [ ChengKing(ZhengJian) ] 
 3     /// Blog:   Http://blog.youkuaiyun.com/ChengKing
 4     /// Date:   2007/4/3
 5     /// 

 6       ///  
 7     /// 承载重构Header事件所需的参数[Author:ChengKing(ZhengJian)]
 8     /// 

 9       public   class  RebuildHeaderEventArgs : EventArgs
10      {
11           private  GridViewFixedMultiHeader _GridViewObject;
12           private  GridViewRow _HeaderRowObject;
13 
14           ///  
15         /// 存储GrivViewExtend对象本身
16         /// 

17           public  GridViewFixedMultiHeader GridViewObject
18          {
19               get
20              {
21                   return  _GridViewObject;
22              }
23               set
24              {
25                  _GridViewObject  =  value;
26              }
27          }
28 
29           ///  
30         /// 存储GrivViewExtend的HeaderRow对象
31         /// 

32           public  GridViewRow HeaderRowObject
33          {
34               get
35              {
36                   return  _HeaderRowObject;
37              }
38               set
39              {
40                  _HeaderRowObject  =  value;
41              }
42          }
43      }

   3. 测试页面文件default.aspx代码, 直接拖动一个控件到设计器就OK了. 不需要设置任何属性.

1 <div>
2    <asp:GridView ID="GridViewFixedMultiHeader1" runat="server"  asp:GridView>                  
3  div>

   4. 在新增自定义事件中增加表头行代码, 这里增加三行表头HeaderRow.
 1  ///  
 2     /// 具体重写方法, 此方法比较灵活, 可以任意设置您需要创建的格式, 比如更复杂的表格
 3     /// 另外, 可以直接从第二个参数中取得控件对象引用
 4     /// 

 5       ///  
 6       ///  
 7       protected   void  GridViewExpend1_RebuildHeader( object  sender, EventArgs e)
 8      {
 9           // 取得参数e中包含的对象的引用        
10          GridViewFixedMultiHeader currentGVE  =  ((RebuildHeaderEventArgs)e).GridViewObject;   // 到操作当前GridView的对象引用
11          GridViewRow currentHeaderRow  =  ((RebuildHeaderEventArgs)e).HeaderRowObject;  /// /到操作当前GridView's HeaderRow的对象引用
12 
13 
14           ///
15           /// /在当前HeaderRow上面增加一行
16           // 创建一个行并设置与GridViewExtend当前的头类型风格一致
17          GridViewRow willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
18          willAddHeaderRow.Font.Bold  =   true ;
19          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
20          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
21          TableCell cell  =   new  TableCell();
22          cell.Text  =   " Number " ;
23          cell.HorizontalAlign  =  HorizontalAlign.Center;
24          willAddHeaderRow.Cells.Add(cell);
25          cell  =   new  TableCell();
26          cell.Text  =   " Detail " ;
27          cell.ColumnSpan  =   2 ;
28          cell.HorizontalAlign  =  HorizontalAlign.Center;
29          willAddHeaderRow.Cells.Add(cell);
30           // 添加到GridView
31          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);
32 
33 
34           ///
35           /// /在当前HeaderRow上面再增加一行
36           // 同样创建一个行并设置与GridViewExtend当前的头类型风格一致
37          willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
38          willAddHeaderRow.Font.Bold  =   true ;
39          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
40          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
41 
42          cell  =   new  TableCell();
43          cell.Text  =   " Fruits category information " ;
44          cell.ColumnSpan  =   3 ;
45          cell.HorizontalAlign  =  HorizontalAlign.Center;
46          willAddHeaderRow.Cells.Add(cell);
47           // 添加到GridView
48          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);  
49       
50           // 还可以继续增加N个表头行;
51           // 不管增加多么, GridView控件都能够自动检测到HeaderRow的个数, 并且能够正确呈现滚动条
52           // ..;  
53           // ..; 
54      }

 

(五). 示例代码下载

        http://www.cnblogs.com/Files/MVP33650/extendgridviewfixedmultiheader.rar

 

(六). 控件开发其它相关文章:

        http://blog.youkuaiyun.com/ChengKing/category/288694.aspx

 

 

 

 

 

 

  


(一). 概述

        1. 实现GridView表头固定表体滚动效果

        2. 继承GridView的所有功能, 增加扩展功能, 表体滚动功能; 不需要另外加辅助滚动控件, 如

.

        3. 支持多行表头滚动, 此控件能够自动检测到使用者增加的表头的行数. 准确的实现表头滚动.

            有增加GridView多表头实现方案, 请看[多表头自定义控件]. 

实现原理:
    一般要实现GridView表头固定,表体滚动功能时,都是自己增加一个
控件,
然后将GridView嵌套在这个
控件里面; 使用这个 GridView 控件就不用在页面中自己
增加个
控件了, 因为它自动完成了增加
控件的功能, 具有通用性 .

(二). 运行如图

      1.  单行表头增加自动滚动效果

 

      2.  多行表头增加自动滚动效果

  

 

(三). 用法

   1. 将GridViewExpendHeader控件Dll添加引用到Web站点工程中

   2. 从工具箱拖动一个GridViewExpendHeader控件到设计器中

   3. 设置GridViewExpendHeader控件的属性.

                a.  设置属性窗口中新增的 "扩展" 类别中的两个属性,  这两个属性是指滚动区域的大小, 如下图所示:

                        

               b.  设置GridView本身的高度Height, 这个高度是指滚动区域内的GridView的实际高度, 这个高度数值设置

                     要大于ScrollHeight滚动条才能够呈现.  简单地说, 本自定义控件自动会实现一个GridView(自己)

                    的父控件

,  然后再把自己放在里面,  如果自己高度小于
高度了,  不用滚动就能够显示

                    全自己的数据, 滚动条就没有呈现的意义了.   这里讲得有点啰嗦.   .        

   4. F5运行即可

(四). 完整代码

    1. 主控件GridViewFixedMultiHeader类代码    

  1       ///   < summary >
  2       ///  Author: [ ChengKing(ZhengJian) ] 
  3       ///  Blog:   Http: // blog.youkuaiyun.com / ChengKing
  4       ///   Date :    2007 / 4 / 3
  5       ///   summary>    
  6     /// <summary>
  7     /// 主控件类, 继承GridView的所有功能
  8     ///  summary>
  9     [ToolboxData("<{0}:GridViewExpendHeader runat=server> ")]
 10     public class GridViewFixedMultiHeader : GridView 
 11     {       
 12         [Description("当需要重新构造Header时触发此事件")]
 13         public event System.EventHandler RebuildHeader;
 14 
 15         private System.Web.UI.WebControls.Panel pnlScroll = new System.Web.UI.WebControls.Panel();
 16 
 17         #region 扩展
 18         /// <summary>
 19         /// 设定滚动容器的宽度
 20         ///  summary>
 21         [Bindable(true)]
 22         [Category("扩展")]
 23         [DefaultValue("500px")]
 24         [Localizable(true)]
 25         [TypeConverter(typeof(UnitConverter))]
 26         public Unit ScrollWidth
 27         {
 28             get
 29             {
 30                 return pnlScroll.Width;
 31             }
 32             set
 33             {
 34                 pnlScroll.Width = value;
 35             }
 36         }
 37 
 38         /// <summary>
 39         /// 设定滚动容器的高度
 40         ///  summary>
 41         [Bindable(true)]
 42         [Category("扩展")]
 43         [DefaultValue("150px")]
 44         [Localizable(true)]
 45         [TypeConverter(typeof(UnitConverter))]
 46         public Unit ScrollHeight
 47         {
 48             get
 49             {
 50                 return pnlScroll.Height;
 51             }
 52             set
 53             {
 54                 pnlScroll.Height = value;
 55             }
 56         }
 57         #endregion
 58 
 59         protected override void OnPreRender(EventArgs e)
 60         {
 61             
 62             StringBuilder sb = new StringBuilder();              
 63             sb.Append(" function Tidy()");
 64             sb.Append(" {");
 65             sb.Append("     var gve = document.getElementById(/""+ this.UniqueID +"/"); ");            
 66             sb.Append("     if( gve.rows.length > 0 )");
 67             sb.Append("     {");
 68             sb.Append("         var a1 = document.getElementById(/"divHeaderContainer/");");
 69             sb.Append("         var table1 = document.createElement(/"table/");");
 70             sb.Append("         var tbody1 = document.createElement(/"tbody/");");
 71             sb.Append("         table1.style.cssText = /"table-layout:fixed;border-style: solid ;border-color:gray; border-width: 1px thin;/";   ");
 72             //sb.Append("         table1.style.cssText = /"table-layout:fixed;color:#CCCCFF;background-color:#003399;font-weight:bold;/";");
 73             sb.Append("         var i;");
 74             sb.Append("         var blnIfFind = false;");
 75             sb.Append("         for( i = gve.rows.length - 1; i >= 0; i-- )");
 76             sb.Append("         {");
 77             sb.Append("             if( gve.rows[i].children(0).tagName.toUpperCase() != /"TH/" && blnIfFind == false )  ");
 78             sb.Append("             {");
 79             sb.Append("                 continue;");
 80             sb.Append("             }");
 81             sb.Append("             if( blnIfFind == false )");
 82             sb.Append("             {");
 83             sb.Append("                 blnIfFind = true; ");
 84             sb.Append("             }");
 85             sb.Append("             if( tbody1.children.length == 0 )");
 86             sb.Append("             {");
 87             sb.Append("                 var newRow = gve.rows[i].cloneNode(true); ");
 88             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");            
 89             sb.Append("                 tbody1.appendChild( newRow ); ");
 90             sb.Append("             }");
 91             sb.Append("             else");
 92             sb.Append("             {");
 93             sb.Append("                 var newRow = gve.rows[i].cloneNode(true);   ");
 94             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");
 95             sb.Append("                 tbody1.insertBefore( newRow , tbody1.firstChild );");
 96             sb.Append("             }");
 97             sb.Append("         }");
 98             sb.Append("         table1.appendChild(tbody1);");
 99             sb.Append("         a1.appendChild(table1); ");
100             sb.Append("         for( i = 0; i < gve.rows.length -1; i++)");
101             sb.Append("         {");
102             sb.Append("             if( gve.rows[0].children(0).tagName.toUpperCase() != /"TH/" )");
103             sb.Append("             {");
104             sb.Append("                 gve.deleteRow(0);   ");
105             sb.Append("                 continue;");
106             sb.Append("             }");
107             sb.Append("             gve.deleteRow(0);   ");
108             sb.Append("             break; ");
109             sb.Append("         }");
110             sb.Append("     }");
111             sb.Append(" }");
112 
113             if (!Page.ClientScript.IsClientScriptBlockRegistered("Tidy"))
114             {
115                 Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Tidy", sb.ToString(),true);
116             }
117 
118             if (!Page.ClientScript.IsStartupScriptRegistered("Init"))
119             {
120                 Page.ClientScript.RegisterStartupScript(this.GetType(), "Init""<script type=/"text/javascript/">window.onload = Tidy;</script> "false);
121             }
122 
123             base.OnPreRender(e);
124         }
125 
126         protected override void Render(HtmlTextWriter writer)
127         {
128             OnRebuildHeader();         
129             base.Render(writer);
130         }
131         protected override void CreateChildControls()
132         {
133             Control parent = this.Parent;
134 
135             if (DesignMode == false)
136             {
137                 //生成头容器<DIV>
138                 System.Web.UI.HtmlControls.HtmlGenericControl div = new System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
139                 div.ID = "divHeaderContainer";
140                 div.Style.Add("width", this.Width.ToString());
141                 parent.Controls.Add(div);
142 
143                 Control gridView = this;
144                 parent.Controls.Remove(gridView);
145                  
146                 pnlScroll.Style.Add("width", this.Width.ToString());
147                 pnlScroll.Style.Add("OVERFLOW-Y""scroll");
148                 pnlScroll.Style.Add("OVERFLOW-X""hidden");
149        
150                 pnlScroll.Controls.Add(this);
151                 parent.Controls.Add(pnlScroll);
152 
153                 ChildControlsCreated = true;
154             }
155 
156             base.CreateChildControls();            
157         }
158     
159         protected virtual void OnRebuildHeader()
160         {
161             //重新构造Head
162             if (RebuildHeader != null)
163             {
164                 RebuildHeaderEventArgs args = new RebuildHeaderEventArgs();
165                 args.GridViewObject = this;
166                 args.HeaderRowObject = this.HeaderRow;
167 
168                 RebuildHeader(this, args);
169             }
170             
171         }       
172     } 

    2. 文件RebuildHeaderEventArgs.cs 代码

 1  ///  
 2     /// Author: [ ChengKing(ZhengJian) ] 
 3     /// Blog:   Http://blog.youkuaiyun.com/ChengKing
 4     /// Date:   2007/4/3
 5     /// 

 6       ///  
 7     /// 承载重构Header事件所需的参数[Author:ChengKing(ZhengJian)]
 8     /// 

 9       public   class  RebuildHeaderEventArgs : EventArgs
10      {
11           private  GridViewFixedMultiHeader _GridViewObject;
12           private  GridViewRow _HeaderRowObject;
13 
14           ///  
15         /// 存储GrivViewExtend对象本身
16         /// 

17           public  GridViewFixedMultiHeader GridViewObject
18          {
19               get
20              {
21                   return  _GridViewObject;
22              }
23               set
24              {
25                  _GridViewObject  =  value;
26              }
27          }
28 
29           ///  
30         /// 存储GrivViewExtend的HeaderRow对象
31         /// 

32           public  GridViewRow HeaderRowObject
33          {
34               get
35              {
36                   return  _HeaderRowObject;
37              }
38               set
39              {
40                  _HeaderRowObject  =  value;
41              }
42          }
43      }

   3. 测试页面文件default.aspx代码, 直接拖动一个控件到设计器就OK了. 不需要设置任何属性.

1 <div>
2    <asp:GridView ID="GridViewFixedMultiHeader1" runat="server"  asp:GridView>                  
3  div>

   4. 在新增自定义事件中增加表头行代码, 这里增加三行表头HeaderRow.
 1  ///  
 2     /// 具体重写方法, 此方法比较灵活, 可以任意设置您需要创建的格式, 比如更复杂的表格
 3     /// 另外, 可以直接从第二个参数中取得控件对象引用
 4     /// 

 5       ///  
 6       ///  
 7       protected   void  GridViewExpend1_RebuildHeader( object  sender, EventArgs e)
 8      {
 9           // 取得参数e中包含的对象的引用        
10          GridViewFixedMultiHeader currentGVE  =  ((RebuildHeaderEventArgs)e).GridViewObject;   // 到操作当前GridView的对象引用
11          GridViewRow currentHeaderRow  =  ((RebuildHeaderEventArgs)e).HeaderRowObject;  /// /到操作当前GridView's HeaderRow的对象引用
12 
13 
14           ///
15           /// /在当前HeaderRow上面增加一行
16           // 创建一个行并设置与GridViewExtend当前的头类型风格一致
17          GridViewRow willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
18          willAddHeaderRow.Font.Bold  =   true ;
19          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
20          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
21          TableCell cell  =   new  TableCell();
22          cell.Text  =   " Number " ;
23          cell.HorizontalAlign  =  HorizontalAlign.Center;
24          willAddHeaderRow.Cells.Add(cell);
25          cell  =   new  TableCell();
26          cell.Text  =   " Detail " ;
27          cell.ColumnSpan  =   2 ;
28          cell.HorizontalAlign  =  HorizontalAlign.Center;
29          willAddHeaderRow.Cells.Add(cell);
30           // 添加到GridView
31          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);
32 
33 
34           ///
35           /// /在当前HeaderRow上面再增加一行
36           // 同样创建一个行并设置与GridViewExtend当前的头类型风格一致
37          willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
38          willAddHeaderRow.Font.Bold  =   true ;
39          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
40          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
41 
42          cell  =   new  TableCell();
43          cell.Text  =   " Fruits category information " ;
44          cell.ColumnSpan  =   3 ;
45          cell.HorizontalAlign  =  HorizontalAlign.Center;
46          willAddHeaderRow.Cells.Add(cell);
47           // 添加到GridView
48          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);  
49       
50           // 还可以继续增加N个表头行;
51           // 不管增加多么, GridView控件都能够自动检测到HeaderRow的个数, 并且能够正确呈现滚动条
52           // ..;  
53           // ..; 
54      }

 

(五). 示例代码下载

        http://www.cnblogs.com/Files/MVP33650/extendgridviewfixedmultiheader.rar

 

(六). 控件开发其它相关文章:

        http://blog.youkuaiyun.com/ChengKing/category/288694.aspx

 

 

 

 

 

 

  


(一). 概述

        1. 实现GridView表头固定表体滚动效果

        2. 继承GridView的所有功能, 增加扩展功能, 表体滚动功能; 不需要另外加辅助滚动控件, 如

.

        3. 支持多行表头滚动, 此控件能够自动检测到使用者增加的表头的行数. 准确的实现表头滚动.

            有增加GridView多表头实现方案, 请看[多表头自定义控件]. 

实现原理:
    一般要实现GridView表头固定,表体滚动功能时,都是自己增加一个
控件,
然后将GridView嵌套在这个
控件里面; 使用这个 GridView 控件就不用在页面中自己
增加个
控件了, 因为它自动完成了增加
控件的功能, 具有通用性 .

(二). 运行如图

      1.  单行表头增加自动滚动效果

 

      2.  多行表头增加自动滚动效果

  

 

(三). 用法

   1. 将GridViewExpendHeader控件Dll添加引用到Web站点工程中

   2. 从工具箱拖动一个GridViewExpendHeader控件到设计器中

   3. 设置GridViewExpendHeader控件的属性.

                a.  设置属性窗口中新增的 "扩展" 类别中的两个属性,  这两个属性是指滚动区域的大小, 如下图所示:

                        

               b.  设置GridView本身的高度Height, 这个高度是指滚动区域内的GridView的实际高度, 这个高度数值设置

                     要大于ScrollHeight滚动条才能够呈现.  简单地说, 本自定义控件自动会实现一个GridView(自己)

                    的父控件

,  然后再把自己放在里面,  如果自己高度小于
高度了,  不用滚动就能够显示

                    全自己的数据, 滚动条就没有呈现的意义了.   这里讲得有点啰嗦.   .        

   4. F5运行即可

(四). 完整代码

    1. 主控件GridViewFixedMultiHeader类代码    

  1       ///   < summary >
  2       ///  Author: [ ChengKing(ZhengJian) ] 
  3       ///  Blog:   Http: // blog.youkuaiyun.com / ChengKing
  4       ///   Date :    2007 / 4 / 3
  5       ///   summary>    
  6     /// <summary>
  7     /// 主控件类, 继承GridView的所有功能
  8     ///  summary>
  9     [ToolboxData("<{0}:GridViewExpendHeader runat=server> ")]
 10     public class GridViewFixedMultiHeader : GridView 
 11     {       
 12         [Description("当需要重新构造Header时触发此事件")]
 13         public event System.EventHandler RebuildHeader;
 14 
 15         private System.Web.UI.WebControls.Panel pnlScroll = new System.Web.UI.WebControls.Panel();
 16 
 17         #region 扩展
 18         /// <summary>
 19         /// 设定滚动容器的宽度
 20         ///  summary>
 21         [Bindable(true)]
 22         [Category("扩展")]
 23         [DefaultValue("500px")]
 24         [Localizable(true)]
 25         [TypeConverter(typeof(UnitConverter))]
 26         public Unit ScrollWidth
 27         {
 28             get
 29             {
 30                 return pnlScroll.Width;
 31             }
 32             set
 33             {
 34                 pnlScroll.Width = value;
 35             }
 36         }
 37 
 38         /// <summary>
 39         /// 设定滚动容器的高度
 40         ///  summary>
 41         [Bindable(true)]
 42         [Category("扩展")]
 43         [DefaultValue("150px")]
 44         [Localizable(true)]
 45         [TypeConverter(typeof(UnitConverter))]
 46         public Unit ScrollHeight
 47         {
 48             get
 49             {
 50                 return pnlScroll.Height;
 51             }
 52             set
 53             {
 54                 pnlScroll.Height = value;
 55             }
 56         }
 57         #endregion
 58 
 59         protected override void OnPreRender(EventArgs e)
 60         {
 61             
 62             StringBuilder sb = new StringBuilder();              
 63             sb.Append(" function Tidy()");
 64             sb.Append(" {");
 65             sb.Append("     var gve = document.getElementById(/""+ this.UniqueID +"/"); ");            
 66             sb.Append("     if( gve.rows.length > 0 )");
 67             sb.Append("     {");
 68             sb.Append("         var a1 = document.getElementById(/"divHeaderContainer/");");
 69             sb.Append("         var table1 = document.createElement(/"table/");");
 70             sb.Append("         var tbody1 = document.createElement(/"tbody/");");
 71             sb.Append("         table1.style.cssText = /"table-layout:fixed;border-style: solid ;border-color:gray; border-width: 1px thin;/";   ");
 72             //sb.Append("         table1.style.cssText = /"table-layout:fixed;color:#CCCCFF;background-color:#003399;font-weight:bold;/";");
 73             sb.Append("         var i;");
 74             sb.Append("         var blnIfFind = false;");
 75             sb.Append("         for( i = gve.rows.length - 1; i >= 0; i-- )");
 76             sb.Append("         {");
 77             sb.Append("             if( gve.rows[i].children(0).tagName.toUpperCase() != /"TH/" && blnIfFind == false )  ");
 78             sb.Append("             {");
 79             sb.Append("                 continue;");
 80             sb.Append("             }");
 81             sb.Append("             if( blnIfFind == false )");
 82             sb.Append("             {");
 83             sb.Append("                 blnIfFind = true; ");
 84             sb.Append("             }");
 85             sb.Append("             if( tbody1.children.length == 0 )");
 86             sb.Append("             {");
 87             sb.Append("                 var newRow = gve.rows[i].cloneNode(true); ");
 88             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");            
 89             sb.Append("                 tbody1.appendChild( newRow ); ");
 90             sb.Append("             }");
 91             sb.Append("             else");
 92             sb.Append("             {");
 93             sb.Append("                 var newRow = gve.rows[i].cloneNode(true);   ");
 94             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");
 95             sb.Append("                 tbody1.insertBefore( newRow , tbody1.firstChild );");
 96             sb.Append("             }");
 97             sb.Append("         }");
 98             sb.Append("         table1.appendChild(tbody1);");
 99             sb.Append("         a1.appendChild(table1); ");
100             sb.Append("         for( i = 0; i < gve.rows.length -1; i++)");
101             sb.Append("         {");
102             sb.Append("             if( gve.rows[0].children(0).tagName.toUpperCase() != /"TH/" )");
103             sb.Append("             {");
104             sb.Append("                 gve.deleteRow(0);   ");
105             sb.Append("                 continue;");
106             sb.Append("             }");
107             sb.Append("             gve.deleteRow(0);   ");
108             sb.Append("             break; ");
109             sb.Append("         }");
110             sb.Append("     }");
111             sb.Append(" }");
112 
113             if (!Page.ClientScript.IsClientScriptBlockRegistered("Tidy"))
114             {
115                 Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Tidy", sb.ToString(),true);
116             }
117 
118             if (!Page.ClientScript.IsStartupScriptRegistered("Init"))
119             {
120                 Page.ClientScript.RegisterStartupScript(this.GetType(), "Init""<script type=/"text/javascript/">window.onload = Tidy;</script> "false);
121             }
122 
123             base.OnPreRender(e);
124         }
125 
126         protected override void Render(HtmlTextWriter writer)
127         {
128             OnRebuildHeader();         
129             base.Render(writer);
130         }
131         protected override void CreateChildControls()
132         {
133             Control parent = this.Parent;
134 
135             if (DesignMode == false)
136             {
137                 //生成头容器<DIV>
138                 System.Web.UI.HtmlControls.HtmlGenericControl div = new System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
139                 div.ID = "divHeaderContainer";
140                 div.Style.Add("width", this.Width.ToString());
141                 parent.Controls.Add(div);
142 
143                 Control gridView = this;
144                 parent.Controls.Remove(gridView);
145                  
146                 pnlScroll.Style.Add("width", this.Width.ToString());
147                 pnlScroll.Style.Add("OVERFLOW-Y""scroll");
148                 pnlScroll.Style.Add("OVERFLOW-X""hidden");
149        
150                 pnlScroll.Controls.Add(this);
151                 parent.Controls.Add(pnlScroll);
152 
153                 ChildControlsCreated = true;
154             }
155 
156             base.CreateChildControls();            
157         }
158     
159         protected virtual void OnRebuildHeader()
160         {
161             //重新构造Head
162             if (RebuildHeader != null)
163             {
164                 RebuildHeaderEventArgs args = new RebuildHeaderEventArgs();
165                 args.GridViewObject = this;
166                 args.HeaderRowObject = this.HeaderRow;
167 
168                 RebuildHeader(this, args);
169             }
170             
171         }       
172     } 

    2. 文件RebuildHeaderEventArgs.cs 代码

 1  ///  
 2     /// Author: [ ChengKing(ZhengJian) ] 
 3     /// Blog:   Http://blog.youkuaiyun.com/ChengKing
 4     /// Date:   2007/4/3
 5     /// 

 6       ///  
 7     /// 承载重构Header事件所需的参数[Author:ChengKing(ZhengJian)]
 8     /// 

 9       public   class  RebuildHeaderEventArgs : EventArgs
10      {
11           private  GridViewFixedMultiHeader _GridViewObject;
12           private  GridViewRow _HeaderRowObject;
13 
14           ///  
15         /// 存储GrivViewExtend对象本身
16         /// 

17           public  GridViewFixedMultiHeader GridViewObject
18          {
19               get
20              {
21                   return  _GridViewObject;
22              }
23               set
24              {
25                  _GridViewObject  =  value;
26              }
27          }
28 
29           ///  
30         /// 存储GrivViewExtend的HeaderRow对象
31         /// 

32           public  GridViewRow HeaderRowObject
33          {
34               get
35              {
36                   return  _HeaderRowObject;
37              }
38               set
39              {
40                  _HeaderRowObject  =  value;
41              }
42          }
43      }

   3. 测试页面文件default.aspx代码, 直接拖动一个控件到设计器就OK了. 不需要设置任何属性.

1 <div>
2    <asp:GridView ID="GridViewFixedMultiHeader1" runat="server"  asp:GridView>                  
3  div>

   4. 在新增自定义事件中增加表头行代码, 这里增加三行表头HeaderRow.
 1  ///  
 2     /// 具体重写方法, 此方法比较灵活, 可以任意设置您需要创建的格式, 比如更复杂的表格
 3     /// 另外, 可以直接从第二个参数中取得控件对象引用
 4     /// 

 5       ///  
 6       ///  
 7       protected   void  GridViewExpend1_RebuildHeader( object  sender, EventArgs e)
 8      {
 9           // 取得参数e中包含的对象的引用        
10          GridViewFixedMultiHeader currentGVE  =  ((RebuildHeaderEventArgs)e).GridViewObject;   // 到操作当前GridView的对象引用
11          GridViewRow currentHeaderRow  =  ((RebuildHeaderEventArgs)e).HeaderRowObject;  /// /到操作当前GridView's HeaderRow的对象引用
12 
13 
14           ///
15           /// /在当前HeaderRow上面增加一行
16           // 创建一个行并设置与GridViewExtend当前的头类型风格一致
17          GridViewRow willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
18          willAddHeaderRow.Font.Bold  =   true ;
19          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
20          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
21          TableCell cell  =   new  TableCell();
22          cell.Text  =   " Number " ;
23          cell.HorizontalAlign  =  HorizontalAlign.Center;
24          willAddHeaderRow.Cells.Add(cell);
25          cell  =   new  TableCell();
26          cell.Text  =   " Detail " ;
27          cell.ColumnSpan  =   2 ;
28          cell.HorizontalAlign  =  HorizontalAlign.Center;
29          willAddHeaderRow.Cells.Add(cell);
30           // 添加到GridView
31          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);
32 
33 
34           ///
35           /// /在当前HeaderRow上面再增加一行
36           // 同样创建一个行并设置与GridViewExtend当前的头类型风格一致
37          willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
38          willAddHeaderRow.Font.Bold  =   true ;
39          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
40          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
41 
42          cell  =   new  TableCell();
43          cell.Text  =   " Fruits category information " ;
44          cell.ColumnSpan  =   3 ;
45          cell.HorizontalAlign  =  HorizontalAlign.Center;
46          willAddHeaderRow.Cells.Add(cell);
47           // 添加到GridView
48          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);  
49       
50           // 还可以继续增加N个表头行;
51           // 不管增加多么, GridView控件都能够自动检测到HeaderRow的个数, 并且能够正确呈现滚动条
52           // ..;  
53           // ..; 
54      }

 

(五). 示例代码下载

        http://www.cnblogs.com/Files/MVP33650/extendgridviewfixedmultiheader.rar

 

(六). 控件开发其它相关文章:

        http://blog.youkuaiyun.com/ChengKing/category/288694.aspx

 

 

 

 

 

 

  


(一). 概述

        1. 实现GridView表头固定表体滚动效果

        2. 继承GridView的所有功能, 增加扩展功能, 表体滚动功能; 不需要另外加辅助滚动控件, 如

.

        3. 支持多行表头滚动, 此控件能够自动检测到使用者增加的表头的行数. 准确的实现表头滚动.

            有增加GridView多表头实现方案, 请看[多表头自定义控件]. 

实现原理:
    一般要实现GridView表头固定,表体滚动功能时,都是自己增加一个
控件,
然后将GridView嵌套在这个
控件里面; 使用这个 GridView 控件就不用在页面中自己
增加个
控件了, 因为它自动完成了增加
控件的功能, 具有通用性 .

(二). 运行如图

      1.  单行表头增加自动滚动效果

 

      2.  多行表头增加自动滚动效果

  

 

(三). 用法

   1. 将GridViewExpendHeader控件Dll添加引用到Web站点工程中

   2. 从工具箱拖动一个GridViewExpendHeader控件到设计器中

   3. 设置GridViewExpendHeader控件的属性.

                a.  设置属性窗口中新增的 "扩展" 类别中的两个属性,  这两个属性是指滚动区域的大小, 如下图所示:

                        

               b.  设置GridView本身的高度Height, 这个高度是指滚动区域内的GridView的实际高度, 这个高度数值设置

                     要大于ScrollHeight滚动条才能够呈现.  简单地说, 本自定义控件自动会实现一个GridView(自己)

                    的父控件

,  然后再把自己放在里面,  如果自己高度小于
高度了,  不用滚动就能够显示

                    全自己的数据, 滚动条就没有呈现的意义了.   这里讲得有点啰嗦.   .        

   4. F5运行即可

(四). 完整代码

    1. 主控件GridViewFixedMultiHeader类代码    

  1       ///   < summary >
  2       ///  Author: [ ChengKing(ZhengJian) ] 
  3       ///  Blog:   Http: // blog.youkuaiyun.com / ChengKing
  4       ///   Date :    2007 / 4 / 3
  5       ///   summary>    
  6     /// <summary>
  7     /// 主控件类, 继承GridView的所有功能
  8     ///  summary>
  9     [ToolboxData("<{0}:GridViewExpendHeader runat=server> ")]
 10     public class GridViewFixedMultiHeader : GridView 
 11     {       
 12         [Description("当需要重新构造Header时触发此事件")]
 13         public event System.EventHandler RebuildHeader;
 14 
 15         private System.Web.UI.WebControls.Panel pnlScroll = new System.Web.UI.WebControls.Panel();
 16 
 17         #region 扩展
 18         /// <summary>
 19         /// 设定滚动容器的宽度
 20         ///  summary>
 21         [Bindable(true)]
 22         [Category("扩展")]
 23         [DefaultValue("500px")]
 24         [Localizable(true)]
 25         [TypeConverter(typeof(UnitConverter))]
 26         public Unit ScrollWidth
 27         {
 28             get
 29             {
 30                 return pnlScroll.Width;
 31             }
 32             set
 33             {
 34                 pnlScroll.Width = value;
 35             }
 36         }
 37 
 38         /// <summary>
 39         /// 设定滚动容器的高度
 40         ///  summary>
 41         [Bindable(true)]
 42         [Category("扩展")]
 43         [DefaultValue("150px")]
 44         [Localizable(true)]
 45         [TypeConverter(typeof(UnitConverter))]
 46         public Unit ScrollHeight
 47         {
 48             get
 49             {
 50                 return pnlScroll.Height;
 51             }
 52             set
 53             {
 54                 pnlScroll.Height = value;
 55             }
 56         }
 57         #endregion
 58 
 59         protected override void OnPreRender(EventArgs e)
 60         {
 61             
 62             StringBuilder sb = new StringBuilder();              
 63             sb.Append(" function Tidy()");
 64             sb.Append(" {");
 65             sb.Append("     var gve = document.getElementById(/""+ this.UniqueID +"/"); ");            
 66             sb.Append("     if( gve.rows.length > 0 )");
 67             sb.Append("     {");
 68             sb.Append("         var a1 = document.getElementById(/"divHeaderContainer/");");
 69             sb.Append("         var table1 = document.createElement(/"table/");");
 70             sb.Append("         var tbody1 = document.createElement(/"tbody/");");
 71             sb.Append("         table1.style.cssText = /"table-layout:fixed;border-style: solid ;border-color:gray; border-width: 1px thin;/";   ");
 72             //sb.Append("         table1.style.cssText = /"table-layout:fixed;color:#CCCCFF;background-color:#003399;font-weight:bold;/";");
 73             sb.Append("         var i;");
 74             sb.Append("         var blnIfFind = false;");
 75             sb.Append("         for( i = gve.rows.length - 1; i >= 0; i-- )");
 76             sb.Append("         {");
 77             sb.Append("             if( gve.rows[i].children(0).tagName.toUpperCase() != /"TH/" && blnIfFind == false )  ");
 78             sb.Append("             {");
 79             sb.Append("                 continue;");
 80             sb.Append("             }");
 81             sb.Append("             if( blnIfFind == false )");
 82             sb.Append("             {");
 83             sb.Append("                 blnIfFind = true; ");
 84             sb.Append("             }");
 85             sb.Append("             if( tbody1.children.length == 0 )");
 86             sb.Append("             {");
 87             sb.Append("                 var newRow = gve.rows[i].cloneNode(true); ");
 88             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");            
 89             sb.Append("                 tbody1.appendChild( newRow ); ");
 90             sb.Append("             }");
 91             sb.Append("             else");
 92             sb.Append("             {");
 93             sb.Append("                 var newRow = gve.rows[i].cloneNode(true);   ");
 94             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");
 95             sb.Append("                 tbody1.insertBefore( newRow , tbody1.firstChild );");
 96             sb.Append("             }");
 97             sb.Append("         }");
 98             sb.Append("         table1.appendChild(tbody1);");
 99             sb.Append("         a1.appendChild(table1); ");
100             sb.Append("         for( i = 0; i < gve.rows.length -1; i++)");
101             sb.Append("         {");
102             sb.Append("             if( gve.rows[0].children(0).tagName.toUpperCase() != /"TH/" )");
103             sb.Append("             {");
104             sb.Append("                 gve.deleteRow(0);   ");
105             sb.Append("                 continue;");
106             sb.Append("             }");
107             sb.Append("             gve.deleteRow(0);   ");
108             sb.Append("             break; ");
109             sb.Append("         }");
110             sb.Append("     }");
111             sb.Append(" }");
112 
113             if (!Page.ClientScript.IsClientScriptBlockRegistered("Tidy"))
114             {
115                 Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Tidy", sb.ToString(),true);
116             }
117 
118             if (!Page.ClientScript.IsStartupScriptRegistered("Init"))
119             {
120                 Page.ClientScript.RegisterStartupScript(this.GetType(), "Init""<script type=/"text/javascript/">window.onload = Tidy;</script> "false);
121             }
122 
123             base.OnPreRender(e);
124         }
125 
126         protected override void Render(HtmlTextWriter writer)
127         {
128             OnRebuildHeader();         
129             base.Render(writer);
130         }
131         protected override void CreateChildControls()
132         {
133             Control parent = this.Parent;
134 
135             if (DesignMode == false)
136             {
137                 //生成头容器<DIV>
138                 System.Web.UI.HtmlControls.HtmlGenericControl div = new System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
139                 div.ID = "divHeaderContainer";
140                 div.Style.Add("width", this.Width.ToString());
141                 parent.Controls.Add(div);
142 
143                 Control gridView = this;
144                 parent.Controls.Remove(gridView);
145                  
146                 pnlScroll.Style.Add("width", this.Width.ToString());
147                 pnlScroll.Style.Add("OVERFLOW-Y""scroll");
148                 pnlScroll.Style.Add("OVERFLOW-X""hidden");
149        
150                 pnlScroll.Controls.Add(this);
151                 parent.Controls.Add(pnlScroll);
152 
153                 ChildControlsCreated = true;
154             }
155 
156             base.CreateChildControls();            
157         }
158     
159         protected virtual void OnRebuildHeader()
160         {
161             //重新构造Head
162             if (RebuildHeader != null)
163             {
164                 RebuildHeaderEventArgs args = new RebuildHeaderEventArgs();
165                 args.GridViewObject = this;
166                 args.HeaderRowObject = this.HeaderRow;
167 
168                 RebuildHeader(this, args);
169             }
170             
171         }       
172     } 

    2. 文件RebuildHeaderEventArgs.cs 代码

 1  ///  
 2     /// Author: [ ChengKing(ZhengJian) ] 
 3     /// Blog:   Http://blog.youkuaiyun.com/ChengKing
 4     /// Date:   2007/4/3
 5     /// 

 6       ///  
 7     /// 承载重构Header事件所需的参数[Author:ChengKing(ZhengJian)]
 8     /// 

 9       public   class  RebuildHeaderEventArgs : EventArgs
10      {
11           private  GridViewFixedMultiHeader _GridViewObject;
12           private  GridViewRow _HeaderRowObject;
13 
14           ///  
15         /// 存储GrivViewExtend对象本身
16         /// 

17           public  GridViewFixedMultiHeader GridViewObject
18          {
19               get
20              {
21                   return  _GridViewObject;
22              }
23               set
24              {
25                  _GridViewObject  =  value;
26              }
27          }
28 
29           ///  
30         /// 存储GrivViewExtend的HeaderRow对象
31         /// 

32           public  GridViewRow HeaderRowObject
33          {
34               get
35              {
36                   return  _HeaderRowObject;
37              }
38               set
39              {
40                  _HeaderRowObject  =  value;
41              }
42          }
43      }

   3. 测试页面文件default.aspx代码, 直接拖动一个控件到设计器就OK了. 不需要设置任何属性.

1 <div>
2    <asp:GridView ID="GridViewFixedMultiHeader1" runat="server"  asp:GridView>                  
3  div>

   4. 在新增自定义事件中增加表头行代码, 这里增加三行表头HeaderRow.
 1  ///  
 2     /// 具体重写方法, 此方法比较灵活, 可以任意设置您需要创建的格式, 比如更复杂的表格
 3     /// 另外, 可以直接从第二个参数中取得控件对象引用
 4     /// 

 5       ///  
 6       ///  
 7       protected   void  GridViewExpend1_RebuildHeader( object  sender, EventArgs e)
 8      {
 9           // 取得参数e中包含的对象的引用        
10          GridViewFixedMultiHeader currentGVE  =  ((RebuildHeaderEventArgs)e).GridViewObject;   // 到操作当前GridView的对象引用
11          GridViewRow currentHeaderRow  =  ((RebuildHeaderEventArgs)e).HeaderRowObject;  /// /到操作当前GridView's HeaderRow的对象引用
12 
13 
14           ///
15           /// /在当前HeaderRow上面增加一行
16           // 创建一个行并设置与GridViewExtend当前的头类型风格一致
17          GridViewRow willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
18          willAddHeaderRow.Font.Bold  =   true ;
19          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
20          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
21          TableCell cell  =   new  TableCell();
22          cell.Text  =   " Number " ;
23          cell.HorizontalAlign  =  HorizontalAlign.Center;
24          willAddHeaderRow.Cells.Add(cell);
25          cell  =   new  TableCell();
26          cell.Text  =   " Detail " ;
27          cell.ColumnSpan  =   2 ;
28          cell.HorizontalAlign  =  HorizontalAlign.Center;
29          willAddHeaderRow.Cells.Add(cell);
30           // 添加到GridView
31          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);
32 
33 
34           ///
35           /// /在当前HeaderRow上面再增加一行
36           // 同样创建一个行并设置与GridViewExtend当前的头类型风格一致
37          willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
38          willAddHeaderRow.Font.Bold  =   true ;
39          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
40          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
41 
42          cell  =   new  TableCell();
43          cell.Text  =   " Fruits category information " ;
44          cell.ColumnSpan  =   3 ;
45          cell.HorizontalAlign  =  HorizontalAlign.Center;
46          willAddHeaderRow.Cells.Add(cell);
47           // 添加到GridView
48          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);  
49       
50           // 还可以继续增加N个表头行;
51           // 不管增加多么, GridView控件都能够自动检测到HeaderRow的个数, 并且能够正确呈现滚动条
52           // ..;  
53           // ..; 
54      }

 

(五). 示例代码下载

        http://www.cnblogs.com/Files/MVP33650/extendgridviewfixedmultiheader.rar

 

(六). 控件开发其它相关文章:

        http://blog.youkuaiyun.com/ChengKing/category/288694.aspx

 

 

 

 

 

 

  


(一). 概述

        1. 实现GridView表头固定表体滚动效果

        2. 继承GridView的所有功能, 增加扩展功能, 表体滚动功能; 不需要另外加辅助滚动控件, 如

.

        3. 支持多行表头滚动, 此控件能够自动检测到使用者增加的表头的行数. 准确的实现表头滚动.

            有增加GridView多表头实现方案, 请看[多表头自定义控件]. 

实现原理:
    一般要实现GridView表头固定,表体滚动功能时,都是自己增加一个
控件,
然后将GridView嵌套在这个
控件里面; 使用这个 GridView 控件就不用在页面中自己
增加个
控件了, 因为它自动完成了增加
控件的功能, 具有通用性 .

(二). 运行如图

      1.  单行表头增加自动滚动效果

 

      2.  多行表头增加自动滚动效果

  

 

(三). 用法

   1. 将GridViewExpendHeader控件Dll添加引用到Web站点工程中

   2. 从工具箱拖动一个GridViewExpendHeader控件到设计器中

   3. 设置GridViewExpendHeader控件的属性.

                a.  设置属性窗口中新增的 "扩展" 类别中的两个属性,  这两个属性是指滚动区域的大小, 如下图所示:

                        

               b.  设置GridView本身的高度Height, 这个高度是指滚动区域内的GridView的实际高度, 这个高度数值设置

                     要大于ScrollHeight滚动条才能够呈现.  简单地说, 本自定义控件自动会实现一个GridView(自己)

                    的父控件

,  然后再把自己放在里面,  如果自己高度小于
高度了,  不用滚动就能够显示

                    全自己的数据, 滚动条就没有呈现的意义了.   这里讲得有点啰嗦.   .        

   4. F5运行即可

(四). 完整代码

    1. 主控件GridViewFixedMultiHeader类代码    

  1       ///   < summary >
  2       ///  Author: [ ChengKing(ZhengJian) ] 
  3       ///  Blog:   Http: // blog.youkuaiyun.com / ChengKing
  4       ///   Date :    2007 / 4 / 3
  5       ///   summary>    
  6     /// <summary>
  7     /// 主控件类, 继承GridView的所有功能
  8     ///  summary>
  9     [ToolboxData("<{0}:GridViewExpendHeader runat=server> ")]
 10     public class GridViewFixedMultiHeader : GridView 
 11     {       
 12         [Description("当需要重新构造Header时触发此事件")]
 13         public event System.EventHandler RebuildHeader;
 14 
 15         private System.Web.UI.WebControls.Panel pnlScroll = new System.Web.UI.WebControls.Panel();
 16 
 17         #region 扩展
 18         /// <summary>
 19         /// 设定滚动容器的宽度
 20         ///  summary>
 21         [Bindable(true)]
 22         [Category("扩展")]
 23         [DefaultValue("500px")]
 24         [Localizable(true)]
 25         [TypeConverter(typeof(UnitConverter))]
 26         public Unit ScrollWidth
 27         {
 28             get
 29             {
 30                 return pnlScroll.Width;
 31             }
 32             set
 33             {
 34                 pnlScroll.Width = value;
 35             }
 36         }
 37 
 38         /// <summary>
 39         /// 设定滚动容器的高度
 40         ///  summary>
 41         [Bindable(true)]
 42         [Category("扩展")]
 43         [DefaultValue("150px")]
 44         [Localizable(true)]
 45         [TypeConverter(typeof(UnitConverter))]
 46         public Unit ScrollHeight
 47         {
 48             get
 49             {
 50                 return pnlScroll.Height;
 51             }
 52             set
 53             {
 54                 pnlScroll.Height = value;
 55             }
 56         }
 57         #endregion
 58 
 59         protected override void OnPreRender(EventArgs e)
 60         {
 61             
 62             StringBuilder sb = new StringBuilder();              
 63             sb.Append(" function Tidy()");
 64             sb.Append(" {");
 65             sb.Append("     var gve = document.getElementById(/""+ this.UniqueID +"/"); ");            
 66             sb.Append("     if( gve.rows.length > 0 )");
 67             sb.Append("     {");
 68             sb.Append("         var a1 = document.getElementById(/"divHeaderContainer/");");
 69             sb.Append("         var table1 = document.createElement(/"table/");");
 70             sb.Append("         var tbody1 = document.createElement(/"tbody/");");
 71             sb.Append("         table1.style.cssText = /"table-layout:fixed;border-style: solid ;border-color:gray; border-width: 1px thin;/";   ");
 72             //sb.Append("         table1.style.cssText = /"table-layout:fixed;color:#CCCCFF;background-color:#003399;font-weight:bold;/";");
 73             sb.Append("         var i;");
 74             sb.Append("         var blnIfFind = false;");
 75             sb.Append("         for( i = gve.rows.length - 1; i >= 0; i-- )");
 76             sb.Append("         {");
 77             sb.Append("             if( gve.rows[i].children(0).tagName.toUpperCase() != /"TH/" && blnIfFind == false )  ");
 78             sb.Append("             {");
 79             sb.Append("                 continue;");
 80             sb.Append("             }");
 81             sb.Append("             if( blnIfFind == false )");
 82             sb.Append("             {");
 83             sb.Append("                 blnIfFind = true; ");
 84             sb.Append("             }");
 85             sb.Append("             if( tbody1.children.length == 0 )");
 86             sb.Append("             {");
 87             sb.Append("                 var newRow = gve.rows[i].cloneNode(true); ");
 88             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");            
 89             sb.Append("                 tbody1.appendChild( newRow ); ");
 90             sb.Append("             }");
 91             sb.Append("             else");
 92             sb.Append("             {");
 93             sb.Append("                 var newRow = gve.rows[i].cloneNode(true);   ");
 94             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");
 95             sb.Append("                 tbody1.insertBefore( newRow , tbody1.firstChild );");
 96             sb.Append("             }");
 97             sb.Append("         }");
 98             sb.Append("         table1.appendChild(tbody1);");
 99             sb.Append("         a1.appendChild(table1); ");
100             sb.Append("         for( i = 0; i < gve.rows.length -1; i++)");
101             sb.Append("         {");
102             sb.Append("             if( gve.rows[0].children(0).tagName.toUpperCase() != /"TH/" )");
103             sb.Append("             {");
104             sb.Append("                 gve.deleteRow(0);   ");
105             sb.Append("                 continue;");
106             sb.Append("             }");
107             sb.Append("             gve.deleteRow(0);   ");
108             sb.Append("             break; ");
109             sb.Append("         }");
110             sb.Append("     }");
111             sb.Append(" }");
112 
113             if (!Page.ClientScript.IsClientScriptBlockRegistered("Tidy"))
114             {
115                 Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Tidy", sb.ToString(),true);
116             }
117 
118             if (!Page.ClientScript.IsStartupScriptRegistered("Init"))
119             {
120                 Page.ClientScript.RegisterStartupScript(this.GetType(), "Init""<script type=/"text/javascript/">window.onload = Tidy;</script> "false);
121             }
122 
123             base.OnPreRender(e);
124         }
125 
126         protected override void Render(HtmlTextWriter writer)
127         {
128             OnRebuildHeader();         
129             base.Render(writer);
130         }
131         protected override void CreateChildControls()
132         {
133             Control parent = this.Parent;
134 
135             if (DesignMode == false)
136             {
137                 //生成头容器<DIV>
138                 System.Web.UI.HtmlControls.HtmlGenericControl div = new System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
139                 div.ID = "divHeaderContainer";
140                 div.Style.Add("width", this.Width.ToString());
141                 parent.Controls.Add(div);
142 
143                 Control gridView = this;
144                 parent.Controls.Remove(gridView);
145                  
146                 pnlScroll.Style.Add("width", this.Width.ToString());
147                 pnlScroll.Style.Add("OVERFLOW-Y""scroll");
148                 pnlScroll.Style.Add("OVERFLOW-X""hidden");
149        
150                 pnlScroll.Controls.Add(this);
151                 parent.Controls.Add(pnlScroll);
152 
153                 ChildControlsCreated = true;
154             }
155 
156             base.CreateChildControls();            
157         }
158     
159         protected virtual void OnRebuildHeader()
160         {
161             //重新构造Head
162             if (RebuildHeader != null)
163             {
164                 RebuildHeaderEventArgs args = new RebuildHeaderEventArgs();
165                 args.GridViewObject = this;
166                 args.HeaderRowObject = this.HeaderRow;
167 
168                 RebuildHeader(this, args);
169             }
170             
171         }       
172     } 

    2. 文件RebuildHeaderEventArgs.cs 代码

 1  ///  
 2     /// Author: [ ChengKing(ZhengJian) ] 
 3     /// Blog:   Http://blog.youkuaiyun.com/ChengKing
 4     /// Date:   2007/4/3
 5     /// 

 6       ///  
 7     /// 承载重构Header事件所需的参数[Author:ChengKing(ZhengJian)]
 8     /// 

 9       public   class  RebuildHeaderEventArgs : EventArgs
10      {
11           private  GridViewFixedMultiHeader _GridViewObject;
12           private  GridViewRow _HeaderRowObject;
13 
14           ///  
15         /// 存储GrivViewExtend对象本身
16         /// 

17           public  GridViewFixedMultiHeader GridViewObject
18          {
19               get
20              {
21                   return  _GridViewObject;
22              }
23               set
24              {
25                  _GridViewObject  =  value;
26              }
27          }
28 
29           ///  
30         /// 存储GrivViewExtend的HeaderRow对象
31         /// 

32           public  GridViewRow HeaderRowObject
33          {
34               get
35              {
36                   return  _HeaderRowObject;
37              }
38               set
39              {
40                  _HeaderRowObject  =  value;
41              }
42          }
43      }

   3. 测试页面文件default.aspx代码, 直接拖动一个控件到设计器就OK了. 不需要设置任何属性.

1 <div>
2    <asp:GridView ID="GridViewFixedMultiHeader1" runat="server"  asp:GridView>                  
3  div>

   4. 在新增自定义事件中增加表头行代码, 这里增加三行表头HeaderRow.
 1  ///  
 2     /// 具体重写方法, 此方法比较灵活, 可以任意设置您需要创建的格式, 比如更复杂的表格
 3     /// 另外, 可以直接从第二个参数中取得控件对象引用
 4     /// 

 5       ///  
 6       ///  
 7       protected   void  GridViewExpend1_RebuildHeader( object  sender, EventArgs e)
 8      {
 9           // 取得参数e中包含的对象的引用        
10          GridViewFixedMultiHeader currentGVE  =  ((RebuildHeaderEventArgs)e).GridViewObject;   // 到操作当前GridView的对象引用
11          GridViewRow currentHeaderRow  =  ((RebuildHeaderEventArgs)e).HeaderRowObject;  /// /到操作当前GridView's HeaderRow的对象引用
12 
13 
14           ///
15           /// /在当前HeaderRow上面增加一行
16           // 创建一个行并设置与GridViewExtend当前的头类型风格一致
17          GridViewRow willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
18          willAddHeaderRow.Font.Bold  =   true ;
19          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
20          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
21          TableCell cell  =   new  TableCell();
22          cell.Text  =   " Number " ;
23          cell.HorizontalAlign  =  HorizontalAlign.Center;
24          willAddHeaderRow.Cells.Add(cell);
25          cell  =   new  TableCell();
26          cell.Text  =   " Detail " ;
27          cell.ColumnSpan  =   2 ;
28          cell.HorizontalAlign  =  HorizontalAlign.Center;
29          willAddHeaderRow.Cells.Add(cell);
30           // 添加到GridView
31          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);
32 
33 
34           ///
35           /// /在当前HeaderRow上面再增加一行
36           // 同样创建一个行并设置与GridViewExtend当前的头类型风格一致
37          willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
38          willAddHeaderRow.Font.Bold  =   true ;
39          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
40          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
41 
42          cell  =   new  TableCell();
43          cell.Text  =   " Fruits category information " ;
44          cell.ColumnSpan  =   3 ;
45          cell.HorizontalAlign  =  HorizontalAlign.Center;
46          willAddHeaderRow.Cells.Add(cell);
47           // 添加到GridView
48          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);  
49       
50           // 还可以继续增加N个表头行;
51           // 不管增加多么, GridView控件都能够自动检测到HeaderRow的个数, 并且能够正确呈现滚动条
52           // ..;  
53           // ..; 
54      }

 

(五). 示例代码下载

        http://www.cnblogs.com/Files/MVP33650/extendgridviewfixedmultiheader.rar

 

(六). 控件开发其它相关文章:

        http://blog.youkuaiyun.com/ChengKing/category/288694.aspx

 

 

 

 

 

 

  


(一). 概述

        1. 实现GridView表头固定表体滚动效果

        2. 继承GridView的所有功能, 增加扩展功能, 表体滚动功能; 不需要另外加辅助滚动控件, 如

.

        3. 支持多行表头滚动, 此控件能够自动检测到使用者增加的表头的行数. 准确的实现表头滚动.

            有增加GridView多表头实现方案, 请看[多表头自定义控件]. 

实现原理:
    一般要实现GridView表头固定,表体滚动功能时,都是自己增加一个
控件,
然后将GridView嵌套在这个
控件里面; 使用这个 GridView 控件就不用在页面中自己
增加个
控件了, 因为它自动完成了增加
控件的功能, 具有通用性 .

(二). 运行如图

      1.  单行表头增加自动滚动效果

 

      2.  多行表头增加自动滚动效果

  

 

(三). 用法

   1. 将GridViewExpendHeader控件Dll添加引用到Web站点工程中

   2. 从工具箱拖动一个GridViewExpendHeader控件到设计器中

   3. 设置GridViewExpendHeader控件的属性.

                a.  设置属性窗口中新增的 "扩展" 类别中的两个属性,  这两个属性是指滚动区域的大小, 如下图所示:

                        

               b.  设置GridView本身的高度Height, 这个高度是指滚动区域内的GridView的实际高度, 这个高度数值设置

                     要大于ScrollHeight滚动条才能够呈现.  简单地说, 本自定义控件自动会实现一个GridView(自己)

                    的父控件

,  然后再把自己放在里面,  如果自己高度小于
高度了,  不用滚动就能够显示

                    全自己的数据, 滚动条就没有呈现的意义了.   这里讲得有点啰嗦.   .        

   4. F5运行即可

(四). 完整代码

    1. 主控件GridViewFixedMultiHeader类代码    

  1       ///   < summary >
  2       ///  Author: [ ChengKing(ZhengJian) ] 
  3       ///  Blog:   Http: // blog.youkuaiyun.com / ChengKing
  4       ///   Date :    2007 / 4 / 3
  5       ///   summary>    
  6     /// <summary>
  7     /// 主控件类, 继承GridView的所有功能
  8     ///  summary>
  9     [ToolboxData("<{0}:GridViewExpendHeader runat=server> ")]
 10     public class GridViewFixedMultiHeader : GridView 
 11     {       
 12         [Description("当需要重新构造Header时触发此事件")]
 13         public event System.EventHandler RebuildHeader;
 14 
 15         private System.Web.UI.WebControls.Panel pnlScroll = new System.Web.UI.WebControls.Panel();
 16 
 17         #region 扩展
 18         /// <summary>
 19         /// 设定滚动容器的宽度
 20         ///  summary>
 21         [Bindable(true)]
 22         [Category("扩展")]
 23         [DefaultValue("500px")]
 24         [Localizable(true)]
 25         [TypeConverter(typeof(UnitConverter))]
 26         public Unit ScrollWidth
 27         {
 28             get
 29             {
 30                 return pnlScroll.Width;
 31             }
 32             set
 33             {
 34                 pnlScroll.Width = value;
 35             }
 36         }
 37 
 38         /// <summary>
 39         /// 设定滚动容器的高度
 40         ///  summary>
 41         [Bindable(true)]
 42         [Category("扩展")]
 43         [DefaultValue("150px")]
 44         [Localizable(true)]
 45         [TypeConverter(typeof(UnitConverter))]
 46         public Unit ScrollHeight
 47         {
 48             get
 49             {
 50                 return pnlScroll.Height;
 51             }
 52             set
 53             {
 54                 pnlScroll.Height = value;
 55             }
 56         }
 57         #endregion
 58 
 59         protected override void OnPreRender(EventArgs e)
 60         {
 61             
 62             StringBuilder sb = new StringBuilder();              
 63             sb.Append(" function Tidy()");
 64             sb.Append(" {");
 65             sb.Append("     var gve = document.getElementById(/""+ this.UniqueID +"/"); ");            
 66             sb.Append("     if( gve.rows.length > 0 )");
 67             sb.Append("     {");
 68             sb.Append("         var a1 = document.getElementById(/"divHeaderContainer/");");
 69             sb.Append("         var table1 = document.createElement(/"table/");");
 70             sb.Append("         var tbody1 = document.createElement(/"tbody/");");
 71             sb.Append("         table1.style.cssText = /"table-layout:fixed;border-style: solid ;border-color:gray; border-width: 1px thin;/";   ");
 72             //sb.Append("         table1.style.cssText = /"table-layout:fixed;color:#CCCCFF;background-color:#003399;font-weight:bold;/";");
 73             sb.Append("         var i;");
 74             sb.Append("         var blnIfFind = false;");
 75             sb.Append("         for( i = gve.rows.length - 1; i >= 0; i-- )");
 76             sb.Append("         {");
 77             sb.Append("             if( gve.rows[i].children(0).tagName.toUpperCase() != /"TH/" && blnIfFind == false )  ");
 78             sb.Append("             {");
 79             sb.Append("                 continue;");
 80             sb.Append("             }");
 81             sb.Append("             if( blnIfFind == false )");
 82             sb.Append("             {");
 83             sb.Append("                 blnIfFind = true; ");
 84             sb.Append("             }");
 85             sb.Append("             if( tbody1.children.length == 0 )");
 86             sb.Append("             {");
 87             sb.Append("                 var newRow = gve.rows[i].cloneNode(true); ");
 88             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");            
 89             sb.Append("                 tbody1.appendChild( newRow ); ");
 90             sb.Append("             }");
 91             sb.Append("             else");
 92             sb.Append("             {");
 93             sb.Append("                 var newRow = gve.rows[i].cloneNode(true);   ");
 94             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");
 95             sb.Append("                 tbody1.insertBefore( newRow , tbody1.firstChild );");
 96             sb.Append("             }");
 97             sb.Append("         }");
 98             sb.Append("         table1.appendChild(tbody1);");
 99             sb.Append("         a1.appendChild(table1); ");
100             sb.Append("         for( i = 0; i < gve.rows.length -1; i++)");
101             sb.Append("         {");
102             sb.Append("             if( gve.rows[0].children(0).tagName.toUpperCase() != /"TH/" )");
103             sb.Append("             {");
104             sb.Append("                 gve.deleteRow(0);   ");
105             sb.Append("                 continue;");
106             sb.Append("             }");
107             sb.Append("             gve.deleteRow(0);   ");
108             sb.Append("             break; ");
109             sb.Append("         }");
110             sb.Append("     }");
111             sb.Append(" }");
112 
113             if (!Page.ClientScript.IsClientScriptBlockRegistered("Tidy"))
114             {
115                 Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Tidy", sb.ToString(),true);
116             }
117 
118             if (!Page.ClientScript.IsStartupScriptRegistered("Init"))
119             {
120                 Page.ClientScript.RegisterStartupScript(this.GetType(), "Init""<script type=/"text/javascript/">window.onload = Tidy;</script> "false);
121             }
122 
123             base.OnPreRender(e);
124         }
125 
126         protected override void Render(HtmlTextWriter writer)
127         {
128             OnRebuildHeader();         
129             base.Render(writer);
130         }
131         protected override void CreateChildControls()
132         {
133             Control parent = this.Parent;
134 
135             if (DesignMode == false)
136             {
137                 //生成头容器<DIV>
138                 System.Web.UI.HtmlControls.HtmlGenericControl div = new System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
139                 div.ID = "divHeaderContainer";
140                 div.Style.Add("width", this.Width.ToString());
141                 parent.Controls.Add(div);
142 
143                 Control gridView = this;
144                 parent.Controls.Remove(gridView);
145                  
146                 pnlScroll.Style.Add("width", this.Width.ToString());
147                 pnlScroll.Style.Add("OVERFLOW-Y""scroll");
148                 pnlScroll.Style.Add("OVERFLOW-X""hidden");
149        
150                 pnlScroll.Controls.Add(this);
151                 parent.Controls.Add(pnlScroll);
152 
153                 ChildControlsCreated = true;
154             }
155 
156             base.CreateChildControls();            
157         }
158     
159         protected virtual void OnRebuildHeader()
160         {
161             //重新构造Head
162             if (RebuildHeader != null)
163             {
164                 RebuildHeaderEventArgs args = new RebuildHeaderEventArgs();
165                 args.GridViewObject = this;
166                 args.HeaderRowObject = this.HeaderRow;
167 
168                 RebuildHeader(this, args);
169             }
170             
171         }       
172     } 

    2. 文件RebuildHeaderEventArgs.cs 代码

 1  ///  
 2     /// Author: [ ChengKing(ZhengJian) ] 
 3     /// Blog:   Http://blog.youkuaiyun.com/ChengKing
 4     /// Date:   2007/4/3
 5     /// 

 6       ///  
 7     /// 承载重构Header事件所需的参数[Author:ChengKing(ZhengJian)]
 8     /// 

 9       public   class  RebuildHeaderEventArgs : EventArgs
10      {
11           private  GridViewFixedMultiHeader _GridViewObject;
12           private  GridViewRow _HeaderRowObject;
13 
14           ///  
15         /// 存储GrivViewExtend对象本身
16         /// 

17           public  GridViewFixedMultiHeader GridViewObject
18          {
19               get
20              {
21                   return  _GridViewObject;
22              }
23               set
24              {
25                  _GridViewObject  =  value;
26              }
27          }
28 
29           ///  
30         /// 存储GrivViewExtend的HeaderRow对象
31         /// 

32           public  GridViewRow HeaderRowObject
33          {
34               get
35              {
36                   return  _HeaderRowObject;
37              }
38               set
39              {
40                  _HeaderRowObject  =  value;
41              }
42          }
43      }

   3. 测试页面文件default.aspx代码, 直接拖动一个控件到设计器就OK了. 不需要设置任何属性.

1 <div>
2    <asp:GridView ID="GridViewFixedMultiHeader1" runat="server"  asp:GridView>                  
3  div>

   4. 在新增自定义事件中增加表头行代码, 这里增加三行表头HeaderRow.
 1  ///  
 2     /// 具体重写方法, 此方法比较灵活, 可以任意设置您需要创建的格式, 比如更复杂的表格
 3     /// 另外, 可以直接从第二个参数中取得控件对象引用
 4     /// 

 5       ///  
 6       ///  
 7       protected   void  GridViewExpend1_RebuildHeader( object  sender, EventArgs e)
 8      {
 9           // 取得参数e中包含的对象的引用        
10          GridViewFixedMultiHeader currentGVE  =  ((RebuildHeaderEventArgs)e).GridViewObject;   // 到操作当前GridView的对象引用
11          GridViewRow currentHeaderRow  =  ((RebuildHeaderEventArgs)e).HeaderRowObject;  /// /到操作当前GridView's HeaderRow的对象引用
12 
13 
14           ///
15           /// /在当前HeaderRow上面增加一行
16           // 创建一个行并设置与GridViewExtend当前的头类型风格一致
17          GridViewRow willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
18          willAddHeaderRow.Font.Bold  =   true ;
19          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
20          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
21          TableCell cell  =   new  TableCell();
22          cell.Text  =   " Number " ;
23          cell.HorizontalAlign  =  HorizontalAlign.Center;
24          willAddHeaderRow.Cells.Add(cell);
25          cell  =   new  TableCell();
26          cell.Text  =   " Detail " ;
27          cell.ColumnSpan  =   2 ;
28          cell.HorizontalAlign  =  HorizontalAlign.Center;
29          willAddHeaderRow.Cells.Add(cell);
30           // 添加到GridView
31          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);
32 
33 
34           ///
35           /// /在当前HeaderRow上面再增加一行
36           // 同样创建一个行并设置与GridViewExtend当前的头类型风格一致
37          willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
38          willAddHeaderRow.Font.Bold  =   true ;
39          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
40          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
41 
42          cell  =   new  TableCell();
43          cell.Text  =   " Fruits category information " ;
44          cell.ColumnSpan  =   3 ;
45          cell.HorizontalAlign  =  HorizontalAlign.Center;
46          willAddHeaderRow.Cells.Add(cell);
47           // 添加到GridView
48          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);  
49       
50           // 还可以继续增加N个表头行;
51           // 不管增加多么, GridView控件都能够自动检测到HeaderRow的个数, 并且能够正确呈现滚动条
52           // ..;  
53           // ..; 
54      }

 

(五). 示例代码下载

        http://www.cnblogs.com/Files/MVP33650/extendgridviewfixedmultiheader.rar

 

(六). 控件开发其它相关文章:

        http://blog.youkuaiyun.com/ChengKing/category/288694.aspx

 

 

 

 

 

 

  


(一). 概述

        1. 实现GridView表头固定表体滚动效果

        2. 继承GridView的所有功能, 增加扩展功能, 表体滚动功能; 不需要另外加辅助滚动控件, 如

.

        3. 支持多行表头滚动, 此控件能够自动检测到使用者增加的表头的行数. 准确的实现表头滚动.

            有增加GridView多表头实现方案, 请看[多表头自定义控件]. 

实现原理:
    一般要实现GridView表头固定,表体滚动功能时,都是自己增加一个
控件,
然后将GridView嵌套在这个
控件里面; 使用这个 GridView 控件就不用在页面中自己
增加个
控件了, 因为它自动完成了增加
控件的功能, 具有通用性 .

(二). 运行如图

      1.  单行表头增加自动滚动效果

 

      2.  多行表头增加自动滚动效果

  

 

(三). 用法

   1. 将GridViewExpendHeader控件Dll添加引用到Web站点工程中

   2. 从工具箱拖动一个GridViewExpendHeader控件到设计器中

   3. 设置GridViewExpendHeader控件的属性.

                a.  设置属性窗口中新增的 "扩展" 类别中的两个属性,  这两个属性是指滚动区域的大小, 如下图所示:

                        

               b.  设置GridView本身的高度Height, 这个高度是指滚动区域内的GridView的实际高度, 这个高度数值设置

                     要大于ScrollHeight滚动条才能够呈现.  简单地说, 本自定义控件自动会实现一个GridView(自己)

                    的父控件

,  然后再把自己放在里面,  如果自己高度小于
高度了,  不用滚动就能够显示

                    全自己的数据, 滚动条就没有呈现的意义了.   这里讲得有点啰嗦.   .        

   4. F5运行即可

(四). 完整代码

    1. 主控件GridViewFixedMultiHeader类代码    

  1       ///   < summary >
  2       ///  Author: [ ChengKing(ZhengJian) ] 
  3       ///  Blog:   Http: // blog.youkuaiyun.com / ChengKing
  4       ///   Date :    2007 / 4 / 3
  5       ///   summary>    
  6     /// <summary>
  7     /// 主控件类, 继承GridView的所有功能
  8     ///  summary>
  9     [ToolboxData("<{0}:GridViewExpendHeader runat=server> ")]
 10     public class GridViewFixedMultiHeader : GridView 
 11     {       
 12         [Description("当需要重新构造Header时触发此事件")]
 13         public event System.EventHandler RebuildHeader;
 14 
 15         private System.Web.UI.WebControls.Panel pnlScroll = new System.Web.UI.WebControls.Panel();
 16 
 17         #region 扩展
 18         /// <summary>
 19         /// 设定滚动容器的宽度
 20         ///  summary>
 21         [Bindable(true)]
 22         [Category("扩展")]
 23         [DefaultValue("500px")]
 24         [Localizable(true)]
 25         [TypeConverter(typeof(UnitConverter))]
 26         public Unit ScrollWidth
 27         {
 28             get
 29             {
 30                 return pnlScroll.Width;
 31             }
 32             set
 33             {
 34                 pnlScroll.Width = value;
 35             }
 36         }
 37 
 38         /// <summary>
 39         /// 设定滚动容器的高度
 40         ///  summary>
 41         [Bindable(true)]
 42         [Category("扩展")]
 43         [DefaultValue("150px")]
 44         [Localizable(true)]
 45         [TypeConverter(typeof(UnitConverter))]
 46         public Unit ScrollHeight
 47         {
 48             get
 49             {
 50                 return pnlScroll.Height;
 51             }
 52             set
 53             {
 54                 pnlScroll.Height = value;
 55             }
 56         }
 57         #endregion
 58 
 59         protected override void OnPreRender(EventArgs e)
 60         {
 61             
 62             StringBuilder sb = new StringBuilder();              
 63             sb.Append(" function Tidy()");
 64             sb.Append(" {");
 65             sb.Append("     var gve = document.getElementById(/""+ this.UniqueID +"/"); ");            
 66             sb.Append("     if( gve.rows.length > 0 )");
 67             sb.Append("     {");
 68             sb.Append("         var a1 = document.getElementById(/"divHeaderContainer/");");
 69             sb.Append("         var table1 = document.createElement(/"table/");");
 70             sb.Append("         var tbody1 = document.createElement(/"tbody/");");
 71             sb.Append("         table1.style.cssText = /"table-layout:fixed;border-style: solid ;border-color:gray; border-width: 1px thin;/";   ");
 72             //sb.Append("         table1.style.cssText = /"table-layout:fixed;color:#CCCCFF;background-color:#003399;font-weight:bold;/";");
 73             sb.Append("         var i;");
 74             sb.Append("         var blnIfFind = false;");
 75             sb.Append("         for( i = gve.rows.length - 1; i >= 0; i-- )");
 76             sb.Append("         {");
 77             sb.Append("             if( gve.rows[i].children(0).tagName.toUpperCase() != /"TH/" && blnIfFind == false )  ");
 78             sb.Append("             {");
 79             sb.Append("                 continue;");
 80             sb.Append("             }");
 81             sb.Append("             if( blnIfFind == false )");
 82             sb.Append("             {");
 83             sb.Append("                 blnIfFind = true; ");
 84             sb.Append("             }");
 85             sb.Append("             if( tbody1.children.length == 0 )");
 86             sb.Append("             {");
 87             sb.Append("                 var newRow = gve.rows[i].cloneNode(true); ");
 88             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");            
 89             sb.Append("                 tbody1.appendChild( newRow ); ");
 90             sb.Append("             }");
 91             sb.Append("             else");
 92             sb.Append("             {");
 93             sb.Append("                 var newRow = gve.rows[i].cloneNode(true);   ");
 94             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");
 95             sb.Append("                 tbody1.insertBefore( newRow , tbody1.firstChild );");
 96             sb.Append("             }");
 97             sb.Append("         }");
 98             sb.Append("         table1.appendChild(tbody1);");
 99             sb.Append("         a1.appendChild(table1); ");
100             sb.Append("         for( i = 0; i < gve.rows.length -1; i++)");
101             sb.Append("         {");
102             sb.Append("             if( gve.rows[0].children(0).tagName.toUpperCase() != /"TH/" )");
103             sb.Append("             {");
104             sb.Append("                 gve.deleteRow(0);   ");
105             sb.Append("                 continue;");
106             sb.Append("             }");
107             sb.Append("             gve.deleteRow(0);   ");
108             sb.Append("             break; ");
109             sb.Append("         }");
110             sb.Append("     }");
111             sb.Append(" }");
112 
113             if (!Page.ClientScript.IsClientScriptBlockRegistered("Tidy"))
114             {
115                 Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Tidy", sb.ToString(),true);
116             }
117 
118             if (!Page.ClientScript.IsStartupScriptRegistered("Init"))
119             {
120                 Page.ClientScript.RegisterStartupScript(this.GetType(), "Init""<script type=/"text/javascript/">window.onload = Tidy;</script> "false);
121             }
122 
123             base.OnPreRender(e);
124         }
125 
126         protected override void Render(HtmlTextWriter writer)
127         {
128             OnRebuildHeader();         
129             base.Render(writer);
130         }
131         protected override void CreateChildControls()
132         {
133             Control parent = this.Parent;
134 
135             if (DesignMode == false)
136             {
137                 //生成头容器<DIV>
138                 System.Web.UI.HtmlControls.HtmlGenericControl div = new System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
139                 div.ID = "divHeaderContainer";
140                 div.Style.Add("width", this.Width.ToString());
141                 parent.Controls.Add(div);
142 
143                 Control gridView = this;
144                 parent.Controls.Remove(gridView);
145                  
146                 pnlScroll.Style.Add("width", this.Width.ToString());
147                 pnlScroll.Style.Add("OVERFLOW-Y""scroll");
148                 pnlScroll.Style.Add("OVERFLOW-X""hidden");
149        
150                 pnlScroll.Controls.Add(this);
151                 parent.Controls.Add(pnlScroll);
152 
153                 ChildControlsCreated = true;
154             }
155 
156             base.CreateChildControls();            
157         }
158     
159         protected virtual void OnRebuildHeader()
160         {
161             //重新构造Head
162             if (RebuildHeader != null)
163             {
164                 RebuildHeaderEventArgs args = new RebuildHeaderEventArgs();
165                 args.GridViewObject = this;
166                 args.HeaderRowObject = this.HeaderRow;
167 
168                 RebuildHeader(this, args);
169             }
170             
171         }       
172     } 

    2. 文件RebuildHeaderEventArgs.cs 代码

 1  ///  
 2     /// Author: [ ChengKing(ZhengJian) ] 
 3     /// Blog:   Http://blog.youkuaiyun.com/ChengKing
 4     /// Date:   2007/4/3
 5     /// 

 6       ///  
 7     /// 承载重构Header事件所需的参数[Author:ChengKing(ZhengJian)]
 8     /// 

 9       public   class  RebuildHeaderEventArgs : EventArgs
10      {
11           private  GridViewFixedMultiHeader _GridViewObject;
12           private  GridViewRow _HeaderRowObject;
13 
14           ///  
15         /// 存储GrivViewExtend对象本身
16         /// 

17           public  GridViewFixedMultiHeader GridViewObject
18          {
19               get
20              {
21                   return  _GridViewObject;
22              }
23               set
24              {
25                  _GridViewObject  =  value;
26              }
27          }
28 
29           ///  
30         /// 存储GrivViewExtend的HeaderRow对象
31         /// 

32           public  GridViewRow HeaderRowObject
33          {
34               get
35              {
36                   return  _HeaderRowObject;
37              }
38               set
39              {
40                  _HeaderRowObject  =  value;
41              }
42          }
43      }

   3. 测试页面文件default.aspx代码, 直接拖动一个控件到设计器就OK了. 不需要设置任何属性.

1 <div>
2    <asp:GridView ID="GridViewFixedMultiHeader1" runat="server"  asp:GridView>                  
3  div>

   4. 在新增自定义事件中增加表头行代码, 这里增加三行表头HeaderRow.
 1  ///  
 2     /// 具体重写方法, 此方法比较灵活, 可以任意设置您需要创建的格式, 比如更复杂的表格
 3     /// 另外, 可以直接从第二个参数中取得控件对象引用
 4     /// 

 5       ///  
 6       ///  
 7       protected   void  GridViewExpend1_RebuildHeader( object  sender, EventArgs e)
 8      {
 9           // 取得参数e中包含的对象的引用        
10          GridViewFixedMultiHeader currentGVE  =  ((RebuildHeaderEventArgs)e).GridViewObject;   // 到操作当前GridView的对象引用
11          GridViewRow currentHeaderRow  =  ((RebuildHeaderEventArgs)e).HeaderRowObject;  /// /到操作当前GridView's HeaderRow的对象引用
12 
13 
14           ///
15           /// /在当前HeaderRow上面增加一行
16           // 创建一个行并设置与GridViewExtend当前的头类型风格一致
17          GridViewRow willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
18          willAddHeaderRow.Font.Bold  =   true ;
19          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
20          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
21          TableCell cell  =   new  TableCell();
22          cell.Text  =   " Number " ;
23          cell.HorizontalAlign  =  HorizontalAlign.Center;
24          willAddHeaderRow.Cells.Add(cell);
25          cell  =   new  TableCell();
26          cell.Text  =   " Detail " ;
27          cell.ColumnSpan  =   2 ;
28          cell.HorizontalAlign  =  HorizontalAlign.Center;
29          willAddHeaderRow.Cells.Add(cell);
30           // 添加到GridView
31          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);
32 
33 
34           ///
35           /// /在当前HeaderRow上面再增加一行
36           // 同样创建一个行并设置与GridViewExtend当前的头类型风格一致
37          willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
38          willAddHeaderRow.Font.Bold  =   true ;
39          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
40          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
41 
42          cell  =   new  TableCell();
43          cell.Text  =   " Fruits category information " ;
44          cell.ColumnSpan  =   3 ;
45          cell.HorizontalAlign  =  HorizontalAlign.Center;
46          willAddHeaderRow.Cells.Add(cell);
47           // 添加到GridView
48          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);  
49       
50           // 还可以继续增加N个表头行;
51           // 不管增加多么, GridView控件都能够自动检测到HeaderRow的个数, 并且能够正确呈现滚动条
52           // ..;  
53           // ..; 
54      }

 

(五). 示例代码下载

        http://www.cnblogs.com/Files/MVP33650/extendgridviewfixedmultiheader.rar

 

(六). 控件开发其它相关文章:

        http://blog.youkuaiyun.com/ChengKing/category/288694.aspx

 

 

 

 

 

 

  


(一). 概述

        1. 实现GridView表头固定表体滚动效果

        2. 继承GridView的所有功能, 增加扩展功能, 表体滚动功能; 不需要另外加辅助滚动控件, 如

.

        3. 支持多行表头滚动, 此控件能够自动检测到使用者增加的表头的行数. 准确的实现表头滚动.

            有增加GridView多表头实现方案, 请看[多表头自定义控件]. 

实现原理:
    一般要实现GridView表头固定,表体滚动功能时,都是自己增加一个
控件,
然后将GridView嵌套在这个
控件里面; 使用这个 GridView 控件就不用在页面中自己
增加个
控件了, 因为它自动完成了增加
控件的功能, 具有通用性 .

(二). 运行如图

      1.  单行表头增加自动滚动效果

 

      2.  多行表头增加自动滚动效果

  

 

(三). 用法

   1. 将GridViewExpendHeader控件Dll添加引用到Web站点工程中

   2. 从工具箱拖动一个GridViewExpendHeader控件到设计器中

   3. 设置GridViewExpendHeader控件的属性.

                a.  设置属性窗口中新增的 "扩展" 类别中的两个属性,  这两个属性是指滚动区域的大小, 如下图所示:

                        

               b.  设置GridView本身的高度Height, 这个高度是指滚动区域内的GridView的实际高度, 这个高度数值设置

                     要大于ScrollHeight滚动条才能够呈现.  简单地说, 本自定义控件自动会实现一个GridView(自己)

                    的父控件

,  然后再把自己放在里面,  如果自己高度小于
高度了,  不用滚动就能够显示

                    全自己的数据, 滚动条就没有呈现的意义了.   这里讲得有点啰嗦.   .        

   4. F5运行即可

(四). 完整代码

    1. 主控件GridViewFixedMultiHeader类代码    

  1       ///   < summary >
  2       ///  Author: [ ChengKing(ZhengJian) ] 
  3       ///  Blog:   Http: // blog.youkuaiyun.com / ChengKing
  4       ///   Date :    2007 / 4 / 3
  5       ///   summary>    
  6     /// <summary>
  7     /// 主控件类, 继承GridView的所有功能
  8     ///  summary>
  9     [ToolboxData("<{0}:GridViewExpendHeader runat=server> ")]
 10     public class GridViewFixedMultiHeader : GridView 
 11     {       
 12         [Description("当需要重新构造Header时触发此事件")]
 13         public event System.EventHandler RebuildHeader;
 14 
 15         private System.Web.UI.WebControls.Panel pnlScroll = new System.Web.UI.WebControls.Panel();
 16 
 17         #region 扩展
 18         /// <summary>
 19         /// 设定滚动容器的宽度
 20         ///  summary>
 21         [Bindable(true)]
 22         [Category("扩展")]
 23         [DefaultValue("500px")]
 24         [Localizable(true)]
 25         [TypeConverter(typeof(UnitConverter))]
 26         public Unit ScrollWidth
 27         {
 28             get
 29             {
 30                 return pnlScroll.Width;
 31             }
 32             set
 33             {
 34                 pnlScroll.Width = value;
 35             }
 36         }
 37 
 38         /// <summary>
 39         /// 设定滚动容器的高度
 40         ///  summary>
 41         [Bindable(true)]
 42         [Category("扩展")]
 43         [DefaultValue("150px")]
 44         [Localizable(true)]
 45         [TypeConverter(typeof(UnitConverter))]
 46         public Unit ScrollHeight
 47         {
 48             get
 49             {
 50                 return pnlScroll.Height;
 51             }
 52             set
 53             {
 54                 pnlScroll.Height = value;
 55             }
 56         }
 57         #endregion
 58 
 59         protected override void OnPreRender(EventArgs e)
 60         {
 61             
 62             StringBuilder sb = new StringBuilder();              
 63             sb.Append(" function Tidy()");
 64             sb.Append(" {");
 65             sb.Append("     var gve = document.getElementById(/""+ this.UniqueID +"/"); ");            
 66             sb.Append("     if( gve.rows.length > 0 )");
 67             sb.Append("     {");
 68             sb.Append("         var a1 = document.getElementById(/"divHeaderContainer/");");
 69             sb.Append("         var table1 = document.createElement(/"table/");");
 70             sb.Append("         var tbody1 = document.createElement(/"tbody/");");
 71             sb.Append("         table1.style.cssText = /"table-layout:fixed;border-style: solid ;border-color:gray; border-width: 1px thin;/";   ");
 72             //sb.Append("         table1.style.cssText = /"table-layout:fixed;color:#CCCCFF;background-color:#003399;font-weight:bold;/";");
 73             sb.Append("         var i;");
 74             sb.Append("         var blnIfFind = false;");
 75             sb.Append("         for( i = gve.rows.length - 1; i >= 0; i-- )");
 76             sb.Append("         {");
 77             sb.Append("             if( gve.rows[i].children(0).tagName.toUpperCase() != /"TH/" && blnIfFind == false )  ");
 78             sb.Append("             {");
 79             sb.Append("                 continue;");
 80             sb.Append("             }");
 81             sb.Append("             if( blnIfFind == false )");
 82             sb.Append("             {");
 83             sb.Append("                 blnIfFind = true; ");
 84             sb.Append("             }");
 85             sb.Append("             if( tbody1.children.length == 0 )");
 86             sb.Append("             {");
 87             sb.Append("                 var newRow = gve.rows[i].cloneNode(true); ");
 88             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");            
 89             sb.Append("                 tbody1.appendChild( newRow ); ");
 90             sb.Append("             }");
 91             sb.Append("             else");
 92             sb.Append("             {");
 93             sb.Append("                 var newRow = gve.rows[i].cloneNode(true);   ");
 94             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");
 95             sb.Append("                 tbody1.insertBefore( newRow , tbody1.firstChild );");
 96             sb.Append("             }");
 97             sb.Append("         }");
 98             sb.Append("         table1.appendChild(tbody1);");
 99             sb.Append("         a1.appendChild(table1); ");
100             sb.Append("         for( i = 0; i < gve.rows.length -1; i++)");
101             sb.Append("         {");
102             sb.Append("             if( gve.rows[0].children(0).tagName.toUpperCase() != /"TH/" )");
103             sb.Append("             {");
104             sb.Append("                 gve.deleteRow(0);   ");
105             sb.Append("                 continue;");
106             sb.Append("             }");
107             sb.Append("             gve.deleteRow(0);   ");
108             sb.Append("             break; ");
109             sb.Append("         }");
110             sb.Append("     }");
111             sb.Append(" }");
112 
113             if (!Page.ClientScript.IsClientScriptBlockRegistered("Tidy"))
114             {
115                 Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Tidy", sb.ToString(),true);
116             }
117 
118             if (!Page.ClientScript.IsStartupScriptRegistered("Init"))
119             {
120                 Page.ClientScript.RegisterStartupScript(this.GetType(), "Init""<script type=/"text/javascript/">window.onload = Tidy;</script> "false);
121             }
122 
123             base.OnPreRender(e);
124         }
125 
126         protected override void Render(HtmlTextWriter writer)
127         {
128             OnRebuildHeader();         
129             base.Render(writer);
130         }
131         protected override void CreateChildControls()
132         {
133             Control parent = this.Parent;
134 
135             if (DesignMode == false)
136             {
137                 //生成头容器<DIV>
138                 System.Web.UI.HtmlControls.HtmlGenericControl div = new System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
139                 div.ID = "divHeaderContainer";
140                 div.Style.Add("width", this.Width.ToString());
141                 parent.Controls.Add(div);
142 
143                 Control gridView = this;
144                 parent.Controls.Remove(gridView);
145                  
146                 pnlScroll.Style.Add("width", this.Width.ToString());
147                 pnlScroll.Style.Add("OVERFLOW-Y""scroll");
148                 pnlScroll.Style.Add("OVERFLOW-X""hidden");
149        
150                 pnlScroll.Controls.Add(this);
151                 parent.Controls.Add(pnlScroll);
152 
153                 ChildControlsCreated = true;
154             }
155 
156             base.CreateChildControls();            
157         }
158     
159         protected virtual void OnRebuildHeader()
160         {
161             //重新构造Head
162             if (RebuildHeader != null)
163             {
164                 RebuildHeaderEventArgs args = new RebuildHeaderEventArgs();
165                 args.GridViewObject = this;
166                 args.HeaderRowObject = this.HeaderRow;
167 
168                 RebuildHeader(this, args);
169             }
170             
171         }       
172     } 

    2. 文件RebuildHeaderEventArgs.cs 代码

 1  ///  
 2     /// Author: [ ChengKing(ZhengJian) ] 
 3     /// Blog:   Http://blog.youkuaiyun.com/ChengKing
 4     /// Date:   2007/4/3
 5     /// 

 6       ///  
 7     /// 承载重构Header事件所需的参数[Author:ChengKing(ZhengJian)]
 8     /// 

 9       public   class  RebuildHeaderEventArgs : EventArgs
10      {
11           private  GridViewFixedMultiHeader _GridViewObject;
12           private  GridViewRow _HeaderRowObject;
13 
14           ///  
15         /// 存储GrivViewExtend对象本身
16         /// 

17           public  GridViewFixedMultiHeader GridViewObject
18          {
19               get
20              {
21                   return  _GridViewObject;
22              }
23               set
24              {
25                  _GridViewObject  =  value;
26              }
27          }
28 
29           ///  
30         /// 存储GrivViewExtend的HeaderRow对象
31         /// 

32           public  GridViewRow HeaderRowObject
33          {
34               get
35              {
36                   return  _HeaderRowObject;
37              }
38               set
39              {
40                  _HeaderRowObject  =  value;
41              }
42          }
43      }

   3. 测试页面文件default.aspx代码, 直接拖动一个控件到设计器就OK了. 不需要设置任何属性.

1 <div>
2    <asp:GridView ID="GridViewFixedMultiHeader1" runat="server"  asp:GridView>                  
3  div>

   4. 在新增自定义事件中增加表头行代码, 这里增加三行表头HeaderRow.
 1  ///  
 2     /// 具体重写方法, 此方法比较灵活, 可以任意设置您需要创建的格式, 比如更复杂的表格
 3     /// 另外, 可以直接从第二个参数中取得控件对象引用
 4     /// 

 5       ///  
 6       ///  
 7       protected   void  GridViewExpend1_RebuildHeader( object  sender, EventArgs e)
 8      {
 9           // 取得参数e中包含的对象的引用        
10          GridViewFixedMultiHeader currentGVE  =  ((RebuildHeaderEventArgs)e).GridViewObject;   // 到操作当前GridView的对象引用
11          GridViewRow currentHeaderRow  =  ((RebuildHeaderEventArgs)e).HeaderRowObject;  /// /到操作当前GridView's HeaderRow的对象引用
12 
13 
14           ///
15           /// /在当前HeaderRow上面增加一行
16           // 创建一个行并设置与GridViewExtend当前的头类型风格一致
17          GridViewRow willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
18          willAddHeaderRow.Font.Bold  =   true ;
19          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
20          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
21          TableCell cell  =   new  TableCell();
22          cell.Text  =   " Number " ;
23          cell.HorizontalAlign  =  HorizontalAlign.Center;
24          willAddHeaderRow.Cells.Add(cell);
25          cell  =   new  TableCell();
26          cell.Text  =   " Detail " ;
27          cell.ColumnSpan  =   2 ;
28          cell.HorizontalAlign  =  HorizontalAlign.Center;
29          willAddHeaderRow.Cells.Add(cell);
30           // 添加到GridView
31          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);
32 
33 
34           ///
35           /// /在当前HeaderRow上面再增加一行
36           // 同样创建一个行并设置与GridViewExtend当前的头类型风格一致
37          willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
38          willAddHeaderRow.Font.Bold  =   true ;
39          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
40          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
41 
42          cell  =   new  TableCell();
43          cell.Text  =   " Fruits category information " ;
44          cell.ColumnSpan  =   3 ;
45          cell.HorizontalAlign  =  HorizontalAlign.Center;
46          willAddHeaderRow.Cells.Add(cell);
47           // 添加到GridView
48          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);  
49       
50           // 还可以继续增加N个表头行;
51           // 不管增加多么, GridView控件都能够自动检测到HeaderRow的个数, 并且能够正确呈现滚动条
52           // ..;  
53           // ..; 
54      }

 

(五). 示例代码下载

        http://www.cnblogs.com/Files/MVP33650/extendgridviewfixedmultiheader.rar

 

(六). 控件开发其它相关文章:

        http://blog.youkuaiyun.com/ChengKing/category/288694.aspx

 

 

 

 

 

 

  


(一). 概述

        1. 实现GridView表头固定表体滚动效果

        2. 继承GridView的所有功能, 增加扩展功能, 表体滚动功能; 不需要另外加辅助滚动控件, 如

.

        3. 支持多行表头滚动, 此控件能够自动检测到使用者增加的表头的行数. 准确的实现表头滚动.

            有增加GridView多表头实现方案, 请看[多表头自定义控件]. 

实现原理:
    一般要实现GridView表头固定,表体滚动功能时,都是自己增加一个
控件,
然后将GridView嵌套在这个
控件里面; 使用这个 GridView 控件就不用在页面中自己
增加个
控件了, 因为它自动完成了增加
控件的功能, 具有通用性 .

(二). 运行如图

      1.  单行表头增加自动滚动效果

 

      2.  多行表头增加自动滚动效果

  

 

(三). 用法

   1. 将GridViewExpendHeader控件Dll添加引用到Web站点工程中

   2. 从工具箱拖动一个GridViewExpendHeader控件到设计器中

   3. 设置GridViewExpendHeader控件的属性.

                a.  设置属性窗口中新增的 "扩展" 类别中的两个属性,  这两个属性是指滚动区域的大小, 如下图所示:

                        

               b.  设置GridView本身的高度Height, 这个高度是指滚动区域内的GridView的实际高度, 这个高度数值设置

                     要大于ScrollHeight滚动条才能够呈现.  简单地说, 本自定义控件自动会实现一个GridView(自己)

                    的父控件

,  然后再把自己放在里面,  如果自己高度小于
高度了,  不用滚动就能够显示

                    全自己的数据, 滚动条就没有呈现的意义了.   这里讲得有点啰嗦.   .        

   4. F5运行即可

(四). 完整代码

    1. 主控件GridViewFixedMultiHeader类代码    

  1       ///   < summary >
  2       ///  Author: [ ChengKing(ZhengJian) ] 
  3       ///  Blog:   Http: // blog.youkuaiyun.com / ChengKing
  4       ///   Date :    2007 / 4 / 3
  5       ///   summary>    
  6     /// <summary>
  7     /// 主控件类, 继承GridView的所有功能
  8     ///  summary>
  9     [ToolboxData("<{0}:GridViewExpendHeader runat=server> ")]
 10     public class GridViewFixedMultiHeader : GridView 
 11     {       
 12         [Description("当需要重新构造Header时触发此事件")]
 13         public event System.EventHandler RebuildHeader;
 14 
 15         private System.Web.UI.WebControls.Panel pnlScroll = new System.Web.UI.WebControls.Panel();
 16 
 17         #region 扩展
 18         /// <summary>
 19         /// 设定滚动容器的宽度
 20         ///  summary>
 21         [Bindable(true)]
 22         [Category("扩展")]
 23         [DefaultValue("500px")]
 24         [Localizable(true)]
 25         [TypeConverter(typeof(UnitConverter))]
 26         public Unit ScrollWidth
 27         {
 28             get
 29             {
 30                 return pnlScroll.Width;
 31             }
 32             set
 33             {
 34                 pnlScroll.Width = value;
 35             }
 36         }
 37 
 38         /// <summary>
 39         /// 设定滚动容器的高度
 40         ///  summary>
 41         [Bindable(true)]
 42         [Category("扩展")]
 43         [DefaultValue("150px")]
 44         [Localizable(true)]
 45         [TypeConverter(typeof(UnitConverter))]
 46         public Unit ScrollHeight
 47         {
 48             get
 49             {
 50                 return pnlScroll.Height;
 51             }
 52             set
 53             {
 54                 pnlScroll.Height = value;
 55             }
 56         }
 57         #endregion
 58 
 59         protected override void OnPreRender(EventArgs e)
 60         {
 61             
 62             StringBuilder sb = new StringBuilder();              
 63             sb.Append(" function Tidy()");
 64             sb.Append(" {");
 65             sb.Append("     var gve = document.getElementById(/""+ this.UniqueID +"/"); ");            
 66             sb.Append("     if( gve.rows.length > 0 )");
 67             sb.Append("     {");
 68             sb.Append("         var a1 = document.getElementById(/"divHeaderContainer/");");
 69             sb.Append("         var table1 = document.createElement(/"table/");");
 70             sb.Append("         var tbody1 = document.createElement(/"tbody/");");
 71             sb.Append("         table1.style.cssText = /"table-layout:fixed;border-style: solid ;border-color:gray; border-width: 1px thin;/";   ");
 72             //sb.Append("         table1.style.cssText = /"table-layout:fixed;color:#CCCCFF;background-color:#003399;font-weight:bold;/";");
 73             sb.Append("         var i;");
 74             sb.Append("         var blnIfFind = false;");
 75             sb.Append("         for( i = gve.rows.length - 1; i >= 0; i-- )");
 76             sb.Append("         {");
 77             sb.Append("             if( gve.rows[i].children(0).tagName.toUpperCase() != /"TH/" && blnIfFind == false )  ");
 78             sb.Append("             {");
 79             sb.Append("                 continue;");
 80             sb.Append("             }");
 81             sb.Append("             if( blnIfFind == false )");
 82             sb.Append("             {");
 83             sb.Append("                 blnIfFind = true; ");
 84             sb.Append("             }");
 85             sb.Append("             if( tbody1.children.length == 0 )");
 86             sb.Append("             {");
 87             sb.Append("                 var newRow = gve.rows[i].cloneNode(true); ");
 88             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");            
 89             sb.Append("                 tbody1.appendChild( newRow ); ");
 90             sb.Append("             }");
 91             sb.Append("             else");
 92             sb.Append("             {");
 93             sb.Append("                 var newRow = gve.rows[i].cloneNode(true);   ");
 94             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");
 95             sb.Append("                 tbody1.insertBefore( newRow , tbody1.firstChild );");
 96             sb.Append("             }");
 97             sb.Append("         }");
 98             sb.Append("         table1.appendChild(tbody1);");
 99             sb.Append("         a1.appendChild(table1); ");
100             sb.Append("         for( i = 0; i < gve.rows.length -1; i++)");
101             sb.Append("         {");
102             sb.Append("             if( gve.rows[0].children(0).tagName.toUpperCase() != /"TH/" )");
103             sb.Append("             {");
104             sb.Append("                 gve.deleteRow(0);   ");
105             sb.Append("                 continue;");
106             sb.Append("             }");
107             sb.Append("             gve.deleteRow(0);   ");
108             sb.Append("             break; ");
109             sb.Append("         }");
110             sb.Append("     }");
111             sb.Append(" }");
112 
113             if (!Page.ClientScript.IsClientScriptBlockRegistered("Tidy"))
114             {
115                 Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Tidy", sb.ToString(),true);
116             }
117 
118             if (!Page.ClientScript.IsStartupScriptRegistered("Init"))
119             {
120                 Page.ClientScript.RegisterStartupScript(this.GetType(), "Init""<script type=/"text/javascript/">window.onload = Tidy;</script> "false);
121             }
122 
123             base.OnPreRender(e);
124         }
125 
126         protected override void Render(HtmlTextWriter writer)
127         {
128             OnRebuildHeader();         
129             base.Render(writer);
130         }
131         protected override void CreateChildControls()
132         {
133             Control parent = this.Parent;
134 
135             if (DesignMode == false)
136             {
137                 //生成头容器<DIV>
138                 System.Web.UI.HtmlControls.HtmlGenericControl div = new System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
139                 div.ID = "divHeaderContainer";
140                 div.Style.Add("width", this.Width.ToString());
141                 parent.Controls.Add(div);
142 
143                 Control gridView = this;
144                 parent.Controls.Remove(gridView);
145                  
146                 pnlScroll.Style.Add("width", this.Width.ToString());
147                 pnlScroll.Style.Add("OVERFLOW-Y""scroll");
148                 pnlScroll.Style.Add("OVERFLOW-X""hidden");
149        
150                 pnlScroll.Controls.Add(this);
151                 parent.Controls.Add(pnlScroll);
152 
153                 ChildControlsCreated = true;
154             }
155 
156             base.CreateChildControls();            
157         }
158     
159         protected virtual void OnRebuildHeader()
160         {
161             //重新构造Head
162             if (RebuildHeader != null)
163             {
164                 RebuildHeaderEventArgs args = new RebuildHeaderEventArgs();
165                 args.GridViewObject = this;
166                 args.HeaderRowObject = this.HeaderRow;
167 
168                 RebuildHeader(this, args);
169             }
170             
171         }       
172     } 

    2. 文件RebuildHeaderEventArgs.cs 代码

 1  ///  
 2     /// Author: [ ChengKing(ZhengJian) ] 
 3     /// Blog:   Http://blog.youkuaiyun.com/ChengKing
 4     /// Date:   2007/4/3
 5     /// 

 6       ///  
 7     /// 承载重构Header事件所需的参数[Author:ChengKing(ZhengJian)]
 8     /// 

 9       public   class  RebuildHeaderEventArgs : EventArgs
10      {
11           private  GridViewFixedMultiHeader _GridViewObject;
12           private  GridViewRow _HeaderRowObject;
13 
14           ///  
15         /// 存储GrivViewExtend对象本身
16         /// 

17           public  GridViewFixedMultiHeader GridViewObject
18          {
19               get
20              {
21                   return  _GridViewObject;
22              }
23               set
24              {
25                  _GridViewObject  =  value;
26              }
27          }
28 
29           ///  
30         /// 存储GrivViewExtend的HeaderRow对象
31         /// 

32           public  GridViewRow HeaderRowObject
33          {
34               get
35              {
36                   return  _HeaderRowObject;
37              }
38               set
39              {
40                  _HeaderRowObject  =  value;
41              }
42          }
43      }

   3. 测试页面文件default.aspx代码, 直接拖动一个控件到设计器就OK了. 不需要设置任何属性.

1 <div>
2    <asp:GridView ID="GridViewFixedMultiHeader1" runat="server"  asp:GridView>                  
3  div>

   4. 在新增自定义事件中增加表头行代码, 这里增加三行表头HeaderRow.
 1  ///  
 2     /// 具体重写方法, 此方法比较灵活, 可以任意设置您需要创建的格式, 比如更复杂的表格
 3     /// 另外, 可以直接从第二个参数中取得控件对象引用
 4     /// 

 5       ///  
 6       ///  
 7       protected   void  GridViewExpend1_RebuildHeader( object  sender, EventArgs e)
 8      {
 9           // 取得参数e中包含的对象的引用        
10          GridViewFixedMultiHeader currentGVE  =  ((RebuildHeaderEventArgs)e).GridViewObject;   // 到操作当前GridView的对象引用
11          GridViewRow currentHeaderRow  =  ((RebuildHeaderEventArgs)e).HeaderRowObject;  /// /到操作当前GridView's HeaderRow的对象引用
12 
13 
14           ///
15           /// /在当前HeaderRow上面增加一行
16           // 创建一个行并设置与GridViewExtend当前的头类型风格一致
17          GridViewRow willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
18          willAddHeaderRow.Font.Bold  =   true ;
19          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
20          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
21          TableCell cell  =   new  TableCell();
22          cell.Text  =   " Number " ;
23          cell.HorizontalAlign  =  HorizontalAlign.Center;
24          willAddHeaderRow.Cells.Add(cell);
25          cell  =   new  TableCell();
26          cell.Text  =   " Detail " ;
27          cell.ColumnSpan  =   2 ;
28          cell.HorizontalAlign  =  HorizontalAlign.Center;
29          willAddHeaderRow.Cells.Add(cell);
30           // 添加到GridView
31          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);
32 
33 
34           ///
35           /// /在当前HeaderRow上面再增加一行
36           // 同样创建一个行并设置与GridViewExtend当前的头类型风格一致
37          willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
38          willAddHeaderRow.Font.Bold  =   true ;
39          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
40          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
41 
42          cell  =   new  TableCell();
43          cell.Text  =   " Fruits category information " ;
44          cell.ColumnSpan  =   3 ;
45          cell.HorizontalAlign  =  HorizontalAlign.Center;
46          willAddHeaderRow.Cells.Add(cell);
47           // 添加到GridView
48          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);  
49       
50           // 还可以继续增加N个表头行;
51           // 不管增加多么, GridView控件都能够自动检测到HeaderRow的个数, 并且能够正确呈现滚动条
52           // ..;  
53           // ..; 
54      }

 

(五). 示例代码下载

        http://www.cnblogs.com/Files/MVP33650/extendgridviewfixedmultiheader.rar

 

(六). 控件开发其它相关文章:

        http://blog.youkuaiyun.com/ChengKing/category/288694.aspx

 

 

 

 

 

 

  


(一). 概述

        1. 实现GridView表头固定表体滚动效果

        2. 继承GridView的所有功能, 增加扩展功能, 表体滚动功能; 不需要另外加辅助滚动控件, 如

.

        3. 支持多行表头滚动, 此控件能够自动检测到使用者增加的表头的行数. 准确的实现表头滚动.

            有增加GridView多表头实现方案, 请看[多表头自定义控件]. 

实现原理:
    一般要实现GridView表头固定,表体滚动功能时,都是自己增加一个
控件,
然后将GridView嵌套在这个
控件里面; 使用这个 GridView 控件就不用在页面中自己
增加个
控件了, 因为它自动完成了增加
控件的功能, 具有通用性 .

(二). 运行如图

      1.  单行表头增加自动滚动效果

 

      2.  多行表头增加自动滚动效果

  

 

(三). 用法

   1. 将GridViewExpendHeader控件Dll添加引用到Web站点工程中

   2. 从工具箱拖动一个GridViewExpendHeader控件到设计器中

   3. 设置GridViewExpendHeader控件的属性.

                a.  设置属性窗口中新增的 "扩展" 类别中的两个属性,  这两个属性是指滚动区域的大小, 如下图所示:

                        

               b.  设置GridView本身的高度Height, 这个高度是指滚动区域内的GridView的实际高度, 这个高度数值设置

                     要大于ScrollHeight滚动条才能够呈现.  简单地说, 本自定义控件自动会实现一个GridView(自己)

                    的父控件

,  然后再把自己放在里面,  如果自己高度小于
高度了,  不用滚动就能够显示

                    全自己的数据, 滚动条就没有呈现的意义了.   这里讲得有点啰嗦.   .        

   4. F5运行即可

(四). 完整代码

    1. 主控件GridViewFixedMultiHeader类代码    

  1       ///   < summary >
  2       ///  Author: [ ChengKing(ZhengJian) ] 
  3       ///  Blog:   Http: // blog.youkuaiyun.com / ChengKing
  4       ///   Date :    2007 / 4 / 3
  5       ///   summary>    
  6     /// <summary>
  7     /// 主控件类, 继承GridView的所有功能
  8     ///  summary>
  9     [ToolboxData("<{0}:GridViewExpendHeader runat=server> ")]
 10     public class GridViewFixedMultiHeader : GridView 
 11     {       
 12         [Description("当需要重新构造Header时触发此事件")]
 13         public event System.EventHandler RebuildHeader;
 14 
 15         private System.Web.UI.WebControls.Panel pnlScroll = new System.Web.UI.WebControls.Panel();
 16 
 17         #region 扩展
 18         /// <summary>
 19         /// 设定滚动容器的宽度
 20         ///  summary>
 21         [Bindable(true)]
 22         [Category("扩展")]
 23         [DefaultValue("500px")]
 24         [Localizable(true)]
 25         [TypeConverter(typeof(UnitConverter))]
 26         public Unit ScrollWidth
 27         {
 28             get
 29             {
 30                 return pnlScroll.Width;
 31             }
 32             set
 33             {
 34                 pnlScroll.Width = value;
 35             }
 36         }
 37 
 38         /// <summary>
 39         /// 设定滚动容器的高度
 40         ///  summary>
 41         [Bindable(true)]
 42         [Category("扩展")]
 43         [DefaultValue("150px")]
 44         [Localizable(true)]
 45         [TypeConverter(typeof(UnitConverter))]
 46         public Unit ScrollHeight
 47         {
 48             get
 49             {
 50                 return pnlScroll.Height;
 51             }
 52             set
 53             {
 54                 pnlScroll.Height = value;
 55             }
 56         }
 57         #endregion
 58 
 59         protected override void OnPreRender(EventArgs e)
 60         {
 61             
 62             StringBuilder sb = new StringBuilder();              
 63             sb.Append(" function Tidy()");
 64             sb.Append(" {");
 65             sb.Append("     var gve = document.getElementById(/""+ this.UniqueID +"/"); ");            
 66             sb.Append("     if( gve.rows.length > 0 )");
 67             sb.Append("     {");
 68             sb.Append("         var a1 = document.getElementById(/"divHeaderContainer/");");
 69             sb.Append("         var table1 = document.createElement(/"table/");");
 70             sb.Append("         var tbody1 = document.createElement(/"tbody/");");
 71             sb.Append("         table1.style.cssText = /"table-layout:fixed;border-style: solid ;border-color:gray; border-width: 1px thin;/";   ");
 72             //sb.Append("         table1.style.cssText = /"table-layout:fixed;color:#CCCCFF;background-color:#003399;font-weight:bold;/";");
 73             sb.Append("         var i;");
 74             sb.Append("         var blnIfFind = false;");
 75             sb.Append("         for( i = gve.rows.length - 1; i >= 0; i-- )");
 76             sb.Append("         {");
 77             sb.Append("             if( gve.rows[i].children(0).tagName.toUpperCase() != /"TH/" && blnIfFind == false )  ");
 78             sb.Append("             {");
 79             sb.Append("                 continue;");
 80             sb.Append("             }");
 81             sb.Append("             if( blnIfFind == false )");
 82             sb.Append("             {");
 83             sb.Append("                 blnIfFind = true; ");
 84             sb.Append("             }");
 85             sb.Append("             if( tbody1.children.length == 0 )");
 86             sb.Append("             {");
 87             sb.Append("                 var newRow = gve.rows[i].cloneNode(true); ");
 88             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");            
 89             sb.Append("                 tbody1.appendChild( newRow ); ");
 90             sb.Append("             }");
 91             sb.Append("             else");
 92             sb.Append("             {");
 93             sb.Append("                 var newRow = gve.rows[i].cloneNode(true);   ");
 94             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");
 95             sb.Append("                 tbody1.insertBefore( newRow , tbody1.firstChild );");
 96             sb.Append("             }");
 97             sb.Append("         }");
 98             sb.Append("         table1.appendChild(tbody1);");
 99             sb.Append("         a1.appendChild(table1); ");
100             sb.Append("         for( i = 0; i < gve.rows.length -1; i++)");
101             sb.Append("         {");
102             sb.Append("             if( gve.rows[0].children(0).tagName.toUpperCase() != /"TH/" )");
103             sb.Append("             {");
104             sb.Append("                 gve.deleteRow(0);   ");
105             sb.Append("                 continue;");
106             sb.Append("             }");
107             sb.Append("             gve.deleteRow(0);   ");
108             sb.Append("             break; ");
109             sb.Append("         }");
110             sb.Append("     }");
111             sb.Append(" }");
112 
113             if (!Page.ClientScript.IsClientScriptBlockRegistered("Tidy"))
114             {
115                 Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Tidy", sb.ToString(),true);
116             }
117 
118             if (!Page.ClientScript.IsStartupScriptRegistered("Init"))
119             {
120                 Page.ClientScript.RegisterStartupScript(this.GetType(), "Init""<script type=/"text/javascript/">window.onload = Tidy;</script> "false);
121             }
122 
123             base.OnPreRender(e);
124         }
125 
126         protected override void Render(HtmlTextWriter writer)
127         {
128             OnRebuildHeader();         
129             base.Render(writer);
130         }
131         protected override void CreateChildControls()
132         {
133             Control parent = this.Parent;
134 
135             if (DesignMode == false)
136             {
137                 //生成头容器<DIV>
138                 System.Web.UI.HtmlControls.HtmlGenericControl div = new System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
139                 div.ID = "divHeaderContainer";
140                 div.Style.Add("width", this.Width.ToString());
141                 parent.Controls.Add(div);
142 
143                 Control gridView = this;
144                 parent.Controls.Remove(gridView);
145                  
146                 pnlScroll.Style.Add("width", this.Width.ToString());
147                 pnlScroll.Style.Add("OVERFLOW-Y""scroll");
148                 pnlScroll.Style.Add("OVERFLOW-X""hidden");
149        
150                 pnlScroll.Controls.Add(this);
151                 parent.Controls.Add(pnlScroll);
152 
153                 ChildControlsCreated = true;
154             }
155 
156             base.CreateChildControls();            
157         }
158     
159         protected virtual void OnRebuildHeader()
160         {
161             //重新构造Head
162             if (RebuildHeader != null)
163             {
164                 RebuildHeaderEventArgs args = new RebuildHeaderEventArgs();
165                 args.GridViewObject = this;
166                 args.HeaderRowObject = this.HeaderRow;
167 
168                 RebuildHeader(this, args);
169             }
170             
171         }       
172     } 

    2. 文件RebuildHeaderEventArgs.cs 代码

 1  ///  
 2     /// Author: [ ChengKing(ZhengJian) ] 
 3     /// Blog:   Http://blog.youkuaiyun.com/ChengKing
 4     /// Date:   2007/4/3
 5     /// 

 6       ///  
 7     /// 承载重构Header事件所需的参数[Author:ChengKing(ZhengJian)]
 8     /// 

 9       public   class  RebuildHeaderEventArgs : EventArgs
10      {
11           private  GridViewFixedMultiHeader _GridViewObject;
12           private  GridViewRow _HeaderRowObject;
13 
14           ///  
15         /// 存储GrivViewExtend对象本身
16         /// 

17           public  GridViewFixedMultiHeader GridViewObject
18          {
19               get
20              {
21                   return  _GridViewObject;
22              }
23               set
24              {
25                  _GridViewObject  =  value;
26              }
27          }
28 
29           ///  
30         /// 存储GrivViewExtend的HeaderRow对象
31         /// 

32           public  GridViewRow HeaderRowObject
33          {
34               get
35              {
36                   return  _HeaderRowObject;
37              }
38               set
39              {
40                  _HeaderRowObject  =  value;
41              }
42          }
43      }

   3. 测试页面文件default.aspx代码, 直接拖动一个控件到设计器就OK了. 不需要设置任何属性.

1 <div>
2    <asp:GridView ID="GridViewFixedMultiHeader1" runat="server"  asp:GridView>                  
3  div>

   4. 在新增自定义事件中增加表头行代码, 这里增加三行表头HeaderRow.
 1  ///  
 2     /// 具体重写方法, 此方法比较灵活, 可以任意设置您需要创建的格式, 比如更复杂的表格
 3     /// 另外, 可以直接从第二个参数中取得控件对象引用
 4     /// 

 5       ///  
 6       ///  
 7       protected   void  GridViewExpend1_RebuildHeader( object  sender, EventArgs e)
 8      {
 9           // 取得参数e中包含的对象的引用        
10          GridViewFixedMultiHeader currentGVE  =  ((RebuildHeaderEventArgs)e).GridViewObject;   // 到操作当前GridView的对象引用
11          GridViewRow currentHeaderRow  =  ((RebuildHeaderEventArgs)e).HeaderRowObject;  /// /到操作当前GridView's HeaderRow的对象引用
12 
13 
14           ///
15           /// /在当前HeaderRow上面增加一行
16           // 创建一个行并设置与GridViewExtend当前的头类型风格一致
17          GridViewRow willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
18          willAddHeaderRow.Font.Bold  =   true ;
19          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
20          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
21          TableCell cell  =   new  TableCell();
22          cell.Text  =   " Number " ;
23          cell.HorizontalAlign  =  HorizontalAlign.Center;
24          willAddHeaderRow.Cells.Add(cell);
25          cell  =   new  TableCell();
26          cell.Text  =   " Detail " ;
27          cell.ColumnSpan  =   2 ;
28          cell.HorizontalAlign  =  HorizontalAlign.Center;
29          willAddHeaderRow.Cells.Add(cell);
30           // 添加到GridView
31          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);
32 
33 
34           ///
35           /// /在当前HeaderRow上面再增加一行
36           // 同样创建一个行并设置与GridViewExtend当前的头类型风格一致
37          willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
38          willAddHeaderRow.Font.Bold  =   true ;
39          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
40          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
41 
42          cell  =   new  TableCell();
43          cell.Text  =   " Fruits category information " ;
44          cell.ColumnSpan  =   3 ;
45          cell.HorizontalAlign  =  HorizontalAlign.Center;
46          willAddHeaderRow.Cells.Add(cell);
47           // 添加到GridView
48          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);  
49       
50           // 还可以继续增加N个表头行;
51           // 不管增加多么, GridView控件都能够自动检测到HeaderRow的个数, 并且能够正确呈现滚动条
52           // ..;  
53           // ..; 
54      }

 

(五). 示例代码下载

        http://www.cnblogs.com/Files/MVP33650/extendgridviewfixedmultiheader.rar

 

(六). 控件开发其它相关文章:

        http://blog.youkuaiyun.com/ChengKing/category/288694.aspx

 

 

 

 

 

 

  


(一). 概述

        1. 实现GridView表头固定表体滚动效果

        2. 继承GridView的所有功能, 增加扩展功能, 表体滚动功能; 不需要另外加辅助滚动控件, 如

.

        3. 支持多行表头滚动, 此控件能够自动检测到使用者增加的表头的行数. 准确的实现表头滚动.

            有增加GridView多表头实现方案, 请看[多表头自定义控件]. 

实现原理:
    一般要实现GridView表头固定,表体滚动功能时,都是自己增加一个
控件,
然后将GridView嵌套在这个
控件里面; 使用这个 GridView 控件就不用在页面中自己
增加个
控件了, 因为它自动完成了增加
控件的功能, 具有通用性 .

(二). 运行如图

      1.  单行表头增加自动滚动效果

 

      2.  多行表头增加自动滚动效果

  

 

(三). 用法

   1. 将GridViewExpendHeader控件Dll添加引用到Web站点工程中

   2. 从工具箱拖动一个GridViewExpendHeader控件到设计器中

   3. 设置GridViewExpendHeader控件的属性.

                a.  设置属性窗口中新增的 "扩展" 类别中的两个属性,  这两个属性是指滚动区域的大小, 如下图所示:

                        

               b.  设置GridView本身的高度Height, 这个高度是指滚动区域内的GridView的实际高度, 这个高度数值设置

                     要大于ScrollHeight滚动条才能够呈现.  简单地说, 本自定义控件自动会实现一个GridView(自己)

                    的父控件

,  然后再把自己放在里面,  如果自己高度小于
高度了,  不用滚动就能够显示

                    全自己的数据, 滚动条就没有呈现的意义了.   这里讲得有点啰嗦.   .        

   4. F5运行即可

(四). 完整代码

    1. 主控件GridViewFixedMultiHeader类代码    

  1       ///   < summary >
  2       ///  Author: [ ChengKing(ZhengJian) ] 
  3       ///  Blog:   Http: // blog.youkuaiyun.com / ChengKing
  4       ///   Date :    2007 / 4 / 3
  5       ///   summary>    
  6     /// <summary>
  7     /// 主控件类, 继承GridView的所有功能
  8     ///  summary>
  9     [ToolboxData("<{0}:GridViewExpendHeader runat=server> ")]
 10     public class GridViewFixedMultiHeader : GridView 
 11     {       
 12         [Description("当需要重新构造Header时触发此事件")]
 13         public event System.EventHandler RebuildHeader;
 14 
 15         private System.Web.UI.WebControls.Panel pnlScroll = new System.Web.UI.WebControls.Panel();
 16 
 17         #region 扩展
 18         /// <summary>
 19         /// 设定滚动容器的宽度
 20         ///  summary>
 21         [Bindable(true)]
 22         [Category("扩展")]
 23         [DefaultValue("500px")]
 24         [Localizable(true)]
 25         [TypeConverter(typeof(UnitConverter))]
 26         public Unit ScrollWidth
 27         {
 28             get
 29             {
 30                 return pnlScroll.Width;
 31             }
 32             set
 33             {
 34                 pnlScroll.Width = value;
 35             }
 36         }
 37 
 38         /// <summary>
 39         /// 设定滚动容器的高度
 40         ///  summary>
 41         [Bindable(true)]
 42         [Category("扩展")]
 43         [DefaultValue("150px")]
 44         [Localizable(true)]
 45         [TypeConverter(typeof(UnitConverter))]
 46         public Unit ScrollHeight
 47         {
 48             get
 49             {
 50                 return pnlScroll.Height;
 51             }
 52             set
 53             {
 54                 pnlScroll.Height = value;
 55             }
 56         }
 57         #endregion
 58 
 59         protected override void OnPreRender(EventArgs e)
 60         {
 61             
 62             StringBuilder sb = new StringBuilder();              
 63             sb.Append(" function Tidy()");
 64             sb.Append(" {");
 65             sb.Append("     var gve = document.getElementById(/""+ this.UniqueID +"/"); ");            
 66             sb.Append("     if( gve.rows.length > 0 )");
 67             sb.Append("     {");
 68             sb.Append("         var a1 = document.getElementById(/"divHeaderContainer/");");
 69             sb.Append("         var table1 = document.createElement(/"table/");");
 70             sb.Append("         var tbody1 = document.createElement(/"tbody/");");
 71             sb.Append("         table1.style.cssText = /"table-layout:fixed;border-style: solid ;border-color:gray; border-width: 1px thin;/";   ");
 72             //sb.Append("         table1.style.cssText = /"table-layout:fixed;color:#CCCCFF;background-color:#003399;font-weight:bold;/";");
 73             sb.Append("         var i;");
 74             sb.Append("         var blnIfFind = false;");
 75             sb.Append("         for( i = gve.rows.length - 1; i >= 0; i-- )");
 76             sb.Append("         {");
 77             sb.Append("             if( gve.rows[i].children(0).tagName.toUpperCase() != /"TH/" && blnIfFind == false )  ");
 78             sb.Append("             {");
 79             sb.Append("                 continue;");
 80             sb.Append("             }");
 81             sb.Append("             if( blnIfFind == false )");
 82             sb.Append("             {");
 83             sb.Append("                 blnIfFind = true; ");
 84             sb.Append("             }");
 85             sb.Append("             if( tbody1.children.length == 0 )");
 86             sb.Append("             {");
 87             sb.Append("                 var newRow = gve.rows[i].cloneNode(true); ");
 88             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");            
 89             sb.Append("                 tbody1.appendChild( newRow ); ");
 90             sb.Append("             }");
 91             sb.Append("             else");
 92             sb.Append("             {");
 93             sb.Append("                 var newRow = gve.rows[i].cloneNode(true);   ");
 94             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");
 95             sb.Append("                 tbody1.insertBefore( newRow , tbody1.firstChild );");
 96             sb.Append("             }");
 97             sb.Append("         }");
 98             sb.Append("         table1.appendChild(tbody1);");
 99             sb.Append("         a1.appendChild(table1); ");
100             sb.Append("         for( i = 0; i < gve.rows.length -1; i++)");
101             sb.Append("         {");
102             sb.Append("             if( gve.rows[0].children(0).tagName.toUpperCase() != /"TH/" )");
103             sb.Append("             {");
104             sb.Append("                 gve.deleteRow(0);   ");
105             sb.Append("                 continue;");
106             sb.Append("             }");
107             sb.Append("             gve.deleteRow(0);   ");
108             sb.Append("             break; ");
109             sb.Append("         }");
110             sb.Append("     }");
111             sb.Append(" }");
112 
113             if (!Page.ClientScript.IsClientScriptBlockRegistered("Tidy"))
114             {
115                 Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Tidy", sb.ToString(),true);
116             }
117 
118             if (!Page.ClientScript.IsStartupScriptRegistered("Init"))
119             {
120                 Page.ClientScript.RegisterStartupScript(this.GetType(), "Init""<script type=/"text/javascript/">window.onload = Tidy;</script> "false);
121             }
122 
123             base.OnPreRender(e);
124         }
125 
126         protected override void Render(HtmlTextWriter writer)
127         {
128             OnRebuildHeader();         
129             base.Render(writer);
130         }
131         protected override void CreateChildControls()
132         {
133             Control parent = this.Parent;
134 
135             if (DesignMode == false)
136             {
137                 //生成头容器<DIV>
138                 System.Web.UI.HtmlControls.HtmlGenericControl div = new System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
139                 div.ID = "divHeaderContainer";
140                 div.Style.Add("width", this.Width.ToString());
141                 parent.Controls.Add(div);
142 
143                 Control gridView = this;
144                 parent.Controls.Remove(gridView);
145                  
146                 pnlScroll.Style.Add("width", this.Width.ToString());
147                 pnlScroll.Style.Add("OVERFLOW-Y""scroll");
148                 pnlScroll.Style.Add("OVERFLOW-X""hidden");
149        
150                 pnlScroll.Controls.Add(this);
151                 parent.Controls.Add(pnlScroll);
152 
153                 ChildControlsCreated = true;
154             }
155 
156             base.CreateChildControls();            
157         }
158     
159         protected virtual void OnRebuildHeader()
160         {
161             //重新构造Head
162             if (RebuildHeader != null)
163             {
164                 RebuildHeaderEventArgs args = new RebuildHeaderEventArgs();
165                 args.GridViewObject = this;
166                 args.HeaderRowObject = this.HeaderRow;
167 
168                 RebuildHeader(this, args);
169             }
170             
171         }       
172     } 

    2. 文件RebuildHeaderEventArgs.cs 代码

 1  ///  
 2     /// Author: [ ChengKing(ZhengJian) ] 
 3     /// Blog:   Http://blog.youkuaiyun.com/ChengKing
 4     /// Date:   2007/4/3
 5     /// 

 6       ///  
 7     /// 承载重构Header事件所需的参数[Author:ChengKing(ZhengJian)]
 8     /// 

 9       public   class  RebuildHeaderEventArgs : EventArgs
10      {
11           private  GridViewFixedMultiHeader _GridViewObject;
12           private  GridViewRow _HeaderRowObject;
13 
14           ///  
15         /// 存储GrivViewExtend对象本身
16         /// 

17           public  GridViewFixedMultiHeader GridViewObject
18          {
19               get
20              {
21                   return  _GridViewObject;
22              }
23               set
24              {
25                  _GridViewObject  =  value;
26              }
27          }
28 
29           ///  
30         /// 存储GrivViewExtend的HeaderRow对象
31         /// 

32           public  GridViewRow HeaderRowObject
33          {
34               get
35              {
36                   return  _HeaderRowObject;
37              }
38               set
39              {
40                  _HeaderRowObject  =  value;
41              }
42          }
43      }

   3. 测试页面文件default.aspx代码, 直接拖动一个控件到设计器就OK了. 不需要设置任何属性.

1 <div>
2    <asp:GridView ID="GridViewFixedMultiHeader1" runat="server"  asp:GridView>                  
3  div>

   4. 在新增自定义事件中增加表头行代码, 这里增加三行表头HeaderRow.
 1  ///  
 2     /// 具体重写方法, 此方法比较灵活, 可以任意设置您需要创建的格式, 比如更复杂的表格
 3     /// 另外, 可以直接从第二个参数中取得控件对象引用
 4     /// 

 5       ///  
 6       ///  
 7       protected   void  GridViewExpend1_RebuildHeader( object  sender, EventArgs e)
 8      {
 9           // 取得参数e中包含的对象的引用        
10          GridViewFixedMultiHeader currentGVE  =  ((RebuildHeaderEventArgs)e).GridViewObject;   // 到操作当前GridView的对象引用
11          GridViewRow currentHeaderRow  =  ((RebuildHeaderEventArgs)e).HeaderRowObject;  /// /到操作当前GridView's HeaderRow的对象引用
12 
13 
14           ///
15           /// /在当前HeaderRow上面增加一行
16           // 创建一个行并设置与GridViewExtend当前的头类型风格一致
17          GridViewRow willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
18          willAddHeaderRow.Font.Bold  =   true ;
19          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
20          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
21          TableCell cell  =   new  TableCell();
22          cell.Text  =   " Number " ;
23          cell.HorizontalAlign  =  HorizontalAlign.Center;
24          willAddHeaderRow.Cells.Add(cell);
25          cell  =   new  TableCell();
26          cell.Text  =   " Detail " ;
27          cell.ColumnSpan  =   2 ;
28          cell.HorizontalAlign  =  HorizontalAlign.Center;
29          willAddHeaderRow.Cells.Add(cell);
30           // 添加到GridView
31          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);
32 
33 
34           ///
35           /// /在当前HeaderRow上面再增加一行
36           // 同样创建一个行并设置与GridViewExtend当前的头类型风格一致
37          willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
38          willAddHeaderRow.Font.Bold  =   true ;
39          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
40          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
41 
42          cell  =   new  TableCell();
43          cell.Text  =   " Fruits category information " ;
44          cell.ColumnSpan  =   3 ;
45          cell.HorizontalAlign  =  HorizontalAlign.Center;
46          willAddHeaderRow.Cells.Add(cell);
47           // 添加到GridView
48          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);  
49       
50           // 还可以继续增加N个表头行;
51           // 不管增加多么, GridView控件都能够自动检测到HeaderRow的个数, 并且能够正确呈现滚动条
52           // ..;  
53           // ..; 
54      }

 

(五). 示例代码下载

        http://www.cnblogs.com/Files/MVP33650/extendgridviewfixedmultiheader.rar

 

(六). 控件开发其它相关文章:

        http://blog.youkuaiyun.com/ChengKing/category/288694.aspx

 

 

 

 

 

 

  


(一). 概述

        1. 实现GridView表头固定表体滚动效果

        2. 继承GridView的所有功能, 增加扩展功能, 表体滚动功能; 不需要另外加辅助滚动控件, 如

.

        3. 支持多行表头滚动, 此控件能够自动检测到使用者增加的表头的行数. 准确的实现表头滚动.

            有增加GridView多表头实现方案, 请看[多表头自定义控件]. 

实现原理:
    一般要实现GridView表头固定,表体滚动功能时,都是自己增加一个
控件,
然后将GridView嵌套在这个
控件里面; 使用这个 GridView 控件就不用在页面中自己
增加个
控件了, 因为它自动完成了增加
控件的功能, 具有通用性 .

(二). 运行如图

      1.  单行表头增加自动滚动效果

 

      2.  多行表头增加自动滚动效果

  

 

(三). 用法

   1. 将GridViewExpendHeader控件Dll添加引用到Web站点工程中

   2. 从工具箱拖动一个GridViewExpendHeader控件到设计器中

   3. 设置GridViewExpendHeader控件的属性.

                a.  设置属性窗口中新增的 "扩展" 类别中的两个属性,  这两个属性是指滚动区域的大小, 如下图所示:

                        

               b.  设置GridView本身的高度Height, 这个高度是指滚动区域内的GridView的实际高度, 这个高度数值设置

                     要大于ScrollHeight滚动条才能够呈现.  简单地说, 本自定义控件自动会实现一个GridView(自己)

                    的父控件

,  然后再把自己放在里面,  如果自己高度小于
高度了,  不用滚动就能够显示

                    全自己的数据, 滚动条就没有呈现的意义了.   这里讲得有点啰嗦.   .        

   4. F5运行即可

(四). 完整代码

    1. 主控件GridViewFixedMultiHeader类代码    

  1       ///   < summary >
  2       ///  Author: [ ChengKing(ZhengJian) ] 
  3       ///  Blog:   Http: // blog.youkuaiyun.com / ChengKing
  4       ///   Date :    2007 / 4 / 3
  5       ///   summary>    
  6     /// <summary>
  7     /// 主控件类, 继承GridView的所有功能
  8     ///  summary>
  9     [ToolboxData("<{0}:GridViewExpendHeader runat=server> ")]
 10     public class GridViewFixedMultiHeader : GridView 
 11     {       
 12         [Description("当需要重新构造Header时触发此事件")]
 13         public event System.EventHandler RebuildHeader;
 14 
 15         private System.Web.UI.WebControls.Panel pnlScroll = new System.Web.UI.WebControls.Panel();
 16 
 17         #region 扩展
 18         /// <summary>
 19         /// 设定滚动容器的宽度
 20         ///  summary>
 21         [Bindable(true)]
 22         [Category("扩展")]
 23         [DefaultValue("500px")]
 24         [Localizable(true)]
 25         [TypeConverter(typeof(UnitConverter))]
 26         public Unit ScrollWidth
 27         {
 28             get
 29             {
 30                 return pnlScroll.Width;
 31             }
 32             set
 33             {
 34                 pnlScroll.Width = value;
 35             }
 36         }
 37 
 38         /// <summary>
 39         /// 设定滚动容器的高度
 40         ///  summary>
 41         [Bindable(true)]
 42         [Category("扩展")]
 43         [DefaultValue("150px")]
 44         [Localizable(true)]
 45         [TypeConverter(typeof(UnitConverter))]
 46         public Unit ScrollHeight
 47         {
 48             get
 49             {
 50                 return pnlScroll.Height;
 51             }
 52             set
 53             {
 54                 pnlScroll.Height = value;
 55             }
 56         }
 57         #endregion
 58 
 59         protected override void OnPreRender(EventArgs e)
 60         {
 61             
 62             StringBuilder sb = new StringBuilder();              
 63             sb.Append(" function Tidy()");
 64             sb.Append(" {");
 65             sb.Append("     var gve = document.getElementById(/""+ this.UniqueID +"/"); ");            
 66             sb.Append("     if( gve.rows.length > 0 )");
 67             sb.Append("     {");
 68             sb.Append("         var a1 = document.getElementById(/"divHeaderContainer/");");
 69             sb.Append("         var table1 = document.createElement(/"table/");");
 70             sb.Append("         var tbody1 = document.createElement(/"tbody/");");
 71             sb.Append("         table1.style.cssText = /"table-layout:fixed;border-style: solid ;border-color:gray; border-width: 1px thin;/";   ");
 72             //sb.Append("         table1.style.cssText = /"table-layout:fixed;color:#CCCCFF;background-color:#003399;font-weight:bold;/";");
 73             sb.Append("         var i;");
 74             sb.Append("         var blnIfFind = false;");
 75             sb.Append("         for( i = gve.rows.length - 1; i >= 0; i-- )");
 76             sb.Append("         {");
 77             sb.Append("             if( gve.rows[i].children(0).tagName.toUpperCase() != /"TH/" && blnIfFind == false )  ");
 78             sb.Append("             {");
 79             sb.Append("                 continue;");
 80             sb.Append("             }");
 81             sb.Append("             if( blnIfFind == false )");
 82             sb.Append("             {");
 83             sb.Append("                 blnIfFind = true; ");
 84             sb.Append("             }");
 85             sb.Append("             if( tbody1.children.length == 0 )");
 86             sb.Append("             {");
 87             sb.Append("                 var newRow = gve.rows[i].cloneNode(true); ");
 88             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");            
 89             sb.Append("                 tbody1.appendChild( newRow ); ");
 90             sb.Append("             }");
 91             sb.Append("             else");
 92             sb.Append("             {");
 93             sb.Append("                 var newRow = gve.rows[i].cloneNode(true);   ");
 94             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");
 95             sb.Append("                 tbody1.insertBefore( newRow , tbody1.firstChild );");
 96             sb.Append("             }");
 97             sb.Append("         }");
 98             sb.Append("         table1.appendChild(tbody1);");
 99             sb.Append("         a1.appendChild(table1); ");
100             sb.Append("         for( i = 0; i < gve.rows.length -1; i++)");
101             sb.Append("         {");
102             sb.Append("             if( gve.rows[0].children(0).tagName.toUpperCase() != /"TH/" )");
103             sb.Append("             {");
104             sb.Append("                 gve.deleteRow(0);   ");
105             sb.Append("                 continue;");
106             sb.Append("             }");
107             sb.Append("             gve.deleteRow(0);   ");
108             sb.Append("             break; ");
109             sb.Append("         }");
110             sb.Append("     }");
111             sb.Append(" }");
112 
113             if (!Page.ClientScript.IsClientScriptBlockRegistered("Tidy"))
114             {
115                 Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Tidy", sb.ToString(),true);
116             }
117 
118             if (!Page.ClientScript.IsStartupScriptRegistered("Init"))
119             {
120                 Page.ClientScript.RegisterStartupScript(this.GetType(), "Init""<script type=/"text/javascript/">window.onload = Tidy;</script> "false);
121             }
122 
123             base.OnPreRender(e);
124         }
125 
126         protected override void Render(HtmlTextWriter writer)
127         {
128             OnRebuildHeader();         
129             base.Render(writer);
130         }
131         protected override void CreateChildControls()
132         {
133             Control parent = this.Parent;
134 
135             if (DesignMode == false)
136             {
137                 //生成头容器<DIV>
138                 System.Web.UI.HtmlControls.HtmlGenericControl div = new System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
139                 div.ID = "divHeaderContainer";
140                 div.Style.Add("width", this.Width.ToString());
141                 parent.Controls.Add(div);
142 
143                 Control gridView = this;
144                 parent.Controls.Remove(gridView);
145                  
146                 pnlScroll.Style.Add("width", this.Width.ToString());
147                 pnlScroll.Style.Add("OVERFLOW-Y""scroll");
148                 pnlScroll.Style.Add("OVERFLOW-X""hidden");
149        
150                 pnlScroll.Controls.Add(this);
151                 parent.Controls.Add(pnlScroll);
152 
153                 ChildControlsCreated = true;
154             }
155 
156             base.CreateChildControls();            
157         }
158     
159         protected virtual void OnRebuildHeader()
160         {
161             //重新构造Head
162             if (RebuildHeader != null)
163             {
164                 RebuildHeaderEventArgs args = new RebuildHeaderEventArgs();
165                 args.GridViewObject = this;
166                 args.HeaderRowObject = this.HeaderRow;
167 
168                 RebuildHeader(this, args);
169             }
170             
171         }       
172     } 

    2. 文件RebuildHeaderEventArgs.cs 代码

 1  ///  
 2     /// Author: [ ChengKing(ZhengJian) ] 
 3     /// Blog:   Http://blog.youkuaiyun.com/ChengKing
 4     /// Date:   2007/4/3
 5     /// 

 6       ///  
 7     /// 承载重构Header事件所需的参数[Author:ChengKing(ZhengJian)]
 8     /// 

 9       public   class  RebuildHeaderEventArgs : EventArgs
10      {
11           private  GridViewFixedMultiHeader _GridViewObject;
12           private  GridViewRow _HeaderRowObject;
13 
14           ///  
15         /// 存储GrivViewExtend对象本身
16         /// 

17           public  GridViewFixedMultiHeader GridViewObject
18          {
19               get
20              {
21                   return  _GridViewObject;
22              }
23               set
24              {
25                  _GridViewObject  =  value;
26              }
27          }
28 
29           ///  
30         /// 存储GrivViewExtend的HeaderRow对象
31         /// 

32           public  GridViewRow HeaderRowObject
33          {
34               get
35              {
36                   return  _HeaderRowObject;
37              }
38               set
39              {
40                  _HeaderRowObject  =  value;
41              }
42          }
43      }

   3. 测试页面文件default.aspx代码, 直接拖动一个控件到设计器就OK了. 不需要设置任何属性.

1 <div>
2    <asp:GridView ID="GridViewFixedMultiHeader1" runat="server"  asp:GridView>                  
3  div>

   4. 在新增自定义事件中增加表头行代码, 这里增加三行表头HeaderRow.
 1  ///  
 2     /// 具体重写方法, 此方法比较灵活, 可以任意设置您需要创建的格式, 比如更复杂的表格
 3     /// 另外, 可以直接从第二个参数中取得控件对象引用
 4     /// 

 5       ///  
 6       ///  
 7       protected   void  GridViewExpend1_RebuildHeader( object  sender, EventArgs e)
 8      {
 9           // 取得参数e中包含的对象的引用        
10          GridViewFixedMultiHeader currentGVE  =  ((RebuildHeaderEventArgs)e).GridViewObject;   // 到操作当前GridView的对象引用
11          GridViewRow currentHeaderRow  =  ((RebuildHeaderEventArgs)e).HeaderRowObject;  /// /到操作当前GridView's HeaderRow的对象引用
12 
13 
14           ///
15           /// /在当前HeaderRow上面增加一行
16           // 创建一个行并设置与GridViewExtend当前的头类型风格一致
17          GridViewRow willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
18          willAddHeaderRow.Font.Bold  =   true ;
19          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
20          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
21          TableCell cell  =   new  TableCell();
22          cell.Text  =   " Number " ;
23          cell.HorizontalAlign  =  HorizontalAlign.Center;
24          willAddHeaderRow.Cells.Add(cell);
25          cell  =   new  TableCell();
26          cell.Text  =   " Detail " ;
27          cell.ColumnSpan  =   2 ;
28          cell.HorizontalAlign  =  HorizontalAlign.Center;
29          willAddHeaderRow.Cells.Add(cell);
30           // 添加到GridView
31          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);
32 
33 
34           ///
35           /// /在当前HeaderRow上面再增加一行
36           // 同样创建一个行并设置与GridViewExtend当前的头类型风格一致
37          willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
38          willAddHeaderRow.Font.Bold  =   true ;
39          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
40          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
41 
42          cell  =   new  TableCell();
43          cell.Text  =   " Fruits category information " ;
44          cell.ColumnSpan  =   3 ;
45          cell.HorizontalAlign  =  HorizontalAlign.Center;
46          willAddHeaderRow.Cells.Add(cell);
47           // 添加到GridView
48          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);  
49       
50           // 还可以继续增加N个表头行;
51           // 不管增加多么, GridView控件都能够自动检测到HeaderRow的个数, 并且能够正确呈现滚动条
52           // ..;  
53           // ..; 
54      }

 

(五). 示例代码下载

        http://www.cnblogs.com/Files/MVP33650/extendgridviewfixedmultiheader.rar

 

(六). 控件开发其它相关文章:

        http://blog.youkuaiyun.com/ChengKing/category/288694.aspx

 

 

 

 

 

 

  


(一). 概述

        1. 实现GridView表头固定表体滚动效果

        2. 继承GridView的所有功能, 增加扩展功能, 表体滚动功能; 不需要另外加辅助滚动控件, 如

.

        3. 支持多行表头滚动, 此控件能够自动检测到使用者增加的表头的行数. 准确的实现表头滚动.

            有增加GridView多表头实现方案, 请看[多表头自定义控件]. 

实现原理:
    一般要实现GridView表头固定,表体滚动功能时,都是自己增加一个
控件,
然后将GridView嵌套在这个
控件里面; 使用这个 GridView 控件就不用在页面中自己
增加个
控件了, 因为它自动完成了增加
控件的功能, 具有通用性 .

(二). 运行如图

      1.  单行表头增加自动滚动效果

 

      2.  多行表头增加自动滚动效果

  

 

(三). 用法

   1. 将GridViewExpendHeader控件Dll添加引用到Web站点工程中

   2. 从工具箱拖动一个GridViewExpendHeader控件到设计器中

   3. 设置GridViewExpendHeader控件的属性.

                a.  设置属性窗口中新增的 "扩展" 类别中的两个属性,  这两个属性是指滚动区域的大小, 如下图所示:

                        

               b.  设置GridView本身的高度Height, 这个高度是指滚动区域内的GridView的实际高度, 这个高度数值设置

                     要大于ScrollHeight滚动条才能够呈现.  简单地说, 本自定义控件自动会实现一个GridView(自己)

                    的父控件

,  然后再把自己放在里面,  如果自己高度小于
高度了,  不用滚动就能够显示

                    全自己的数据, 滚动条就没有呈现的意义了.   这里讲得有点啰嗦.   .        

   4. F5运行即可

(四). 完整代码

    1. 主控件GridViewFixedMultiHeader类代码    

  1       ///   < summary >
  2       ///  Author: [ ChengKing(ZhengJian) ] 
  3       ///  Blog:   Http: // blog.youkuaiyun.com / ChengKing
  4       ///   Date :    2007 / 4 / 3
  5       ///   summary>    
  6     /// <summary>
  7     /// 主控件类, 继承GridView的所有功能
  8     ///  summary>
  9     [ToolboxData("<{0}:GridViewExpendHeader runat=server> ")]
 10     public class GridViewFixedMultiHeader : GridView 
 11     {       
 12         [Description("当需要重新构造Header时触发此事件")]
 13         public event System.EventHandler RebuildHeader;
 14 
 15         private System.Web.UI.WebControls.Panel pnlScroll = new System.Web.UI.WebControls.Panel();
 16 
 17         #region 扩展
 18         /// <summary>
 19         /// 设定滚动容器的宽度
 20         ///  summary>
 21         [Bindable(true)]
 22         [Category("扩展")]
 23         [DefaultValue("500px")]
 24         [Localizable(true)]
 25         [TypeConverter(typeof(UnitConverter))]
 26         public Unit ScrollWidth
 27         {
 28             get
 29             {
 30                 return pnlScroll.Width;
 31             }
 32             set
 33             {
 34                 pnlScroll.Width = value;
 35             }
 36         }
 37 
 38         /// <summary>
 39         /// 设定滚动容器的高度
 40         ///  summary>
 41         [Bindable(true)]
 42         [Category("扩展")]
 43         [DefaultValue("150px")]
 44         [Localizable(true)]
 45         [TypeConverter(typeof(UnitConverter))]
 46         public Unit ScrollHeight
 47         {
 48             get
 49             {
 50                 return pnlScroll.Height;
 51             }
 52             set
 53             {
 54                 pnlScroll.Height = value;
 55             }
 56         }
 57         #endregion
 58 
 59         protected override void OnPreRender(EventArgs e)
 60         {
 61             
 62             StringBuilder sb = new StringBuilder();              
 63             sb.Append(" function Tidy()");
 64             sb.Append(" {");
 65             sb.Append("     var gve = document.getElementById(/""+ this.UniqueID +"/"); ");            
 66             sb.Append("     if( gve.rows.length > 0 )");
 67             sb.Append("     {");
 68             sb.Append("         var a1 = document.getElementById(/"divHeaderContainer/");");
 69             sb.Append("         var table1 = document.createElement(/"table/");");
 70             sb.Append("         var tbody1 = document.createElement(/"tbody/");");
 71             sb.Append("         table1.style.cssText = /"table-layout:fixed;border-style: solid ;border-color:gray; border-width: 1px thin;/";   ");
 72             //sb.Append("         table1.style.cssText = /"table-layout:fixed;color:#CCCCFF;background-color:#003399;font-weight:bold;/";");
 73             sb.Append("         var i;");
 74             sb.Append("         var blnIfFind = false;");
 75             sb.Append("         for( i = gve.rows.length - 1; i >= 0; i-- )");
 76             sb.Append("         {");
 77             sb.Append("             if( gve.rows[i].children(0).tagName.toUpperCase() != /"TH/" && blnIfFind == false )  ");
 78             sb.Append("             {");
 79             sb.Append("                 continue;");
 80             sb.Append("             }");
 81             sb.Append("             if( blnIfFind == false )");
 82             sb.Append("             {");
 83             sb.Append("                 blnIfFind = true; ");
 84             sb.Append("             }");
 85             sb.Append("             if( tbody1.children.length == 0 )");
 86             sb.Append("             {");
 87             sb.Append("                 var newRow = gve.rows[i].cloneNode(true); ");
 88             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");            
 89             sb.Append("                 tbody1.appendChild( newRow ); ");
 90             sb.Append("             }");
 91             sb.Append("             else");
 92             sb.Append("             {");
 93             sb.Append("                 var newRow = gve.rows[i].cloneNode(true);   ");
 94             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");
 95             sb.Append("                 tbody1.insertBefore( newRow , tbody1.firstChild );");
 96             sb.Append("             }");
 97             sb.Append("         }");
 98             sb.Append("         table1.appendChild(tbody1);");
 99             sb.Append("         a1.appendChild(table1); ");
100             sb.Append("         for( i = 0; i < gve.rows.length -1; i++)");
101             sb.Append("         {");
102             sb.Append("             if( gve.rows[0].children(0).tagName.toUpperCase() != /"TH/" )");
103             sb.Append("             {");
104             sb.Append("                 gve.deleteRow(0);   ");
105             sb.Append("                 continue;");
106             sb.Append("             }");
107             sb.Append("             gve.deleteRow(0);   ");
108             sb.Append("             break; ");
109             sb.Append("         }");
110             sb.Append("     }");
111             sb.Append(" }");
112 
113             if (!Page.ClientScript.IsClientScriptBlockRegistered("Tidy"))
114             {
115                 Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Tidy", sb.ToString(),true);
116             }
117 
118             if (!Page.ClientScript.IsStartupScriptRegistered("Init"))
119             {
120                 Page.ClientScript.RegisterStartupScript(this.GetType(), "Init""<script type=/"text/javascript/">window.onload = Tidy;</script> "false);
121             }
122 
123             base.OnPreRender(e);
124         }
125 
126         protected override void Render(HtmlTextWriter writer)
127         {
128             OnRebuildHeader();         
129             base.Render(writer);
130         }
131         protected override void CreateChildControls()
132         {
133             Control parent = this.Parent;
134 
135             if (DesignMode == false)
136             {
137                 //生成头容器<DIV>
138                 System.Web.UI.HtmlControls.HtmlGenericControl div = new System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
139                 div.ID = "divHeaderContainer";
140                 div.Style.Add("width", this.Width.ToString());
141                 parent.Controls.Add(div);
142 
143                 Control gridView = this;
144                 parent.Controls.Remove(gridView);
145                  
146                 pnlScroll.Style.Add("width", this.Width.ToString());
147                 pnlScroll.Style.Add("OVERFLOW-Y""scroll");
148                 pnlScroll.Style.Add("OVERFLOW-X""hidden");
149        
150                 pnlScroll.Controls.Add(this);
151                 parent.Controls.Add(pnlScroll);
152 
153                 ChildControlsCreated = true;
154             }
155 
156             base.CreateChildControls();            
157         }
158     
159         protected virtual void OnRebuildHeader()
160         {
161             //重新构造Head
162             if (RebuildHeader != null)
163             {
164                 RebuildHeaderEventArgs args = new RebuildHeaderEventArgs();
165                 args.GridViewObject = this;
166                 args.HeaderRowObject = this.HeaderRow;
167 
168                 RebuildHeader(this, args);
169             }
170             
171         }       
172     } 

    2. 文件RebuildHeaderEventArgs.cs 代码

 1  ///  
 2     /// Author: [ ChengKing(ZhengJian) ] 
 3     /// Blog:   Http://blog.youkuaiyun.com/ChengKing
 4     /// Date:   2007/4/3
 5     /// 

 6       ///  
 7     /// 承载重构Header事件所需的参数[Author:ChengKing(ZhengJian)]
 8     /// 

 9       public   class  RebuildHeaderEventArgs : EventArgs
10      {
11           private  GridViewFixedMultiHeader _GridViewObject;
12           private  GridViewRow _HeaderRowObject;
13 
14           ///  
15         /// 存储GrivViewExtend对象本身
16         /// 

17           public  GridViewFixedMultiHeader GridViewObject
18          {
19               get
20              {
21                   return  _GridViewObject;
22              }
23               set
24              {
25                  _GridViewObject  =  value;
26              }
27          }
28 
29           ///  
30         /// 存储GrivViewExtend的HeaderRow对象
31         /// 

32           public  GridViewRow HeaderRowObject
33          {
34               get
35              {
36                   return  _HeaderRowObject;
37              }
38               set
39              {
40                  _HeaderRowObject  =  value;
41              }
42          }
43      }

   3. 测试页面文件default.aspx代码, 直接拖动一个控件到设计器就OK了. 不需要设置任何属性.

1 <div>
2    <asp:GridView ID="GridViewFixedMultiHeader1" runat="server"  asp:GridView>                  
3  div>

   4. 在新增自定义事件中增加表头行代码, 这里增加三行表头HeaderRow.
 1  ///  
 2     /// 具体重写方法, 此方法比较灵活, 可以任意设置您需要创建的格式, 比如更复杂的表格
 3     /// 另外, 可以直接从第二个参数中取得控件对象引用
 4     /// 

 5       ///  
 6       ///  
 7       protected   void  GridViewExpend1_RebuildHeader( object  sender, EventArgs e)
 8      {
 9           // 取得参数e中包含的对象的引用        
10          GridViewFixedMultiHeader currentGVE  =  ((RebuildHeaderEventArgs)e).GridViewObject;   // 到操作当前GridView的对象引用
11          GridViewRow currentHeaderRow  =  ((RebuildHeaderEventArgs)e).HeaderRowObject;  /// /到操作当前GridView's HeaderRow的对象引用
12 
13 
14           ///
15           /// /在当前HeaderRow上面增加一行
16           // 创建一个行并设置与GridViewExtend当前的头类型风格一致
17          GridViewRow willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
18          willAddHeaderRow.Font.Bold  =   true ;
19          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
20          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
21          TableCell cell  =   new  TableCell();
22          cell.Text  =   " Number " ;
23          cell.HorizontalAlign  =  HorizontalAlign.Center;
24          willAddHeaderRow.Cells.Add(cell);
25          cell  =   new  TableCell();
26          cell.Text  =   " Detail " ;
27          cell.ColumnSpan  =   2 ;
28          cell.HorizontalAlign  =  HorizontalAlign.Center;
29          willAddHeaderRow.Cells.Add(cell);
30           // 添加到GridView
31          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);
32 
33 
34           ///
35           /// /在当前HeaderRow上面再增加一行
36           // 同样创建一个行并设置与GridViewExtend当前的头类型风格一致
37          willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
38          willAddHeaderRow.Font.Bold  =   true ;
39          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
40          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
41 
42          cell  =   new  TableCell();
43          cell.Text  =   " Fruits category information " ;
44          cell.ColumnSpan  =   3 ;
45          cell.HorizontalAlign  =  HorizontalAlign.Center;
46          willAddHeaderRow.Cells.Add(cell);
47           // 添加到GridView
48          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);  
49       
50           // 还可以继续增加N个表头行;
51           // 不管增加多么, GridView控件都能够自动检测到HeaderRow的个数, 并且能够正确呈现滚动条
52           // ..;  
53           // ..; 
54      }

 

(五). 示例代码下载

        http://www.cnblogs.com/Files/MVP33650/extendgridviewfixedmultiheader.rar

 

(六). 控件开发其它相关文章:

        http://blog.youkuaiyun.com/ChengKing/category/288694.aspx

 

 

 

 

 

 

  


(一). 概述

        1. 实现GridView表头固定表体滚动效果

        2. 继承GridView的所有功能, 增加扩展功能, 表体滚动功能; 不需要另外加辅助滚动控件, 如

.

        3. 支持多行表头滚动, 此控件能够自动检测到使用者增加的表头的行数. 准确的实现表头滚动.

            有增加GridView多表头实现方案, 请看[多表头自定义控件]. 

实现原理:
    一般要实现GridView表头固定,表体滚动功能时,都是自己增加一个
控件,
然后将GridView嵌套在这个
控件里面; 使用这个 GridView 控件就不用在页面中自己
增加个
控件了, 因为它自动完成了增加
控件的功能, 具有通用性 .

(二). 运行如图

      1.  单行表头增加自动滚动效果

 

      2.  多行表头增加自动滚动效果

  

 

(三). 用法

   1. 将GridViewExpendHeader控件Dll添加引用到Web站点工程中

   2. 从工具箱拖动一个GridViewExpendHeader控件到设计器中

   3. 设置GridViewExpendHeader控件的属性.

                a.  设置属性窗口中新增的 "扩展" 类别中的两个属性,  这两个属性是指滚动区域的大小, 如下图所示:

                        

               b.  设置GridView本身的高度Height, 这个高度是指滚动区域内的GridView的实际高度, 这个高度数值设置

                     要大于ScrollHeight滚动条才能够呈现.  简单地说, 本自定义控件自动会实现一个GridView(自己)

                    的父控件

,  然后再把自己放在里面,  如果自己高度小于
高度了,  不用滚动就能够显示

                    全自己的数据, 滚动条就没有呈现的意义了.   这里讲得有点啰嗦.   .        

   4. F5运行即可

(四). 完整代码

    1. 主控件GridViewFixedMultiHeader类代码    

  1       ///   < summary >
  2       ///  Author: [ ChengKing(ZhengJian) ] 
  3       ///  Blog:   Http: // blog.youkuaiyun.com / ChengKing
  4       ///   Date :    2007 / 4 / 3
  5       ///   summary>    
  6     /// <summary>
  7     /// 主控件类, 继承GridView的所有功能
  8     ///  summary>
  9     [ToolboxData("<{0}:GridViewExpendHeader runat=server> ")]
 10     public class GridViewFixedMultiHeader : GridView 
 11     {       
 12         [Description("当需要重新构造Header时触发此事件")]
 13         public event System.EventHandler RebuildHeader;
 14 
 15         private System.Web.UI.WebControls.Panel pnlScroll = new System.Web.UI.WebControls.Panel();
 16 
 17         #region 扩展
 18         /// <summary>
 19         /// 设定滚动容器的宽度
 20         ///  summary>
 21         [Bindable(true)]
 22         [Category("扩展")]
 23         [DefaultValue("500px")]
 24         [Localizable(true)]
 25         [TypeConverter(typeof(UnitConverter))]
 26         public Unit ScrollWidth
 27         {
 28             get
 29             {
 30                 return pnlScroll.Width;
 31             }
 32             set
 33             {
 34                 pnlScroll.Width = value;
 35             }
 36         }
 37 
 38         /// <summary>
 39         /// 设定滚动容器的高度
 40         ///  summary>
 41         [Bindable(true)]
 42         [Category("扩展")]
 43         [DefaultValue("150px")]
 44         [Localizable(true)]
 45         [TypeConverter(typeof(UnitConverter))]
 46         public Unit ScrollHeight
 47         {
 48             get
 49             {
 50                 return pnlScroll.Height;
 51             }
 52             set
 53             {
 54                 pnlScroll.Height = value;
 55             }
 56         }
 57         #endregion
 58 
 59         protected override void OnPreRender(EventArgs e)
 60         {
 61             
 62             StringBuilder sb = new StringBuilder();              
 63             sb.Append(" function Tidy()");
 64             sb.Append(" {");
 65             sb.Append("     var gve = document.getElementById(/""+ this.UniqueID +"/"); ");            
 66             sb.Append("     if( gve.rows.length > 0 )");
 67             sb.Append("     {");
 68             sb.Append("         var a1 = document.getElementById(/"divHeaderContainer/");");
 69             sb.Append("         var table1 = document.createElement(/"table/");");
 70             sb.Append("         var tbody1 = document.createElement(/"tbody/");");
 71             sb.Append("         table1.style.cssText = /"table-layout:fixed;border-style: solid ;border-color:gray; border-width: 1px thin;/";   ");
 72             //sb.Append("         table1.style.cssText = /"table-layout:fixed;color:#CCCCFF;background-color:#003399;font-weight:bold;/";");
 73             sb.Append("         var i;");
 74             sb.Append("         var blnIfFind = false;");
 75             sb.Append("         for( i = gve.rows.length - 1; i >= 0; i-- )");
 76             sb.Append("         {");
 77             sb.Append("             if( gve.rows[i].children(0).tagName.toUpperCase() != /"TH/" && blnIfFind == false )  ");
 78             sb.Append("             {");
 79             sb.Append("                 continue;");
 80             sb.Append("             }");
 81             sb.Append("             if( blnIfFind == false )");
 82             sb.Append("             {");
 83             sb.Append("                 blnIfFind = true; ");
 84             sb.Append("             }");
 85             sb.Append("             if( tbody1.children.length == 0 )");
 86             sb.Append("             {");
 87             sb.Append("                 var newRow = gve.rows[i].cloneNode(true); ");
 88             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");            
 89             sb.Append("                 tbody1.appendChild( newRow ); ");
 90             sb.Append("             }");
 91             sb.Append("             else");
 92             sb.Append("             {");
 93             sb.Append("                 var newRow = gve.rows[i].cloneNode(true);   ");
 94             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");
 95             sb.Append("                 tbody1.insertBefore( newRow , tbody1.firstChild );");
 96             sb.Append("             }");
 97             sb.Append("         }");
 98             sb.Append("         table1.appendChild(tbody1);");
 99             sb.Append("         a1.appendChild(table1); ");
100             sb.Append("         for( i = 0; i < gve.rows.length -1; i++)");
101             sb.Append("         {");
102             sb.Append("             if( gve.rows[0].children(0).tagName.toUpperCase() != /"TH/" )");
103             sb.Append("             {");
104             sb.Append("                 gve.deleteRow(0);   ");
105             sb.Append("                 continue;");
106             sb.Append("             }");
107             sb.Append("             gve.deleteRow(0);   ");
108             sb.Append("             break; ");
109             sb.Append("         }");
110             sb.Append("     }");
111             sb.Append(" }");
112 
113             if (!Page.ClientScript.IsClientScriptBlockRegistered("Tidy"))
114             {
115                 Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Tidy", sb.ToString(),true);
116             }
117 
118             if (!Page.ClientScript.IsStartupScriptRegistered("Init"))
119             {
120                 Page.ClientScript.RegisterStartupScript(this.GetType(), "Init""<script type=/"text/javascript/">window.onload = Tidy;</script> "false);
121             }
122 
123             base.OnPreRender(e);
124         }
125 
126         protected override void Render(HtmlTextWriter writer)
127         {
128             OnRebuildHeader();         
129             base.Render(writer);
130         }
131         protected override void CreateChildControls()
132         {
133             Control parent = this.Parent;
134 
135             if (DesignMode == false)
136             {
137                 //生成头容器<DIV>
138                 System.Web.UI.HtmlControls.HtmlGenericControl div = new System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
139                 div.ID = "divHeaderContainer";
140                 div.Style.Add("width", this.Width.ToString());
141                 parent.Controls.Add(div);
142 
143                 Control gridView = this;
144                 parent.Controls.Remove(gridView);
145                  
146                 pnlScroll.Style.Add("width", this.Width.ToString());
147                 pnlScroll.Style.Add("OVERFLOW-Y""scroll");
148                 pnlScroll.Style.Add("OVERFLOW-X""hidden");
149        
150                 pnlScroll.Controls.Add(this);
151                 parent.Controls.Add(pnlScroll);
152 
153                 ChildControlsCreated = true;
154             }
155 
156             base.CreateChildControls();            
157         }
158     
159         protected virtual void OnRebuildHeader()
160         {
161             //重新构造Head
162             if (RebuildHeader != null)
163             {
164                 RebuildHeaderEventArgs args = new RebuildHeaderEventArgs();
165                 args.GridViewObject = this;
166                 args.HeaderRowObject = this.HeaderRow;
167 
168                 RebuildHeader(this, args);
169             }
170             
171         }       
172     } 

    2. 文件RebuildHeaderEventArgs.cs 代码

 1  ///  
 2     /// Author: [ ChengKing(ZhengJian) ] 
 3     /// Blog:   Http://blog.youkuaiyun.com/ChengKing
 4     /// Date:   2007/4/3
 5     /// 

 6       ///  
 7     /// 承载重构Header事件所需的参数[Author:ChengKing(ZhengJian)]
 8     /// 

 9       public   class  RebuildHeaderEventArgs : EventArgs
10      {
11           private  GridViewFixedMultiHeader _GridViewObject;
12           private  GridViewRow _HeaderRowObject;
13 
14           ///  
15         /// 存储GrivViewExtend对象本身
16         /// 

17           public  GridViewFixedMultiHeader GridViewObject
18          {
19               get
20              {
21                   return  _GridViewObject;
22              }
23               set
24              {
25                  _GridViewObject  =  value;
26              }
27          }
28 
29           ///  
30         /// 存储GrivViewExtend的HeaderRow对象
31         /// 

32           public  GridViewRow HeaderRowObject
33          {
34               get
35              {
36                   return  _HeaderRowObject;
37              }
38               set
39              {
40                  _HeaderRowObject  =  value;
41              }
42          }
43      }

   3. 测试页面文件default.aspx代码, 直接拖动一个控件到设计器就OK了. 不需要设置任何属性.

1 <div>
2    <asp:GridView ID="GridViewFixedMultiHeader1" runat="server"  asp:GridView>                  
3  div>

   4. 在新增自定义事件中增加表头行代码, 这里增加三行表头HeaderRow.
 1  ///  
 2     /// 具体重写方法, 此方法比较灵活, 可以任意设置您需要创建的格式, 比如更复杂的表格
 3     /// 另外, 可以直接从第二个参数中取得控件对象引用
 4     /// 

 5       ///  
 6       ///  
 7       protected   void  GridViewExpend1_RebuildHeader( object  sender, EventArgs e)
 8      {
 9           // 取得参数e中包含的对象的引用        
10          GridViewFixedMultiHeader currentGVE  =  ((RebuildHeaderEventArgs)e).GridViewObject;   // 到操作当前GridView的对象引用
11          GridViewRow currentHeaderRow  =  ((RebuildHeaderEventArgs)e).HeaderRowObject;  /// /到操作当前GridView's HeaderRow的对象引用
12 
13 
14           ///
15           /// /在当前HeaderRow上面增加一行
16           // 创建一个行并设置与GridViewExtend当前的头类型风格一致
17          GridViewRow willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
18          willAddHeaderRow.Font.Bold  =   true ;
19          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
20          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
21          TableCell cell  =   new  TableCell();
22          cell.Text  =   " Number " ;
23          cell.HorizontalAlign  =  HorizontalAlign.Center;
24          willAddHeaderRow.Cells.Add(cell);
25          cell  =   new  TableCell();
26          cell.Text  =   " Detail " ;
27          cell.ColumnSpan  =   2 ;
28          cell.HorizontalAlign  =  HorizontalAlign.Center;
29          willAddHeaderRow.Cells.Add(cell);
30           // 添加到GridView
31          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);
32 
33 
34           ///
35           /// /在当前HeaderRow上面再增加一行
36           // 同样创建一个行并设置与GridViewExtend当前的头类型风格一致
37          willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
38          willAddHeaderRow.Font.Bold  =   true ;
39          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
40          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
41 
42          cell  =   new  TableCell();
43          cell.Text  =   " Fruits category information " ;
44          cell.ColumnSpan  =   3 ;
45          cell.HorizontalAlign  =  HorizontalAlign.Center;
46          willAddHeaderRow.Cells.Add(cell);
47           // 添加到GridView
48          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);  
49       
50           // 还可以继续增加N个表头行;
51           // 不管增加多么, GridView控件都能够自动检测到HeaderRow的个数, 并且能够正确呈现滚动条
52           // ..;  
53           // ..; 
54      }

 

(五). 示例代码下载

        http://www.cnblogs.com/Files/MVP33650/extendgridviewfixedmultiheader.rar

 

(六). 控件开发其它相关文章:

        http://blog.youkuaiyun.com/ChengKing/category/288694.aspx

 

 

 

 

 

 

  


(一). 概述

        1. 实现GridView表头固定表体滚动效果

        2. 继承GridView的所有功能, 增加扩展功能, 表体滚动功能; 不需要另外加辅助滚动控件, 如

.

        3. 支持多行表头滚动, 此控件能够自动检测到使用者增加的表头的行数. 准确的实现表头滚动.

            有增加GridView多表头实现方案, 请看[多表头自定义控件]. 

实现原理:
    一般要实现GridView表头固定,表体滚动功能时,都是自己增加一个
控件,
然后将GridView嵌套在这个
控件里面; 使用这个 GridView 控件就不用在页面中自己
增加个
控件了, 因为它自动完成了增加
控件的功能, 具有通用性 .

(二). 运行如图

      1.  单行表头增加自动滚动效果

 

      2.  多行表头增加自动滚动效果

  

 

(三). 用法

   1. 将GridViewExpendHeader控件Dll添加引用到Web站点工程中

   2. 从工具箱拖动一个GridViewExpendHeader控件到设计器中

   3. 设置GridViewExpendHeader控件的属性.

                a.  设置属性窗口中新增的 "扩展" 类别中的两个属性,  这两个属性是指滚动区域的大小, 如下图所示:

                        

               b.  设置GridView本身的高度Height, 这个高度是指滚动区域内的GridView的实际高度, 这个高度数值设置

                     要大于ScrollHeight滚动条才能够呈现.  简单地说, 本自定义控件自动会实现一个GridView(自己)

                    的父控件

,  然后再把自己放在里面,  如果自己高度小于
高度了,  不用滚动就能够显示

                    全自己的数据, 滚动条就没有呈现的意义了.   这里讲得有点啰嗦.   .        

   4. F5运行即可

(四). 完整代码

    1. 主控件GridViewFixedMultiHeader类代码    

  1       ///   < summary >
  2       ///  Author: [ ChengKing(ZhengJian) ] 
  3       ///  Blog:   Http: // blog.youkuaiyun.com / ChengKing
  4       ///   Date :    2007 / 4 / 3
  5       ///   summary>    
  6     /// <summary>
  7     /// 主控件类, 继承GridView的所有功能
  8     ///  summary>
  9     [ToolboxData("<{0}:GridViewExpendHeader runat=server> ")]
 10     public class GridViewFixedMultiHeader : GridView 
 11     {       
 12         [Description("当需要重新构造Header时触发此事件")]
 13         public event System.EventHandler RebuildHeader;
 14 
 15         private System.Web.UI.WebControls.Panel pnlScroll = new System.Web.UI.WebControls.Panel();
 16 
 17         #region 扩展
 18         /// <summary>
 19         /// 设定滚动容器的宽度
 20         ///  summary>
 21         [Bindable(true)]
 22         [Category("扩展")]
 23         [DefaultValue("500px")]
 24         [Localizable(true)]
 25         [TypeConverter(typeof(UnitConverter))]
 26         public Unit ScrollWidth
 27         {
 28             get
 29             {
 30                 return pnlScroll.Width;
 31             }
 32             set
 33             {
 34                 pnlScroll.Width = value;
 35             }
 36         }
 37 
 38         /// <summary>
 39         /// 设定滚动容器的高度
 40         ///  summary>
 41         [Bindable(true)]
 42         [Category("扩展")]
 43         [DefaultValue("150px")]
 44         [Localizable(true)]
 45         [TypeConverter(typeof(UnitConverter))]
 46         public Unit ScrollHeight
 47         {
 48             get
 49             {
 50                 return pnlScroll.Height;
 51             }
 52             set
 53             {
 54                 pnlScroll.Height = value;
 55             }
 56         }
 57         #endregion
 58 
 59         protected override void OnPreRender(EventArgs e)
 60         {
 61             
 62             StringBuilder sb = new StringBuilder();              
 63             sb.Append(" function Tidy()");
 64             sb.Append(" {");
 65             sb.Append("     var gve = document.getElementById(/""+ this.UniqueID +"/"); ");            
 66             sb.Append("     if( gve.rows.length > 0 )");
 67             sb.Append("     {");
 68             sb.Append("         var a1 = document.getElementById(/"divHeaderContainer/");");
 69             sb.Append("         var table1 = document.createElement(/"table/");");
 70             sb.Append("         var tbody1 = document.createElement(/"tbody/");");
 71             sb.Append("         table1.style.cssText = /"table-layout:fixed;border-style: solid ;border-color:gray; border-width: 1px thin;/";   ");
 72             //sb.Append("         table1.style.cssText = /"table-layout:fixed;color:#CCCCFF;background-color:#003399;font-weight:bold;/";");
 73             sb.Append("         var i;");
 74             sb.Append("         var blnIfFind = false;");
 75             sb.Append("         for( i = gve.rows.length - 1; i >= 0; i-- )");
 76             sb.Append("         {");
 77             sb.Append("             if( gve.rows[i].children(0).tagName.toUpperCase() != /"TH/" && blnIfFind == false )  ");
 78             sb.Append("             {");
 79             sb.Append("                 continue;");
 80             sb.Append("             }");
 81             sb.Append("             if( blnIfFind == false )");
 82             sb.Append("             {");
 83             sb.Append("                 blnIfFind = true; ");
 84             sb.Append("             }");
 85             sb.Append("             if( tbody1.children.length == 0 )");
 86             sb.Append("             {");
 87             sb.Append("                 var newRow = gve.rows[i].cloneNode(true); ");
 88             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");            
 89             sb.Append("                 tbody1.appendChild( newRow ); ");
 90             sb.Append("             }");
 91             sb.Append("             else");
 92             sb.Append("             {");
 93             sb.Append("                 var newRow = gve.rows[i].cloneNode(true);   ");
 94             //sb.Append("                 newRow.style.cssText = 'border-style: solid ;border-color:gray; border-width: 1px thin';");
 95             sb.Append("                 tbody1.insertBefore( newRow , tbody1.firstChild );");
 96             sb.Append("             }");
 97             sb.Append("         }");
 98             sb.Append("         table1.appendChild(tbody1);");
 99             sb.Append("         a1.appendChild(table1); ");
100             sb.Append("         for( i = 0; i < gve.rows.length -1; i++)");
101             sb.Append("         {");
102             sb.Append("             if( gve.rows[0].children(0).tagName.toUpperCase() != /"TH/" )");
103             sb.Append("             {");
104             sb.Append("                 gve.deleteRow(0);   ");
105             sb.Append("                 continue;");
106             sb.Append("             }");
107             sb.Append("             gve.deleteRow(0);   ");
108             sb.Append("             break; ");
109             sb.Append("         }");
110             sb.Append("     }");
111             sb.Append(" }");
112 
113             if (!Page.ClientScript.IsClientScriptBlockRegistered("Tidy"))
114             {
115                 Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Tidy", sb.ToString(),true);
116             }
117 
118             if (!Page.ClientScript.IsStartupScriptRegistered("Init"))
119             {
120                 Page.ClientScript.RegisterStartupScript(this.GetType(), "Init""<script type=/"text/javascript/">window.onload = Tidy;</script> "false);
121             }
122 
123             base.OnPreRender(e);
124         }
125 
126         protected override void Render(HtmlTextWriter writer)
127         {
128             OnRebuildHeader();         
129             base.Render(writer);
130         }
131         protected override void CreateChildControls()
132         {
133             Control parent = this.Parent;
134 
135             if (DesignMode == false)
136             {
137                 //生成头容器<DIV>
138                 System.Web.UI.HtmlControls.HtmlGenericControl div = new System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
139                 div.ID = "divHeaderContainer";
140                 div.Style.Add("width", this.Width.ToString());
141                 parent.Controls.Add(div);
142 
143                 Control gridView = this;
144                 parent.Controls.Remove(gridView);
145                  
146                 pnlScroll.Style.Add("width", this.Width.ToString());
147                 pnlScroll.Style.Add("OVERFLOW-Y""scroll");
148                 pnlScroll.Style.Add("OVERFLOW-X""hidden");
149        
150                 pnlScroll.Controls.Add(this);
151                 parent.Controls.Add(pnlScroll);
152 
153                 ChildControlsCreated = true;
154             }
155 
156             base.CreateChildControls();            
157         }
158     
159         protected virtual void OnRebuildHeader()
160         {
161             //重新构造Head
162             if (RebuildHeader != null)
163             {
164                 RebuildHeaderEventArgs args = new RebuildHeaderEventArgs();
165                 args.GridViewObject = this;
166                 args.HeaderRowObject = this.HeaderRow;
167 
168                 RebuildHeader(this, args);
169             }
170             
171         }       
172     } 

    2. 文件RebuildHeaderEventArgs.cs 代码

 1  ///  
 2     /// Author: [ ChengKing(ZhengJian) ] 
 3     /// Blog:   Http://blog.youkuaiyun.com/ChengKing
 4     /// Date:   2007/4/3
 5     /// 

 6       ///  
 7     /// 承载重构Header事件所需的参数[Author:ChengKing(ZhengJian)]
 8     /// 

 9       public   class  RebuildHeaderEventArgs : EventArgs
10      {
11           private  GridViewFixedMultiHeader _GridViewObject;
12           private  GridViewRow _HeaderRowObject;
13 
14           ///  
15         /// 存储GrivViewExtend对象本身
16         /// 

17           public  GridViewFixedMultiHeader GridViewObject
18          {
19               get
20              {
21                   return  _GridViewObject;
22              }
23               set
24              {
25                  _GridViewObject  =  value;
26              }
27          }
28 
29           ///  
30         /// 存储GrivViewExtend的HeaderRow对象
31         /// 

32           public  GridViewRow HeaderRowObject
33          {
34               get
35              {
36                   return  _HeaderRowObject;
37              }
38               set
39              {
40                  _HeaderRowObject  =  value;
41              }
42          }
43      }

   3. 测试页面文件default.aspx代码, 直接拖动一个控件到设计器就OK了. 不需要设置任何属性.

1 <div>
2    <asp:GridView ID="GridViewFixedMultiHeader1" runat="server"  asp:GridView>                  
3  div>

   4. 在新增自定义事件中增加表头行代码, 这里增加三行表头HeaderRow.
 1  ///  
 2     /// 具体重写方法, 此方法比较灵活, 可以任意设置您需要创建的格式, 比如更复杂的表格
 3     /// 另外, 可以直接从第二个参数中取得控件对象引用
 4     /// 

 5       ///  
 6       ///  
 7       protected   void  GridViewExpend1_RebuildHeader( object  sender, EventArgs e)
 8      {
 9           // 取得参数e中包含的对象的引用        
10          GridViewFixedMultiHeader currentGVE  =  ((RebuildHeaderEventArgs)e).GridViewObject;   // 到操作当前GridView的对象引用
11          GridViewRow currentHeaderRow  =  ((RebuildHeaderEventArgs)e).HeaderRowObject;  /// /到操作当前GridView's HeaderRow的对象引用
12 
13 
14           ///
15           /// /在当前HeaderRow上面增加一行
16           // 创建一个行并设置与GridViewExtend当前的头类型风格一致
17          GridViewRow willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
18          willAddHeaderRow.Font.Bold  =   true ;
19          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
20          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
21          TableCell cell  =   new  TableCell();
22          cell.Text  =   " Number " ;
23          cell.HorizontalAlign  =  HorizontalAlign.Center;
24          willAddHeaderRow.Cells.Add(cell);
25          cell  =   new  TableCell();
26          cell.Text  =   " Detail " ;
27          cell.ColumnSpan  =   2 ;
28          cell.HorizontalAlign  =  HorizontalAlign.Center;
29          willAddHeaderRow.Cells.Add(cell);
30           // 添加到GridView
31          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);
32 
33 
34           ///
35           /// /在当前HeaderRow上面再增加一行
36           // 同样创建一个行并设置与GridViewExtend当前的头类型风格一致
37          willAddHeaderRow  =   new  GridViewRow( 0 0 , DataControlRowType.Header, DataControlRowState.Normal);
38          willAddHeaderRow.Font.Bold  =   true ;
39          willAddHeaderRow.BackColor  =  Color.FromName( " #003399 " );
40          willAddHeaderRow.ForeColor  =  Color.FromName( " #CCCCFF " );
41 
42          cell  =   new  TableCell();
43          cell.Text  =   " Fruits category information " ;
44          cell.ColumnSpan  =   3 ;
45          cell.HorizontalAlign  =  HorizontalAlign.Center;
46          willAddHeaderRow.Cells.Add(cell);
47           // 添加到GridView
48          currentGVE.Controls[ 0 ].Controls.AddAt( 0 , willAddHeaderRow);  
49       
50           // 还可以继续增加N个表头行;
51           // 不管增加多么, GridView控件都能够自动检测到HeaderRow的个数, 并且能够正确呈现滚动条
52           // ..;  
53           // ..; 
54      }

 

(五). 示例代码下载

        http://www.cnblogs.com/Files/MVP33650/extendgridviewfixedmultiheader.rar

 

(六). 控件开发其它相关文章:

        http://blog.youkuaiyun.com/ChengKing/category/288694.aspx

 

 

 

 

 

 

  


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值