Click here to Skip to main content

Extended GridView with Fixed Header and Pager


This article is all about creating a custom scrollable gridview control with fixed header and pager. This gridview is an updated version of ASP.NET basic gridview and panel supports a localtable, scrollable region and fixed pager solves the last page flickering issue of basic gridview control.


When you are using basic ASP.NET gridview control in your page with AllowPaging=”True” with PageSize=”12”, then it renders output 12 rows per page. If the total number of records is 77, then total gridview will contain total 7 pages. But the problem comes in the last page, which contains 9 records. As a result when you visit the last page in the gridview then the height of the grid will be lesser than the previous page and the pager row will flicker.



To overcome this issue, I have decided to create a custom gridview control by inheriting the basic ASP.NET GridView class. Users having knowledge of creating an inherited (custom) control can easily use/understand this article. If you are new then visit the link Developing Custom ASP.NET Server Controls [].

Before we start writing the control, we need a deep look into the basic gridview control, why this problem occurs. If you see the rendered HTML of basic gridview control, then you can understand the problems. The gridview renders a table [see HTML output] in the browser.

  • It renders output in a table
  • First row contains the header column
  • Following rows display the actual data
  • And last row displays the pager

So Why the Problem?

Answer: In each page of GridView total number of row is 14 but in the last page the number of row is 11, which causes flicker in the last page.

Then, What is the Solution?

Answer: If we can split the gridview table in three separate tables, the first one is for displaying header, the next to display the data in a scrollable region with fixed height and the last to display the pager, then only we can fix this issue. See below:


  • Header table displays the header columns
  • Data rows are displayed within a fixed-height region “DIV
  • Pager table displays outside the main grid in separate table

Now if you want to display the grid in this manner, then you need to create a custom GridView control which will extend the basic functionality of ASP.NET GridView control.

Steps to Create Custom GridView Control

  1. Create a class named “ExGridView” in your project
  2. Inherit this class from System.Web.UI.WebControls.GridView
  3. Override the default control render method

How the Controls Works

ExGridView is a custom server control which is derived from ASP.NET System.Web.UI.WebControls.GridView class, Which allows all the functionality of GridView.

public class ExGridView : GridView

ExGridView class contains ToolboxData attribute which specifies the default tag generated for this control when it is dragged from a toolbox in a tool such as Microsoft Visual Studio.

ToolboxData("<{0}:ExGridView runat="\""server\"> </{0}:ExGridView>") 

We create actual grid controls in override render() method. This method is called whenever the postback is performed or when the page is first loaded.

ExGridView control contains one custom property:

  • GridHeight: The fixed height of the container to display the grid data rows

ExGridView control contains three portions:

  • Header: Containing gridview header row. It displays in a table in top of the grid with same formatting specified in the page.
  • Data: Containing data rows of the grid view.
  • Pager: Containing pager row. It displays in a table outside the main grid with the same formatting specified in the page.


  • GridHeight: Get the height of the fixed region where the data rows will be displayed. It accepts System.Web.UI.WebControls.Unit value

Header Rendering

To display header row outside the main grid we need to create a table with same CellPadding, CellSpacing and Width attribute values of the main grid.

//render header row 
writer.Write("<table  border='0' cellspacing='" + this.CellSpacing.ToString() + 
"' cellpadding='" + this.CellPadding.ToString() + "' style='width:" + CalculateWidth() 
+ "'>");

Header table width is calculated using a private method called CalculateWidth():

private String CalculateWidth()
     string strWidth = "auto";
     if (!this.Width.IsEmpty)
     strWidth = String.Format("{0}{1}", this.Width.Value, 
    ((this.Width.Type == UnitType.Percentage) ? "%" : "px"));
return strWidth;

Assign the HeaderRow in a variable:

GridViewRow customHeader = this.HeaderRow; 

Render HeaderRow and set the visible property of the default header row to false.

GridViewRow customHeader = this.HeaderRow;
if (this.HeaderRow != null)
if (AutoGenerateColumns == false)
int i = 0;
foreach (DataControlField col in this.Columns)

this.HeaderRow.Visible = false;//make invisible default header  row


Finally close the table tag of header:


Data Rendering

After rendering the header row, the next step is the rendering of actual data rows in a fixed height region. A DIV is used as a container of main grid with fixed height and scrolling support.

//render data rows
writer.Write("<div id='" + ClientID + "_div'  style='" +
"padding-bottom:5px;overflow-x:hidden;overflow-y:scroll;" +
"width:" + CalculateWidth() + ";" +
"height:" + CalculateHeight() + ";" +        "background-color:#FFFFFF;'>");

The overflow-y:scroll CSS property will display a scrollbar in the DIV element in browser. The height and width is calculated using private methods CalculateHeight and CalculateWidth.

Now get the pager row, store it in local variable and make invisible that it doesn't display the PagerRow with main grid table:

//get the pager row and make invisible
GridViewRow customPager = this.BottomPagerRow;
if (this.BottomPagerRow != null)
this.BottomPagerRow.Visible = false;

Finally render the main grid and close the DIV tag.


Pager Rendering

To render the Pager, create another table and render the PagerRow which is stored in local variable.

//render pager row
if (customPager != null && this.PageCount > 0)
writer.Write("<table  border='0' cellspacing='" + this.CellSpacing.ToString() + 
"' cellpadding='" + this.CellPadding.ToString() + "' style='width:" + CalculateWidth()
 + "'>");
customPager.Visible = true;

Using the Code

You can add ExGridView in your pages. The code below shows how to add this control.

Register the Control

<%@ Register Namespace="CustomControls" TagPrefix="ctrl" %>

Add the Control

<ctrl:ExGridView ID="GridView1" runat="server" AllowPaging="True" PageSize="18" 
AutoGenerateColumns="false" CellPadding="4" DataKeyNames="ProductID" 
DataSourceID="SqlDataSource1" ForeColor="#333333"
 GridLines="None" GridHeight="250" 
Width="100%"> <RowStyle BackColor="#FFFBD6" ForeColor="#333333" />
 <asp:BoundField DataField="ProductID" HeaderText="ProductID" ReadOnly="True" 
SortExpression="ProductID" HeaderStyle-Width="10%" ItemStyle-Width="10%" />
 <asp:BoundField DataField="ProductName" HeaderText="ProductName" 
SortExpression="ProductName" HeaderStyle-Width="40%" ItemStyle-Width="40%" />
 <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice" 
SortExpression="UnitPrice"  HeaderStyle-Width="10%" ItemStyle-Width="10%" />
 <asp:BoundField DataField="UnitsInStock" HeaderText="UnitsInStock" 
SortExpression="UnitsInStock" HeaderStyle-Width="10%" ItemStyle-Width="10%" />
 <asp:BoundField DataField="CategoryName" HeaderText="CategoryName" 
SortExpression="CategoryName" HeaderStyle-Width="30%" ItemStyle-Width="30%" />
 <FooterStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
 <PagerStyle BackColor="#FFCC66" ForeColor="#333333" HorizontalAlign="Center" />
 <SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="Navy" />
 <HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
 <AlternatingRowStyle BackColor="White" />
 <asp:SqlDataSource ID="SqlDataSource1" runat="server" 
ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"

 SelectCommand="SELECT [ProductID], [ProductName], [UnitPrice], [UnitsInStock], 
[CategoryName] FROM [Alphabetical list of products]">



  • HeaderStyle-Width and ItemStyle-Width values should be provided in the asp:BoundField

Known Issues

  • Header row doesn't render properly when you set AutoGenerateColumns=”true” of the grid view

Web03 | 2.8.160207.1 | Advertise | Privacy
Copyright © CodeProject, 1999-2016
All Rights Reserved. Terms of Service