A Better Fixed GridView Header for ASP.NET

CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Introduction

There are several articles on fixed headers. I even wrote one called “Implementing a Fixed GridView Header in ASP.NET.” What I discovered was that the technique described in that article and some others doesn’t work very well when controls are nested or pages become complex. What I was looking for was a more durable solution.

What I started with was a technique that developers have been using for a while: shadowing a grid with a separate table. The challenge with aligning a separate control with a grid is aligning the separate control with the grid and the columns of the grid as it shrinks and grows and the columns change size. In this article, I present a better, improved spin on an old standby. Some interesting JavaScript is used to clone a fix the position of a grid header, handling runtime changes in the associated grid’s appearance.

As you read this article, you will have an opportunity to explore and expand your knowledge of JavaScript and ASP.NET, learn about object-oriented JavaScript, and gain a better understanding of the relationship between ASP.NET Web controls, HTML, and JavaScript.

An Overview of the Solution

Have you ever sat in a presentation listening to a lot of technical details without an idea of where you are going? I have. Many times it would have helped to have a thesis statement, a sort of, overview of what will be learned, why, and how we might get there. Hence this section.

In this article, you will learn a technique that will help you pin a header for a table (specifically the one generated by a ASP.NET GridView) even when the page containing the GridView scrolls. Along the way, you will have an opportunity to learn about object-oriented JavaScript and might glean a better understanding of ASP.NET web controls. If you want your grid headers to stay put, you are in the right place. If you are curious about object-oriented JavaScript, you are in the right place. If you are bored, stuck in an airport, or just curious, welcome.

This better fixed grid header solution has three elements: object-based JavaScript that manages the grid header, a stub separate HTML table for pinning the header, and some sample code that demonstrates a GridView with enough data to need scrolling. Hence, there are three sections to this article: the presentation view and the grid that has enough data to require scrolling, a simple section, the HTML tags that will ultimately represent the pin-able header, another relatively simple section, and the JavaScript that does all of the heavy lifting. The last section has all of the code.

Making a Page with a Scrollable Div and GridView

There are a couple of well-used ways to manage the location of controls. Two popular ways are the HTML Table and HTML Div. In this section, you will use a Div to house the GridView. You could make the Div scrollable or just add enough data to the GridView to make the page scroll. With the totality of the code in this article, either approach will permit the header to scroll correctly. To simplify the creation of the presentation layer, you’ll use a scrolling page and a lot of data in a GridView.

To implement a test presentation—web page—you can create a dummy class, use a generic List, and bind that list to a GridView. Before you write the code in Listing 1, drop a GridView on a web page.

Listing 1: A sample class and code that populates a GridView.

Imports System.Collections.Generic

Partial Class _Default
   Inherits System.Web.UI.Page

   Protected Sub Page_Load(ByVal sender As Object, _
      ByVal e As System.EventArgs) Handles Me.Load

      If (IsPostBack) Then Return

      Dim list As List(Of Sample) = New List(Of Sample)

      Dim I As Integer

      For I = 1 To 100
         list.Add(New Sample(I, "Name" + I.ToString(), I.ToString()))
      Next

      GridView1.DataSource = list
      GridView1.DataBind()

   End Sub
End Class

Public Class Sample

   Private _iD As Integer
   Public Property ID() As Integer
      Get
         Return _iD
      End Get
      Set(ByVal Value As Integer)
         _iD = Value
      End Set
   End Property

   Private _name As String
   Public Property Name() As String
      Get
         Return _name
      End Get
      Set(ByVal Value As String)
         _name = Value
      End Set
   End Property

   Private _filler As String
   Public Property Filler() As String
      Get
         Return _filler
      End Get
      Set(ByVal Value As String)
         _filler = Value
      End Set
   End Property

   ''' <summary>
   ''' Initializes a new instance of the Sample class.
   ''' </summary>
   ''' <param name="iD"></param>
   ''' <param name="name"></param>
   ''' <param name="filler"></param>
   Public Sub New(ByVal iD As Integer, _
      ByVal name As String, ByVal filler As String)
      _iD = iD
      _name = name
      _filler = filler
   End Sub

End Class

You can use anything to populate the GridView; it really isn’t relevant to the discussion. All you should care about is that you have something that generates an HTML table and enough data to make that table need to scroll.

It is worth noting that ASP.NET web controls are HTML generators that spit out HTML on the server. Basically, if it looks like a duck, it is a duck. That is, a GridView is actually rendered as an HTML table, so this technique will work on anything that is ultimately an HTML table.

Adding the HTML Div and Table Stubs

The GridView will have a header. For the technique for pinning it, you could use the GridView’s actual header, but is actually a little easier to use a clone. The reason is that if you pin the GridView’s actual header, you have to adjust its position differently when you have scrolled to the top (or you hide row 1), and you might have to account for a positioned header’s index when manipulating the data. For these reasons, I elected to use a stub div and table to mimic the fixed header.

Tip: Did you know that a table header is rendered as a <TR> with <TH> children instead of <TD> (cells) children? Did you also know that you can place the row containing the header (or <TH> cells) anywhere in a Table? You can.

To add the div and table stub, open your web page and add the following HTML just above the GridView’s tag. Here is the additional HTML followed by complete HTML/ASP for the sample form (in Listing 2).

<div id="fixedHeader" style="position: absolute">
   <table id="header" style="position: absolute">
   </table>
</div>

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read