Stories about Software


Adding a Second Header to an ASP.NET Gridview

Last week, I had some specs to create a grid view in ASP that had normal column headers, as one might expect, and then also “super” column headers, where the columns were categorized. So, if, for instance, you had columns for “Dog”, “Cat”, and “Bird”, those three headers might have a “super-header” called “Pet”, in what basically amounts to a two-tiered categorization hierarchy.

Visually, what I wanted to do was create a second header row on top of the one populated from my data source, but there didn’t seem to be any good way to make this happen through the properties of the GridView. It also seemed like a mess to try to do this through CSS and somehow matching client side HTML styling with a service-side generated table. So, to combat this, I got ahold of the grid view’s table and manually added a row to it:

protected void GridView_DataBound(object sender, EventArgs e)
    var myGridView = (GridView)sender;
    if (myGridView.Controls.Count > 0)

private static void AddSuperHeader(GridView gridView)
    var myTable = (Table)gridView.Controls[0];
    var myNewRow = new GridViewRow(0, -1, DataControlRowType.Header, DataControlRowState.Normal);
    myNewRow.Cells.Add(MakeCell("PETS", 3));
    myNewRow.Cells.Add(MakeCell("ZOO ANIMALS", 3));
    myNewRow.Cells.Add(MakeCell("VARMINTS", 3));
    myNewRow.Cells.Add(MakeCell("GAME ANIMALS", 3));
    myTable.Rows.AddAt(0, myNewRow);

private static TableHeaderCell MakeCell(string text = null, int span = 1)
    return new TableHeaderCell() { ColumnSpan = span, Text = text ?? string.Empty, CssClass = "table-header" };

What’s going on here is that when the grid is data bound, I check to see if data exists and, if so, I add my “super header”. This consists of grabbing the grid view’s first control, which is a table. This is kind of hackalicious in that a change to the ordering of the grid view’s controls collection is a breaking change, but c’est la vie. Once we’ve got ahold of that table, it becomes relatively straightforward to create a row for it using code and to assign it a class to allow further styling in CSS.

So, quick tip for today, and my first ASP.NET oriented one, as I learn the ins and outs of webforms and hopefully later ASP.NET MVC.


Edit: A reader named Patrick Hayden found this useful in his travels, but he was working in Visual Basic.  So for anyone interested in doing this in VB, here is his code:

Protected Sub GridViewBegroting_DataBound(ByVal sender As Object, ByVal e As EventArgs) Handles GridViewBegroting.DataBound
  Dim myGridView As GridView = sender
  If myGridView.Controls.Count > 0 Then
  End If
End Sub

Protected Sub AddSuperHeader(ByVal gridView As GridView)
  Dim myTable As Table = gridView.Controls(0)
  Dim myNewRow As GridViewRow = New GridViewRow(0, -1, DataControlRowType.Header, DataControlRowState.Normal)
  myNewRow.Cells.Add(MakeCell("PETS", 3))
  myNewRow.Cells.Add(MakeCell("ZOO ANIMALS", 3))
  myNewRow.Cells.Add(MakeCell("VARMINTS", 3))
  myNewRow.Cells.Add(MakeCell("GAME ANIMALS", 3))
  myTable.Rows.AddAt(0, myNewRow)
End Sub

Protected Function MakeCell(Optional ByVal text As String = "", Optional ByVal span As Int32 = 1) As TableHeaderCell
' { ColumnSpan = span, Text = text ?? string.Empty, CssClass = "table-header" }
  Dim header As New TableHeaderCell()
  header.ColumnSpan = span
  header.Text = text
  header.CssClass = "table-header"
  Return (header)
End Function


Newest Most Voted
Inline Feedbacks
View all comments
11 years ago

I have ajaxtoolkit modalPopupExtender when i show popup the header row is converted into normal row with empty values what should i do

Erik Dietrich
11 years ago
Reply to  skhurams

I haven’t been doing a lot of webforms lately, so I’m a little rusty. If you throw up a gist of your code though, I can try to offer a suggestion…

ling maaki
ling maaki
10 years ago