[转载]ASP.NET 如何固定表头(fixed header) – JF Zhu – 博客园.
你在HTML中渲染一张表格(可能是GridView或者Repeater),如果表格的行数太多,你就得向下拖东滚动条,但你一旦向下拖动滚动条,表头的信息就不见了。具体见下图。
向下拖动滚动条后,表头信息消失:
在本文中,我向大家讲解如何固定住表头。网上可以搜索到很多种方法来实现这个功能,但这些方法基本的原理都是一样的。就是利用div,将表头的信息复制到表身之上的一个div中。
<div> 表头 </div>
<div> 表身 </div>
滚动条只在表身div中,这样拖动表身div就不会影响到表头的div了。
经过我的实验,有以下两个具体的方法比较好用,分别适用于ASP.NET的Repeater控件和GridView控件。
(一)用于Repeater控件:
WebForm1.aspx
<script type="text/javascript" language="javascript">// <![CDATA[ function FixTableHeader() { var t = document.getElementById("table"); var thead = t.getElementsByTagName("thead")[0]; var t1 = t.cloneNode(false); t1.appendChild(thead); document.getElementById("tableHeader").appendChild(t1) } window.onload = FixTableHeader; // ]]></script> <form id="form1"> <div id="tableHeader"></div> <div style="overflow: scroll; height: 100px; width: 500px;"> <table id="table" style="table-layout: fixed;" width="500"> <thead> <tr id="thead" style="background-color: #bebebe;"> <th>Account Number</th> <th>Account Name</th> <th>City</th> <th>Country</th> </tr> </thead> <tbody> <tr> <td><%#DataBinder.Eval(Container.DataItem, "AccountNumber")%></td> <td><%#DataBinder.Eval(Container.DataItem, "AccountName")%></td> <td></td> <td></td> </tr> </tbody> </table> </div> </form>
注意,如果你想表头和表身的每一列都对齐的话,table的style=”table-layout: fixed”不能少。
C#文件
using System; using System.Web.UI; using System.Data; namespace WebApplication1 { public partial class WebForm1 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { DataTable dt = new DataTable(); dt.Columns.Add(new DataColumn("AccountNumber")); dt.Columns.Add(new DataColumn("AccountName")); dt.Columns.Add(new DataColumn("City")); dt.Columns.Add(new DataColumn("Country")); DataRow dr = dt.NewRow(); dr["AccountName"] = "Test1"; dr["AccountNumber"] = "001"; dr["Country"] = "China"; dr["City"] = "Beijing"; dt.Rows.Add(dr); dr = dt.NewRow(); dr["AccountName"] = "Test2"; dr["AccountNumber"] = "002"; dr["Country"] = "China"; dr["City"] = "Shanghai"; dt.Rows.Add(dr); dr = dt.NewRow(); dr["AccountName"] = "Test3"; dr["AccountNumber"] = "003"; dr["Country"] = "the Nederlands"; dr["City"] = "Amsterdam"; dt.Rows.Add(dr); dr = dt.NewRow(); dr["AccountName"] = "Test4"; dr["AccountNumber"] = "004"; dr["Country"] = "France"; dr["City"] = "Paris"; dt.Rows.Add(dr); dr = dt.NewRow(); dr["AccountName"] = "Test5"; dr["AccountNumber"] = "005"; dr["Country"] = "Spain"; dr["City"] = "Barcelona"; dt.Rows.Add(dr); dr = dt.NewRow(); dr["AccountName"] = "Test6"; dr["AccountNumber"] = "006"; dr["Country"] = "China"; dr["City"] = "Shanghai"; dt.Rows.Add(dr); Reapeter1.DataSource = dt; Reapeter1.DataBind(); } } } }
最后的效果为:
(二) 用于GridView控件:
WebForm2.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm2.aspx.cs" Inherits="WebApplication1.WebForm2" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Head1" runat="server"> <title></title> <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script> <script src="Scripts/ScrollableGridPlugin.js" type="text/javascript"></script> <script type="text/javascript"> $(document).ready(function () { $('#<%=GridView1.ClientID %>').Scrollable({ ScrollHeight: 100, Width: 500 }); }); </script> </head> <body> <form id="form1" runat="server"> <div> <asp:GridView runat="server" ID="GridView1" AutoGenerateColumns="false" Width="500px"> <RowStyle BackColor="#EFF3FB" /> <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> <AlternatingRowStyle BackColor="White" /> <Columns> <asp:BoundField DataField="AccountNumber" HeaderText="Account Number"> </asp:BoundField> <asp:BoundField DataField="AccountName" HeaderText="Account Name"> </asp:BoundField> <asp:BoundField DataField="City" HeaderText="City" > </asp:BoundField> <asp:BoundField DataField="Country" HeaderText="Country"> </asp:BoundField> </Columns> </asp:GridView> </div> </form> </body> </html>
这里主要用到了JQuery和ScrollableGridPlugin.js插件。ScrollableGridPlugin.js插件很好用,想要哪个GridView固定住表头,只需要在开始的Script中加入以下的代码。第一个参数用来设置表的高度,第二个设置表宽,单位都为px。这两个参数也可以省略,ScrollableGridPlugin.js中会设置默认值。
$(document).ready(function () { $('#<%=GridView1.ClientID %>').Scrollable({ ScrollHeight: 100, Width: 500 }); });
ScrollableGridPlugin.js的代码为:
(function ($) { $.fn.Scrollable = function (options) { var defaults = { ScrollHeight: 300, Width: 0 }; var options = $.extend(defaults, options); return this.each(function () { var grid = $(this).get(0); var gridWidth = grid.offsetWidth; var gridHeight = grid.offsetHeight; var headerCellWidths = new Array(); for (var i = 0; i < grid.getElementsByTagName("TH").length; i++) { headerCellWidths[i] = grid.getElementsByTagName("TH")[i].offsetWidth; } grid.parentNode.appendChild(document.createElement("div")); var parentDiv = grid.parentNode; var table = document.createElement("table"); for (i = 0; i < grid.attributes.length; i++) { if (grid.attributes[i].specified && grid.attributes[i].name != "id") { table.setAttribute(grid.attributes[i].name, grid.attributes[i].value); } } table.style.cssText = grid.style.cssText; table.style.width = gridWidth + "px"; table.appendChild(document.createElement("tbody")); table.getElementsByTagName("tbody")[0].appendChild(grid.getElementsByTagName("TR")[0]); var cells = table.getElementsByTagName("TH"); var gridRow = grid.getElementsByTagName("TR")[0]; for (var i = 0; i < cells.length; i++) { var width; if (headerCellWidths[i] > gridRow.getElementsByTagName("TD")[i].offsetWidth) { width = headerCellWidths[i]; } else { width = gridRow.getElementsByTagName("TD")[i].offsetWidth; } cells[i].style.width = parseInt(width - 3) + "px"; gridRow.getElementsByTagName("TD")[i].style.width = parseInt(width - 3) + "px"; } parentDiv.removeChild(grid); var dummyHeader = document.createElement("div"); dummyHeader.appendChild(table); parentDiv.appendChild(dummyHeader); if (options.Width > 0) { gridWidth = options.Width; } var scrollableDiv = document.createElement("div"); if (parseInt(gridHeight) > options.ScrollHeight) { gridWidth = parseInt(gridWidth) + 17; } scrollableDiv.style.cssText = "overflow:auto;height:" + options.ScrollHeight + "px;width:" + gridWidth + "px"; scrollableDiv.appendChild(grid); parentDiv.appendChild(scrollableDiv); }); }; })(jQuery);
C#的代码为:
using System; using System.Web.UI; using System.Data; namespace WebApplication1 { public partial class WebForm2 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { DataTable dt = new DataTable(); dt.Columns.Add(new DataColumn("AccountNumber")); dt.Columns.Add(new DataColumn("AccountName")); dt.Columns.Add(new DataColumn("City")); dt.Columns.Add(new DataColumn("Country")); DataRow dr = dt.NewRow(); dr["AccountName"] = "Test1"; dr["AccountNumber"] = "001"; dr["Country"] = "China"; dr["City"] = "Beijing"; dt.Rows.Add(dr); dr = dt.NewRow(); dr["AccountName"] = "Test2"; dr["AccountNumber"] = "002"; dr["Country"] = "China"; dr["City"] = "Shanghai"; dt.Rows.Add(dr); dr = dt.NewRow(); dr["AccountName"] = "Test3"; dr["AccountNumber"] = "003"; dr["Country"] = "the Nederlands"; dr["City"] = "Amsterdam"; dt.Rows.Add(dr); dr = dt.NewRow(); dr["AccountName"] = "Test4"; dr["AccountNumber"] = "004"; dr["Country"] = "France"; dr["City"] = "Paris"; dt.Rows.Add(dr); dr = dt.NewRow(); dr["AccountName"] = "Test5"; dr["AccountNumber"] = "005"; dr["Country"] = "Spain"; dr["City"] = "Barcelona"; dt.Rows.Add(dr); dr = dt.NewRow(); dr["AccountName"] = "Test6"; dr["AccountNumber"] = "006"; dr["Country"] = "China"; dr["City"] = "Shanghai"; dt.Rows.Add(dr); GridView1.DataSource = dt; GridView1.DataBind(); } } } }