Wednesday, October 19, 2011
Freeze ASP.Net GridView Columns and Header with CSS When working in large s
When working in large spreadsheet in excel I used tofreeze 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 forGridView 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 alwaysEnable 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”
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.
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 scrolling | After 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>
<!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
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