有滚动条、固定Header的ASP.Net DataGrid实现

简介: 客户要一个有滚动条的ASP.Net DataGrid控件,只好写了: ");> using  System; using  System.

客户要一个有滚动条的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. " );

      }

    }

  }

}

目录
相关文章
|
JavaScript 前端开发 数据库
|
Web App开发
RDIFramework.NET框架Web中datagrid与treegrid控件自动生成右键菜单与列标题右键菜单
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chinahuyong/article/details/51490149   在实际应用中常可以看到数据展示控件有右键菜单的功能,对应的列标题也可以右键弹出快捷菜单设置指定列的显示与隐藏等功能。
918 0