博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
有滚动条、固定Header的ASP.Net DataGrid实现
阅读量:6258 次
发布时间:2019-06-22

本文共 8421 字,大约阅读时间需要 28 分钟。

客户要一个有滚动条的ASP.Net DataGrid控件,只好写了:

using
 System;
using
 System.Web.UI;
using
 System.Web.UI.WebControls;
using
 System.ComponentModel;
using
 System.Diagnostics;
using
 System.IO;
using
 System.Web.UI.Design.WebControls;
using
 System.Text;
using
 System.Drawing;
 
[assembly:TagPrefix(
"
Microsoft.Gtec.Dsv
"
"
gtecdsv
"
)]
namespace
 Microsoft.Gtec.Dsv
{
  
///
 
<summary>
  
///
 Summary description for WebCustomControl1.
  
///
 
</summary>
  [ToolboxData(
"
<{0}:ScrollableFixedHeaderDataGrid runat=server></{0}:ScrollableFixedHeaderDataGrid>
"
)]
  
public
 
class
  ScrollableFixedHeaderDataGrid: System.Web.UI.WebControls.DataGrid
  {
    
protected
 
override
 
void
 Render(HtmlTextWriter output)
    {
      
//
Use this flag to determine whether the component is in design-time or runtime.
      
//
The control will be rendered differently in IDE.
      
//
Don't bother to use DataGridDesigner.GetDesignTimeHtml
      
bool
 designMode 
=
 ((Site 
!=
 
null
&&
 (Site.DesignMode));
      
//
Backing up the properties need to change during the render process
      
string
 tempLeft 
=
 Style[
"
LEFT
"
];
      
string
 tempTop 
=
 Style[
"
TOP
"
];
      Unit tempHeight 
=
 Height;
      
string
 tempTableStyle 
=
 Style[
"
TABLE-LAYOUT
"
];
 
      
//
Render a "<div>" container with scrollbars.
      output.WriteBeginTag(
"
div
"
);
      output.WriteAttribute(
"
id
"
,ID 
+
 
"
_div
"
);
      output.WriteAttribute(
"
style
"
,
        
"
HEIGHT: 
"
 
+
 Height 
+
 
"
;
"
 
+
        
//
Leave 20px for the vertical scroll bar,
        
//
assuming the end-user will not set his scroll bar to more than 20px.
        
"
WIDTH: 
"
 
+
 (Width.Value 
+
 
20
+
 
"
px;
"
 
+
        
"
TOP: 
"
 
+
 Style[
"
TOP
"
+
 
"
;
"
 
+
        
"
LEFT: 
"
 
+
 Style[
"
LEFT
"
+
 
"
;
"
 
+
        
"
POSITION: 
"
 
+
 Style[
"
POSITION
"
+
 
"
;
"
 
+
        
"
OVERFLOW-X: auto;
"
 
+
        
"
Z-INDEX: 
"
 
+
 Style[
"
Z-INDEX
"
+
 
"
;
"
 
+
        
//
Render the scrollbar differently for design-time and runtime.
        
"
OVERFLOW-Y: 
"
 
+
 (designMode
?
"
scroll
"
:
"
auto
"
)
        );
      output.Write(HtmlTextWriter.TagRightChar);
                       
      
//
The DataGrid is inside the "<div>" element, so place it at (0,0).
      Style[
"
LEFT
"
=
 
"
0px
"
;
      Style[
"
TOP
"
=
 
"
0px
"
;
      
//
Render the DataGrid.
      
base
.Render(output);
      output.WriteEndTag(
"
div
"
);
      
//
Restore the values
      Style[
"
LEFT
"
=
 tempLeft;
      Style[
"
TOP
"
=
 tempTop;
 
      
//
The following rendering is only necessary under runtime. It has negative impact during design time.
      
if
 (
!
designMode)
      {
        
//
Render another copy of the DataGrid with only headers.
        
//
Render it after the DataGrid with contents,
        
//
so that it is on the top. Z-INDEX is more complex here.
        
//
Set Height to 0, so that it will adjust on its own.
        Height 
=
 
new
 Unit(
"
0px
"
);
        StringWriter sw 
=
 
new
 StringWriter();
        HtmlTextWriter htw 
=
 
new
 HtmlTextWriter(sw);
        
//
This style is important for matching column widths later.
        Style[
"
TABLE-LAYOUT
"
=
 
"
fixed
"
;
        
base
.Render(htw);
        StringBuilder sbRenderedTable 
=
 sw.GetStringBuilder();
        htw.Close();
        sw.Close();
        Debug.Assert((sbRenderedTable.Length 
>
 
0
),
          
"
Rendered HTML string is empty. Check viewstate usage and databinding.
"
);
        
string
 temp 
=
 sbRenderedTable.ToString();
        
if
 (sbRenderedTable.Length 
>
 
0
)
        {
          
//
AllowPaging at the top?
          
if
 ((AllowPaging) 
&&
 ((PagerPosition.Top 
==
 PagerStyle.Position 
||
 (PagerPosition.TopAndBottom 
==
 PagerStyle.Position))))
          {
            Trace.WriteLine(temp);
            sbRenderedTable.Replace(ID,ID 
+
 
"
_Pager
"
0
, (temp.IndexOf(ID) 
+
 ID.Length));
            temp 
=
 sbRenderedTable.ToString();
            
string
 pager 
=
 temp.Substring(
0
, temp.ToLower().IndexOf(
@"
</tr>
"
+
 
5
);
            Trace.WriteLine(pager);
            output.Write(pager);
            output.WriteEndTag(
"
table
"
);
            
//
Start of pager's <tr>
            
int
 start 
=
 temp.ToLower().IndexOf(
@"
<tr
"
);
            
//
End of pager's </tr>
            
int
 end 
=
 temp.ToLower().IndexOf(
@"
</tr>
"
+
 
5
;
            
//
Remove the <tr> for pager from the string. Prepare to render the headers.
            sbRenderedTable.Remove(start,end
-
start);
            Trace.WriteLine(sbRenderedTable.ToString());
            sbRenderedTable.Replace(ID 
+
 
"
_Pager
"
,ID 
+
 
"
_Headers
"
0
, (temp.IndexOf(ID
+
"
_Pager
"
+
 (ID
+
"
_Pager
"
).Length));
            temp 
=
 sbRenderedTable.ToString();
            
string
 tableHeaders 
=
 temp.Substring(
0
, (temp.ToLower()).IndexOf(
@"
</tr>
"
+
 
5
);
            Trace.WriteLine(tableHeaders);
            output.Write(tableHeaders);
            output.WriteEndTag(
"
table
"
);
            
string
 headerID 
=
 ID 
+
 
"
_Headers
"
;
            
string
 pagerID 
=
 ID 
+
 
"
_Pager
"
;
            
string
 divID 
=
 ID 
+
 
"
_div
"
;
            
string
 adjustWidthScript 
=
 
@"
                                                <script language=javascript>
                                                        //debugger;
                                                        var headerTableRow = 
"
 
+
 headerID 
+
 
@"
.rows[0];
                                                        var originalTableRow = 
"
 
+
 ID 
+
 
@"
.rows[1];
"
              
//
Adjust header row's height.
              
+
 
@"
                                                        headerTableRow.height = originalTableRow.offsetHeight;
                                                        
"
 
+
              
//
Adjust pager row's height, width.
              pagerID 
+
 
@"
.rows[0].height = 
"
 
+
 ID 
+
 
@"
.rows[0].offsetHeight;
                                                        
"
 
+
              pagerID 
+
 
@"
.style.width = 
"
 
+
 ID 
+
 
@"
.offsetWidth;
                                                        for (var i = 0; i < headerTableRow.cells.length; i++) {
                                                                headerTableRow.cells[i].width = originalTableRow.cells[i].offsetWidth;
                                                        }
                                                        
"
 
+
              
//
Also needs to adjust the width of the "<div>" at client side in addition to servier side,
              
//
since the Table's actual width can go beyond the width specified at server side under Edit mode.
              
//
The server side width manipulation is mainly for design-time appearance.
              divID 
+
 
@"
.style.width = 
"
 
+
 ID 
+
 
@"
.offsetWidth + 20 + 'px';
                                                                
"
 
+
              
//
The following script is for flow-layout. We cannot get the position of the control
              
//
on server side if the the page is with flow-layout.
              headerID 
+
 
@"
.style.left = 
"
 
+
 divID 
+
 
@"
.offsetLeft;
                                                                
"
 
+
              headerID 
+
 
@"
.style.top = 
"
 
+
 divID 
+
 
@"
.offsetTop + 
"
 
+
 pagerID 
+
 
@"
.offsetHeight;
                                                                
"
 
+
              headerID 
+
 
@"
.style.position = 'absolute';
                                                                
"
 
+
              pagerID 
+
 
@"
.style.left = 
"
 
+
 divID 
+
 
@"
.offsetLeft;
                                                                
"
 
+
              pagerID 
+
 
@"
.style.top = 
"
 
+
 divID 
+
 
@"
.offsetTop;
                                                                
"
 
+
              pagerID 
+
 
@"
.style.position = 'absolute';
                                                </script>
"
;
            Page.RegisterStartupScript(
"
dummyKey
"
 
+
 
this
.ID, adjustWidthScript);
            
//
output.Write(adjustWidthScript);
          }
          
else
          {
            
//
Replace the table's ID with a new ID.
            
//
It is tricky that we must only replace the 1st occurence,
            
//
since the rest occurences can be used for postback scripts for sorting.
            sbRenderedTable.Replace(ID,ID 
+
 
"
_Headers
"
0
, (temp.IndexOf(ID) 
+
 ID.Length));
            Trace.WriteLine(sbRenderedTable.ToString());
            
//
We only need the headers, stripping the rest contents.
            temp 
=
 sbRenderedTable.ToString();
            
string
 tableHeaders 
=
 temp.Substring(
0
, (temp.ToLower()).IndexOf(
@"
</tr>
"
+
 
5
);
            Trace.WriteLine(tableHeaders);
            output.Write(tableHeaders);
            output.WriteEndTag(
"
table
"
);
            
//
Client side script for matching column widths.
            
//
Can't find a way to do this on the server side, since the browser can change widths on the client side.
            
string
 adjustWidthScript 
=
 
@"
                                                <script language=javascript>
                                                        //debugger;
                                                        var headerTableRow = 
"
 
+
 
this
.ID 
+
 
@"
_Headers.rows[0];
                                                        var originalTableRow = 
"
 
+
 
this
.ID 
+
 
@"
.rows[0];
                                                        headerTableRow.height = originalTableRow.offsetHeight;
                                                        for (var i = 0; i < headerTableRow.cells.length; i++) {
                                                                headerTableRow.cells[i].width = originalTableRow.cells[i].offsetWidth;
                                                        }
                                                        
"
 
+
              
//
Also needs to adjust the width of the "<div>" at client side in addition to servier side,
              
//
since the Table's actual width can go beyond the width specified at server side under Edit mode.
              
//
The server side width manipulation is mainly for design-time appearance.
              
this
.ID 
+
 
"
_div
"
 
+
 
@"
.style.width = 
"
 
+
 
this
.ID 
+
 
@"
.offsetWidth + 20 + 'px';
                                                                
"
 
+
              
//
The following script is for flow-layout. We cannot get the position of the control
              
//
on server side if the the page is with flow-layout.
              
this
.ID 
+
 
"
_Headers
"
 
+
 
@"
.style.left = 
"
 
+
 
this
.ID 
+
 
@"
_div.offsetLeft;
                                                                
"
 
+
              
this
.ID 
+
 
"
_Headers
"
 
+
 
@"
.style.top = 
"
 
+
 
this
.ID 
+
 
@"
_div.offsetTop;
                                                                
"
 
+
              
this
.ID 
+
 
"
_Headers
"
 
+
 
@"
.style.position = 'absolute';
                                                </script>
"
;
            Page.RegisterStartupScript(
"
dummyKey
"
 
+
 
this
.ID, adjustWidthScript);
            
//
output.Write(adjustWidthScript);
          }
          Height 
=
 tempHeight;
          Style[
"
TABLE-LAYOUT
"
=
 tempTableStyle;
        }
      }
    }
               
    
protected
 
override
 
void
 OnInit(EventArgs e)
    {
      
if
 (
0
 
==
 Width.Value) Width 
=
 
new
 Unit(
"
400px
"
);
      
if
 (
0
 
==
 Height.Value) Height 
=
 
new
 Unit(
"
200px
"
);
      
//
Transparent header is not allowed.
      
if
 (HeaderStyle.BackColor.IsEmpty)
      {
        HeaderStyle.BackColor 
=
 Color.White;
      }
      
//
Transparent pager is not allowed.
      
if
 (PagerStyle.BackColor.IsEmpty)
      {
        PagerStyle.BackColor 
=
 Color.White;
      }
 
      
base
.OnInit (e);
    }
 
    [Browsable(
false
)]
    
public
 
override
 
bool
 ShowHeader
    {
      
get
      {
        
return
 
true
;
      }
      
set
      {
        
if
 (
false
 
==
 value)
          
throw
 
new
 InvalidOperationException(
"
Use the original DataGrid to set ShowHeaders to false.
"
);
      }
    }
  }
}

转载于:https://www.cnblogs.com/Spring/archive/2006/04/04/366608.html

你可能感兴趣的文章
POJ 2057 The Lost House (经典树形dp)
查看>>
C#与Java的比较(转)
查看>>
jquery checkbox
查看>>
GNU make manual 翻译(三十二)
查看>>
内存泄漏简介
查看>>
管理内核模块
查看>>
SQL NOTE--CURSOR
查看>>
cvMatND 多维数组 设置和读取像素值
查看>>
使用XML文件方式配置log4cxx(log4cxx xml例子)
查看>>
java读写文件大全 [转]
查看>>
C语言学习必读
查看>>
分享一个String Replace方法
查看>>
温习 Linux 命令
查看>>
可扩展性设计之Cache与Search的利用
查看>>
unity3d常见问题
查看>>
压缩UIImage
查看>>
hdu1509
查看>>
Eclipse+PyDev 安装和配置
查看>>
使用SQLServer Audit来监控触发器的启用、禁用情况(转载)
查看>>
OFBIZ Party Relationship 关系图
查看>>