Lately I’ve been working on a pet project where I needed to freeze a GridView header so that it didn’t move while the grid records were scrolled by an end user. After searching the Web I came across a lot of “pure” CSS ways to freeze a header. After researching them more they tend to rely on a lot of CSS hacks to do the job and require HTML to be structured in a custom way. I also found a lot of custom GridView classes (another one here), and more. Some of the solutions were really good while others seemed a bit over the top and required a lot of custom C# or VB.NET code just to do something as simple as freezing a header. Freezing a header requires CSS and potentially JavaScript depending upon what needs done. Regardless if CSS or JavaScript are used, these are client-side technologies of course. I started to write my own derivative of the GridView class but quickly realized that it made more sense to use the standard GridView control and simply extend it from the client-side. An example of what I was after is shown next:

In the past I’ve always made a scrollable GridView by wrapping a
I decided to build my own client-side GridView “extender” code to accomplish the task since I didn’t want to worry about yet another GridView assembly being in my toolbox just to freeze a header. It appears to work great in IE6+ and Firefox 2 (haven’t tried FireFox 1 – 1.5) although I’m sure there are some ways it could be improved and I can’t say I’ve done extensive testing. The code basically grabs the first header row from the GridView using JavaScript and moves it inside of a THEAD tag so that CSS can easily be applied to all of the TH tags and things work well in FireFox. It then applies a few styles to the appropriate items within the GridView HTML that is generated.
The JavaScript and CSS code is shown below
<style type="text/css"><!--
.WrapperDiv {
width:800px;height:400px;border: 1px solid black;
}
.WrapperDiv TH {
position:relative;
}
.WrapperDiv TR
{
/* Needed for IE */
height:0px;
}
--></style>
<script type="text/javascript"><!--
function onLoad()
{
FreezeGridViewHeader('GridView1','WrapperDiv');
}
function FreezeGridViewHeader(gridID,wrapperDivCssClass)
{
/// <summary>
/// Used to create a fixed GridView header and allow scrolling
///
///
<span name="gridID" type="String" class="mceItemParam"></span>
/// Client-side ID of the GridView control
///
///
<span name="wrapperDivCssClass" type="String" class="mceItemParam"></span>
/// CSS class to be applied to the GridView's wrapper div element.
/// Class MUST specify the CSS height and width properties.
/// Example: width:800px;height:400px;border:1px solid black;
///
var grid = document.getElementById(gridID);
if (grid != 'undefined')
{
grid.style.visibility = 'hidden';
var div = null;
if (grid.parentNode != 'undefined')
{
//Find wrapper div output by GridView
div = grid.parentNode;
if (div.tagName == "DIV")
{
div.className = wrapperDivCssClass;
div.style.overflow = "auto";
}
}
//Find DOM TBODY element and remove first TR tag from
//it and add to a THEAD element instead so CSS styles
//can be applied properly in both IE and FireFox
var tags = grid.getElementsByTagName('TBODY');
if (tags != 'undefined')
{
var tbody = tags[0];
var trs = tbody.getElementsByTagName('TR');
var headerHeight = 8;
if (trs != 'undefined')
{
headerHeight += trs[0].offsetHeight;
var headTR = tbody.removeChild(trs[0]);
var head = document.createElement('THEAD');
head.appendChild(headTR);
grid.insertBefore(head, grid.firstChild);
}
//Needed for Firefox
tbody.style.height =
(div.offsetHeight - headerHeight) + 'px';
tbody.style.overflowX = "hidden";
tbody.overflow = 'auto';
tbody.overflowX = 'hidden';
}
grid.style.visibility = 'visible';
}
}
// --></script>

Related Listings:
No comments yet.
RSS feed for comments on this post. TrackBack URL