ASP

本类阅读TOP10

·asp常用数据库连接方法和技巧
·无组件生成BMP验证码
·一些常用的辅助代码 (网络收藏)
·JavaScript实现的数据表格:冻结列、调整列宽和客户端排序
·VisualStudio.NET_2003及其 MSDN 下载地址
·ASP模拟MVC模式编程
·图片以二进制流输出到网页
·MD5加密算法 ASP版
·ASP.NET编程中的十大技巧
·改进 ASP 的字符串处理性能

分类导航
VC语言Delphi
VB语言ASP
PerlJava
Script数据库
其他语言游戏开发
文件格式网站制作
软件工程.NET开发
有滚动条、固定Header的ASP.Net DataGrid实现

作者:未知 来源:月光软件站 加入时间:2005-2-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.");

      }

    }

  }

}




相关文章

相关软件