Wednesday, September 10, 2008

Add TBody and THead to GridView

If you want to play nice with standard (for many reasons), you will notice that GridView does a fair job. However, it does not use tbody, thead, or tfoot tags for the table that is generated when rendered in the browser.

This technique for this entry was learned from this article. However, I found that it was really correct or functional in all cases. For example, if you click on a column i the GridView to sort or do anything else on the page to cause the GridView to do its databinding again the html is regenerated. Which means that after DataBind() is called (implicitly using ObjectDataSource or SqlDataSource) you need to make the changes again. You could technically do this in the PageLoad event, but you would also have to do it in the other places that cause the data binding to fire again. The easiest way I no to have the code in one place is to do it in the PreRender event of the GridView.

uckily, there is a simple fix

protected void GridView1_PreRender(object sender, EventArgs e)

   // You only need the following 2 lines of code if you are not 
   // using an ObjectDataSource of SqlDataSource

   GridView1.DataSource = Sample.GetData();

if (GridView1.Rows.Count > 0)
      //This replaces <td> with <th> and adds the scope attribute
      GridView1.UseAccessibleHeader = true;

//This will add the <thead> and <tbody> elements
      GridView1.HeaderRow.TableSection = TableRowSection.TableHeader;

//This adds the <tfoot> element. 
      //Remove if you don't have a footer row

      GridView1.FooterRow.TableSection = TableRowSection.TableFooter;


The easiest way to wire up this event is to in the Designer, get properites on the GridView, and then click the Events icon (lightning icon) to get the list of events. Now, double-click the PreRender space. This will create a method calle something like the one above. Copy the above code and you are ready to go.


If you prefer the no GUI way. Just add it to your GridView tag. That would look something like this:

<asp:GridView ID="GridView1" runat="server" 


DarKain said...


Brent V said...


Thanks for the feedback. You're welcome! :)


carlossc said...


Brent V said...


Glad you found it useful. Thank you for the kind feedback.


Ricardo said...

Really good. Thanks for that

Brent V said...


Thank you for your kind feedback.


Axel Grude said...

Cool, have integrated that into my inherited Server COntrol; just a question, how can you manipulate the styling of these injected body tags at runtime (server-side). I have added a property BodyHeightEm which I would like to apply to tbody, for scrolling)


Brent V said...

Hi Alex,

I would look at


Does that help?


Ian said...

Still a very useful post. Perfect for when you need <thead> for javascript, like for the tablesorter plugin.

Pia said...

Very useful and easy fix. Thanks!

Anonymous said...

OMG, it's that simple!

Kåre Johnsen said...

I wrote a test to try tablesorter, same as in

The test worked perfectly.
But in my production system it does not work because I can not get Thead and tbody elements.

Could it be because my GridView specifies HeaderTemplate ???

I tried calling
GridView1.UseAccessibleHeader = true;
GridView1.HeaderRow.TableSection = TableRowSection.TableHeader;

both from Page_Prerender and Page_Load....

Silvio Delgado said...

Great solution! Thanks.

Anonymous said...

C# gridview data exporting

Pranav Singh said...

Really Nice article very helpfull