Freeze GridView Columns and Headers in ASP.Net CSS


This article is written by Pon Saravanan  on 16-Aug-09 Last modified on :14-Jun-10





Freeze ASP.Net GridView Columns and Header with CSS

When working in large spreadsheet in excel I used to freeze the columns(including First Column) and rows. This is very useful when you want to compare the values in one column with other column values. And regarding header I always freeze it otherwise it is very hard to find what the values are referring to.

Like spreadsheet the GridView as well displaying the data in the tabular format. But unfortunately there is no support for this freezing functionality. What i dislike is, there is no built in support for GridView scrolling. we need to write our own CSS to control this.

So I started looking for an alternative while I found some and I wanted to derive a custom container control which can hold a GridView inside and you can specify the columns to freeze. But the development is on going. I may not be able to complete.  So I would like to share how this can be achieved with Styles and CSS with the help of ASP.net

Important Note: Document Type will impact freezing

Document type will be playing a major role in this freezing portion as changing this to strict will lead to undesirable effects. So keep it Transactional always

Enable Scrolling before Freezing including First Column

As I said earlier there is no built in support for scrolling. So to enable scrolling we need to do few things.
1) Add a container (in our case it is a div) to the GridView. This is the one which is going to give scrolling to the GridView
2) To enable scrolling in this div. Add a style attribute “overflow”

Freeze GridView Header

To freeze header, add a style “position: relative;” to header row. After this the entire header row will be frozen will not move when scrolling vertically up and down. While scrolling horizontally (e.g. left to right), The column header have to move horizontally

If you just need only to freeze header, then please refer this article here Fixed Header GridView

To achieve this we need to change the left of the column, while scrolling this will do the trick nicely.

left: expression(document.getElementById("GridViewContainer").scrollLeft-2);

Freezing Columns

To freeze columns the style “position: relative;” has to be added to the column and its header. This is to specify the columns to stay in its place while scrolling. But when scrolling vertically (e.g. up and down) this column will not traverse vertically as the other columns move.

To achieve this we need to change the top of the column, while scrolling this will do the trick nicely.

top: expression(document.getElementById("GridViewContainer").scrollTop-2);


Screen Shots

 
Before scrollingAfter Scrolling

SourceCode

Markup (*.Aspx)

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
   
    <style type="text/css">
        /* A scrolable div */
        .GridViewContainer
        {          
            overflow: auto;
        }
        /* to freeze column cells and its respecitve header*/
        .FrozenCell
        {
            background-color:Gray;
            position: relative;
            cursor: default;
            left: expression(document.getElementById("GridViewContainer").scrollLeft-2);
        }
        /* for freezing column header*/
        .FrozenHeader
        {
         background-color:Gray;
            position: relative;
            cursor: default;           
            top: expression(document.getElementById("GridViewContainer").scrollTop-2);
            z-index: 10;
        }
        /*for the locked columns header to stay on top*/
        .FrozenHeader.locked
        {
            z-index: 99;
        }
       
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <div id="GridViewContainer" class="GridViewContainer" style="width:400px;height:600px;" >
        <asp:GridView ID="GridView1" CssClass="GridView" runat="server" BorderWidth="0px"  AutoGenerateColumns="false" >
            <HeaderStyle CssClass="FrozenHeader" />
            <Columns>
                <asp:BoundField DataField="CustomerID" HeaderText="Customer"
                    ItemStyle-CssClass="FrozenCell" HeaderStyle-CssClass="FrozenCell" />
                <asp:BoundField DataField="ShipName" HeaderText="ShipName" />
                <asp:BoundField DataField="ShipAddress" HeaderText="ShipAddress" />
                <asp:BoundField DataField="ShipCity" HeaderText="ShipCity" />
                <asp:BoundField DataField="ShipCountry" HeaderText="ShipCountry" />
            </Columns>
        </asp:GridView>
    </div>
    </form>
</body>
</html>

Code Behind (*.Vb)

Imports System.Data
Imports System.Data.SqlClient
Partial Class _Default
    Inherits System.Web.UI.Page
    Private ReadOnly Property ConnectionString() As String
        Get
            Return "Server=.\SQLEXPRESS;Database=NorthWind;Trusted_Connection=True"
        End Get
    End Property
    Private ReadOnly Property Connection() As SqlConnection
        Get
            Dim ConnectionToFetch As New SqlConnection(ConnectionString)
            ConnectionToFetch.Open()
            Return ConnectionToFetch
        End Get
    End Property
    Public Function GetSourceData() As DataTable
        Dim SelectQry = "select top 100 * from Orders "
        Dim SourceSource As New DataSet
        Try
            Dim SourceDataAdapter As New SqlDataAdapter(SelectQry, ConnectionString)
            SourceDataAdapter.Fill(SourceSource)
        Catch ex As Exception
            Throw ex
        End Try
        Return SourceSource.Tables(0)
    End Function
    Protected Sub _Default_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If (Not IsPostBack) Then
            LoadGrid()
        End If
    End Sub
    Private Sub LoadGrid()
        GridView1.DataSource = GetSourceData()
        GridView1.DataBind()
    End Sub
End Class










Comments
  • GUEST
    nice presentaion.` 10/8/2009 4:06:11 AM

  • GUEST
    Not working in mozilla gve me the solution 10/21/2009 6:54:48 AM

  • pons
    This will work only In Internet Explorer. 10/21/2009 11:58:24 PM

  • GUEST
    Excellent! very helpfull! thanks. 10/27/2009 6:30:09 AM

  • GUEST
    Hi,
    I 've tried your code and it is working fine for freezing columns. But the frozen column's header does not freeze. When I scroll right, the header also moves making it out of sight. How do I freeze the header both horizontally and vertically? Any help is appreciated.
    Thanks!
    1/13/2010 10:58:07 AM

  • pons
    have you changed the Document type to transactional.I spent almost seaveral hours to figured it out.
    1/13/2010 7:07:10 PM

  • GUEST
    Where/how can I set the Document Type? 1/18/2010 6:51:20 AM

  • GUEST
    Please refer to the second line in markup section 1/18/2010 7:44:50 AM

  • GUEST
    ****!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"****
    This is what my html source has too. What else could be the issues with headers text not freezing?
    1/18/2010 9:10:09 AM

  • GUEST
    OKAY. It worked finally. I was setting the left based on the offsetParent and not the div element. Changing it to document.getElementById(div-gridview) made it work. Of course it is very slow. I will have to research a replacement now. Anyway thanks bunch for the code and the help. 1/18/2010 9:23:04 AM

  • GUEST
    I had to do the following to get this to work ...

    Change
    left: expression(document.getElementById("GridViewContainer").scrollLeft-2);
    To
    left: expression(parentNode.parentNode.parentNode.parentNode.scrollLeft);

    And Change

    top: expression(document.getElementById("GridViewContainer").scrollTop-2);
    To
    top: expression(parentNode.parentNode.parentNode.parentNode.scrollTop);
    1/25/2010 2:18:23 PM

  • pons
    Hi
    Thank you for your updates on that.

    There are lot of ways to access an element in Javascript, What you have described is one of the way.
    1/25/2010 6:41:46 PM

  • GUEST
    This solution works perfect for me but I still do have a problem. I have a requirement that, in one of the freezed columns, I have a link column and in the click of it I should show a bubble of text. Now because of this freeze, my bubble is displayed at the back and I have no idea how to get it to the front keeping the column freezed. I tried using z-index but this doesn't seem to work. Any help would be appreciated. 5/19/2010 1:16:00 AM

  • pons
    Hi

    add a div with style attribute style="position:absolute;top:200px;left:50px;background-color:Red;width:1000px"

    I used the above to display a text over the frozen column. It actually displays on top of the frozen column.

    For further analysis
    -------------------
    You please try to use my source code(in the article) exactly with this div(in this comment ) just above the gridview container div. And proceed adding your additional functionalities from there by adding some of your scripts and css one by one. Stop while it is breaking and let me know what caused it is to break.

    I will look into that from there for further analysis
    5/19/2010 4:02:43 AM

  • GUEST
    Hi,

    Great Article, Header text is not freezed, I tried left: expression(parentNode.parentNode.parentNode.parentNode.scrollLeft); what are the parentNodes here? How can I freez the header? Please help me.
    6/7/2010 5:29:18 PM

  • pons
    ok, for freezing only header you please refer to the 'fixed header gridview' under gridview section.

    It is possible that you might not reach the contorl using parentNode hierarchy, however as pointed in the previous comments you can use the document.getElementById in the expression.

    Hope this helps you
    6/7/2010 6:43:18 PM

  • GUEST
    Thanks for the reply, My situation is same like "I 've tried your code and it is working fine for freezing columns. But the frozen column's header does not freeze. When I scroll right, the header also moves making it out of sight. How do I freeze the header both horizontally and vertically? "

    I am using the same code as in the source code section
    6/7/2010 6:55:48 PM

  • pons
    Hi

    I understand your situation, so now i have gone back to my sample and tried in my workstation. The source code is working exactly as expected. It seems there could be some environmental issue if the source code is exactly the same.

    I am attaching an image to illustrate what can be expected from the source code
    6/7/2010 7:34:41 PM

  • GUEST
    Can you tell me how to make this style work in a databound event? I dont have bound columns and I am having a hard time figuring this out. 7/19/2010 3:42:30 PM

  • pons
    You may access the css class attribute of the header in GridView1_databound event.

    You may access the CSS Class attribute of the ITEMS in GridView1_rowDataBound.
    7/19/2010 7:03:04 PM

  • GUEST
    How do I get to the columns in the rowDataBound event? 7/20/2010 8:31:26 AM

  • GUEST
    Its very nice article
    Its working IE not firefox
    could plz look into this also

    Thanx
    Laxmi kanth
    7/28/2010 5:21:08 AM

  • GUEST
    I use asp.net 4.0 then I tested it already, it doesn't frozen header and column all web browser (IE, Firefox,...) why?
    what should i do?, please anyone suggest me.
    Thank you.
    9/1/2010 9:31:39 PM

  • pons
    Mostly it will happen if the wrong document type has been chosen. Please read through the comments for different kind of problems and solution given. if you are still unable to resolve please let me know. 9/2/2010 12:38:51 AM

  • GUEST
    hi i am new to this
    can you help how to use this expression statement
    thanks in advance
    9/13/2010 6:24:35 AM

  • pons
    You may try to use the expresion as you do the other items in the Css Classes
    For example
    .FrozenCell
    {
    background-color:Gray;
    position: relative;
    cursor: default;
    left: expression(document.getElementById("GridViewContainer").scrollLeft-2);
    }


    If you are new to the asp.net try to use the code as it is. Then you try to modify the code as you wish
    9/13/2010 6:32:02 AM

  • GUEST
    thanks for the reply.
    I pasted the above code in my css file
    it is showing error at the "expression......" with red unerlines

    can you give some other example how to use "expression" statements
    expecting your valuable reply

    9/16/2010 1:41:07 AM

  • pons
    Ok it seems that your visualstudio settings are considering css validataions as errors change them to warnings, you will be able to solve it. tools \ options \Text Editor\Html\validations

    uncheck appropriate(html warnings )

    Hope that helps
    9/16/2010 4:31:02 AM

  • GUEST
    Hi Friends,

    I tried this solution the header and the columns are getting freezed but the freezed columns are visible outside the div tag.. can u help me with this issue....

    Thanks in advance
    9/20/2010 7:40:47 AM

  • pons
    Can you try to use the sample as it is and try to find out by changing them to suit your needs.
    The possible problems are
    1)DocType mis match
    2) The positioning defined in the CSS
    9/20/2010 6:47:38 PM

  • GUEST
    Thanks pons for such a nice article. As some of the other guests said, I too, facing the same problem of Frozen column's header cell is not working.

    How to use your .LOCKED Css style ? Do i need to place this for Header ?
    10/3/2010 10:59:15 AM

  • pons
    Use the FrozenCell css class as the reference. If you just want to freeze the header then have a look at Fixed Header Gridview article. 10/4/2010 7:15:41 AM

  • GUEST
    its good 12/20/2010 3:07:35 AM

  • GUEST
    In my case, the header and the first column both outflow the div. Can u plz suggest me a solution. 3/8/2011 6:16:28 AM

  • pons
    Have you tried the sample as it is? Still having issues in freezing column 3/8/2011 6:33:37 AM

  • GUEST
    Yes, after trying ur code, i still have problems. Can u plz give me ur email id. i will send u the screen shot of how the overflow happens. 3/8/2011 7:40:26 AM

  • GUEST
    I copied the exact codes but the first column and headers are not frozen.

    Please help.

    Enan
    5/17/2011 1:22:04 PM

  • GUEST
    i have copied exact code, headers are freezing but not the column.Please help.
    kunalchaniyal01@gmail.com
    5/27/2011 5:03:51 AM

  • GUEST
    hi. im havin prob wit freezin the column. the header freezin works fine. thanks... 7/4/2011 9:09:10 PM

  • GUEST
    Hi, i have tried this code in VS2008 but the header and column is not freezing and it is showing error at the "expression...... not a valid expression for left" with red underlines. i am using IE7+ browser please help...
    8/26/2011 2:01:20 AM

  • GUEST
    Hi, i have tried this code in VS2008 but the header and column is not freezing and it is showing error at the "expression...... not a valid expression for left" with red underlines. i am using IE7+ browser please help...

    i have tried with below expression

    top: expression(parentNode.parentNode.parentNode.parentNode.scrollTop);

    but not working
    8/26/2011 2:02:31 AM

  • GUEST
    Can i use DIV here for scrolling - I have 30 columns.. and I want to have scroll until 6 columns.. 9/6/2011 3:32:12 AM

  • GUEST
    how can i work it for mozilla...... can u help me for that it is urgent.....

    9/9/2011 11:53:25 PM

  • GUEST
    I have:

    1. asp.net 4.0
    2. Mozilla 4.0
    3. IE 8

    Nothing worked from above:
    Where to change. So confused...???

    expression(....) green error coming after doing - tools \ options \Text Editor\Html\validations
    uncheck appropriate(html warnings )

    --Himalaya Garg

    10/23/2011 11:56:40 PM

  • GUEST
    header freezes but header width does not match with column width... how to set that issue 11/5/2011 1:57:41 AM

  • GUEST
    nice article

    But the notfreezed columns header is having no border??
    2/10/2012 7:06:36 AM

  • GUEST
    i have taken same as show in this topic. but unable to freeze neither header not column.
    3/5/2012 3:23:21 AM

  • GUEST
    Will it work for a hierarchical grid view? 4/13/2012 12:17:34 AM

  • GUEST
    I can freeze. But the output is not what you show us. The freeze column values are overlap.

    I used IE 8 and document type below
    DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"

    I cannot use below document. When I used your document type, cannot freeze at all.
    DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"

    Example.
    DataGrid has Scrollbars. Buy No. column values are not scrollable when I 'm scrolling. But other columns are scrolling what you show.

    No. Product Price
    1 A 10
    2 B 11
    3 C 13
    4 D 15
    5 E 13
    6
    7
    8
    9
    5/10/2012 3:17:44 AM

  • GUEST
    Please help me out to fix the column freeze in grid view. I have made it executable but the result im getting is nt properly sorted.
    Like
    1.Freezed column overlaps with other columns.
    2.freezed column dosent contain grid lines.
    3.if i make position:relative nothing freezes .

    my codes r same as above mentioned.

    thank u
    6/7/2013 2:10:08 PM

  • GUEST
    thank you very much 11/11/2013 4:54:26 AM

  • GUEST
    If there is an another div to avoid the scrolling of other contents(eg above heading and search input area), then the freezing overflows over the page. 2/6/2014 9:20:12 AM

  • GUEST
    nobody is telling the solution to work in firefox and chrome browsers 6/4/2014 10:25:30 AM


Comments
   
Captcha Image
For you specially:  
Captcha Text Enter the text in the image.(Not Case sensitive)    



Spam Bot Trap



   



Select Theme
White
Blue
Brown
Gray