The Pavement
Web Design and Application Develop

Freezing GridView Headers and Columns

July 18, 2007 01:53 by Shaun

I am currently developing an ASP.NET web based planning application for a client. The application is very data heavy with a lot of pages displaying large amounts of data in a tabular format. As you would expect I’ve implemented this using a combination of SQL stored procedures, .NET DataTables and finally a GridView on the page itself. I thought I was almost done until a resent review meeting where the client suggested it would be great if they could freeze the table headers and left most columns just like Excel so that they could view the large tables more easily.

After a bit of googling I found a number of examples of how this can be done to html tables all using a combination of CSS and javascript expressions contained within the style sheet itself. A great example can be found here. However when I tried to apply this to an ASP.NET GridView it didn’t work without a fair bit of tweaking! I thought I’d step through what I did to help anybody out faced with a similar demanding clients!

There are three parts to setting this up:

  1. The Mark-up
  2. The CSS
  3. The server side code to apply the relevant styles

The Mark Up

The main issue is that by default the GridView does not render its table header cells as <th> elements instead using the <td> element (Bad Microsoft!). However there is a way around this, by adding the UseAccessibleHeader="True" attribute to the datagrid we can force the control to render in a more compliant way and use the <th> elements. We also need to wrap the Gridview control in a div element to provide the scroll functionality.

<div id="GridViewScrollContainer">
   <asp:GridView UseAccessibleHeader="true" ID="GridView1" runat="server" OnRowDataBound="GridView1_RowDataBound">
    </asp:GridView>
</div> 

The CSS

The following CSS is then used to implement the frozen elements, one thing to note is that if you change the name of the surrounding Div in your mark-up make sure you also change the name in the getElementById expressions.

#GridViewScrollContainer
{
    width: 97%;
    height: 400px;
    overflow: auto;
    margin-left: 5px;
} div#GridViewScrollContainer table th
{
    width: 100px;
} #GridViewScrollContainer th
{
    top: expression(document.getElementById(   "GridViewScrollContainer" ).scrollTop-2);
    z-index: 20;
} #GridViewScrollContainer td.locked, #GridViewScrollContainer th.locked
{
    left: expression(document.getElementById(   "GridViewScrollContainer" ).scrollLeft);
    position: relative;
    z-index: 100;
    border: solid 1px white;
}
#GridViewScrollContainer th, #GridViewScrollContainer th.locked
{
    position: relative;
    cursor: default;
    border: solid 1px white;
}
#GridViewScrollContainer th.locked
{
    z-index: 110;
}

The Server side code

Finally on the RowDataBound event of the GridViewControl we can allocate the columns that we wish to freeze the relevant CssClass.

protected void gvResults_RowDataBound(object sender, GridViewRowEventArgs e)
{
  //lock the first 3 columns
  e.Row.Cells[0].CssClass = locked;
  e.Row.Cells[1].CssClass = locked;
  e.Row.Cells[2].CssClass = locked;
}

One major thing to note is that this solution will not work in IE7 if you mark your page with an XHTML 1.0 doc type,  I believe this is due to the lack of support for the CSS expressions  going forward. To solve the problem change the doc type from XHTML 1.0 to the old HTML 4.0 shown below:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

This obvisly isnt ideal because you are essentially throwing the browser back into ‘qwerks’ mode but for my particular page this didn’t have any adverse effects, plus the application will be running in a closed envirnment where IE6 and 7 are the only browsers in use.

I Hope this helps people and please let me know if you have any comments / suggestions for a more cross browser solution.

Tags: Tags: ,
Categories: .NET
Actions: E-mail | Permalink | Comments (15) | Comment RSSRSS comment feed

Related posts

Comments

September 6. 2007 09:41

Gravatar

Thanks a lot..... U have done a brilliant job....
It was the most helpful code....
We have to fulfil these demanding clients.....thats very much true....

Pradish

September 6. 2007 09:52

Gravatar

No Problem. Glad the code came in handy :)

Shaun

September 6. 2007 10:10

Gravatar

Hi

I am having an issue whereby the locked keyword is not identified on C#

e.Row.Cells[0].CssClass = locked;

Any Ideas

Sri.

Sri

September 6. 2007 10:48

Gravatar

Hi Sri,

My fault, locked should actually be a string, i.e

e.Row.Cells[0].CssClass = "locked";

This will then assign the correct CSS class to the table column.

good luck!

Shaun

September 13. 2007 21:35

Gravatar

hi shaun,
how can i use this cssclass code with vb language?..

my problem is..

'expression(document.getElementById( "GridViewScrollContainer" ).scrollTop-2)'

is not valid value for top property..

rahman

December 15. 2007 13:09

Gravatar

Please help me.......
I want to slide the header or u can say movable like u see in excel sheet.
u can grow the size of a column.
how can i do it with asp 2.0

prashant

January 31. 2008 19:07

Gravatar

Shaun: You are brilliant! Yes, what a brilliant job you had done! Congratulation. I have not used your code yet. I am sure I will. Just want to send you my thanks! -EB

EB

February 12. 2008 08:25

Gravatar

This is very Helpful,
Plz can anybody tell me any work around for Firefox browser.
Thanks in advance:-)

Shankar

February 16. 2008 04:34

Gravatar

When I use "HTML 4.0 Transitional" the fonts on the page becomes big. Can you help me how to set the font size on the browser so same earlier layout of XHTML 1.0 can be preserved.

Thanks,

KK

March 6. 2008 12:33

Gravatar

Gr8 post... helped a lot ...thanxs :)

sjoseph

March 15. 2008 12:04

Gravatar

Hi
I have attached som custom controls under the header template of the Grid View.
My proble is when i apply this css then the header comes out of the div.

Thanks & Regards,
Amit

Amit Mehta

March 26. 2008 13:46

Gravatar

This worked liked a charm.

Any suggestions though for dealing with large GridViews to avoid having to use the expression syntax

I have a gridview that has about 60 columns composed of a variety of controls, such as text boxes, drop down boxes, etc.

The grid reponds fine to client events, up until the expressions are added.

I built a similar grid before, that just locks the headers, not the columns, but I used a separate table and some javascript. In this case, the 60 columns are requiring me to lock the first three columns. I could build something similar, using two datagrids, but I was wondering if you had another suggestion for the sake of performance

Thanks

Robert

May 19. 2008 05:41

Gravatar

Hi am facing Performance issue while using this code. The browser gets hang when number of records in grid view increases . If you have any solution for this u can mail me. Thanks in advance.

Satheesh Kumar

June 19. 2008 02:53

Gravatar

U have done a brilliant job....
Gr8 code,I was in fix since 2 days but u gave perfect sln.
Thanks....

Ankur

June 25. 2008 05:47

Gravatar

Hi I am facing Performance issue while using this code. It works but very slow when i fetch large table from database.If you have any solution regarding this plz mail me. Thanks

Ankur Juneja

Add comment


(Will show your Gravatar icon)  

  Country flag




Live preview

July 4. 2008 14:04

Gravatar