zoukankan      html  css  js  c++  java
  • 有滚动条、固定Header的ASP.Net DataGrid实现

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

          }

        }

      }

    }

  • 相关阅读:
    java学习day39--SSM整合(方案二)
    java学习day39--SSM整合(方案一)
    @PathVariable注解的作用
    Ajax接收Json数据,调用template模板循环渲染页面的方法
    JS中的DOM与BOM
    关于req.params、req.query、req.body等请求对象
    EJS 高效的 JavaScript 模板引擎
    JavaScript中的变量在内存中的具体存储形式
    JavaScript规定了几种语言类型?
    移动端电商项目总结
  • 原文地址:https://www.cnblogs.com/Spring/p/366608.html
Copyright © 2011-2022 走看看