How to freeze the Top Row Dynamically of a Table Server Control in ASP.NET

In my current consulting project, I needed to create a control that would allow me to scroll the rows but keep the top row frozen. Admittedly, this created quite a challenge.

I finally found an article that lead me in the right direction

http://web.tampabay.rr.com/bmerkey/examples/locked-column-csv.html

In order to lock the header of a table server control.  Create a style sheet with the following style for your td tag:

td.locked, th.locked{
border-right: 1px solid silver;
left: expression(parentNode.parentNode.parentNode.parentNode.scrollLeft); /* IE5+ only */

position: relative;
z-index: 10;
background-color:#ACCBE0;
border-color:#D3E0EA;
}

Reference your style sheet in your page's header:

<head runat="server">
<link rel="stylesheet" href="../App_Themes/LockingHeaderRow.css" type="text/css" title="" />
<title>Master Page</title>
</
head>

The table must be initially inside a div tag to scroll:

<div id="persistMe" runat="server" style="width:1000px; height:300px; overflow:auto; z-index:55" >

<asp:Table ID="Table1" runat="server" GridLines="Both" EnableViewState="false" BorderStyle="Solid" BorderWidth="1" Width="1000px" >

<asp:TableRow ID="TableRow2" runat="server" BackColor="White" BorderWidth="1px"><asp:TableCell ID="TableCell25" runat="server"></asp:TableCell><asp:TableCell ID="TableCell28" runat="server">7:00</asp:TableCell><asp:TableCell ID="TableCell29" runat="server">8:00</asp:TableCell><asp:TableCell ID="TableCell30" runat="server">9:00</asp:TableCell><asp:TableCell ID="TableCell31" </asp:Table>
</
div>

When you are dynamically creating or updating the table, set the style of all the cells in the row to the "locked" style class.

TableCell cornerCell = new TableCell();
cornerCell.ID = "CornerCell";
cornerCell.BackColor = Color.LightGray;
cornerCell.Width = 55;
cornerCell.CssClass = "locked";

Notes and Comments:

  • There may be a way to do this with the THead tag, but I haven't figured it out.  Also, you can use this technique for the GridView as well, by accessing the table underlying the GridView.
  • I'm not sure if this works for FireFox (I suspect it doesn't)
  • If you have a horizontal scroll bar in your div, it will throw the header off because the header is locked

Please feel free to post any comments if you have other suggestions