Make the ASP.NET GridView Generate THead and TBody tags

The ASP.NET GridView does not generate the <thead> and <tbody> by default. In order to generate the header in an accessible format and generate the thead and tbody tags, use the following code:


protected void Page_Load(object sender, EventArgs e)


    // adds scope attribute

    GridView1.UseAccessibleHeader = true;


    //adds <thead> and <tbody> elements

    GridView1.HeaderRow.TableSection = 


    GridView1.HeaderRow.CssClass = "someclass";



    Protected Sub Page_Load(ByVal sender As Object, _

                            ByVal e As EventArgs)

        ' adds scope attribute

        GridView1.UseAccessibleHeader = True


        'adds <thead> and <tbody> elements

        GridView1.HeaderRow.TableSection = _


        GridView1.HeaderRow.CssClass = "someclass"

    End Sub

About The Author

Suprotim Agarwal
Suprotim Agarwal, Developer Technologies MVP (Microsoft Most Valuable Professional) is the founder and contributor for DevCurry, DotNetCurry and SQLServerCurry. He is the Chief Editor of a Developer Magazine called DNC Magazine. He has also authored two Books - 51 Recipes using jQuery with ASP.NET Controls. and The Absolutely Awesome jQuery CookBook.

Follow him on twitter @suprotimagarwal.


Arnold said...

it's not working in ie 7.
To fix it you need to add your code in Pre_Render:

protected void GridView1_PreRender(object sender, EventArgs e)

GridView1.UseAccessibleHeader = false;
GridView1.HeaderRow.TableSection = TableRowSection.TableHeader;

Anonymous said...

I got it working in IE7 and firefox also with the tip, but prerender is good place to write this.


Suprotim Agarwal said...

Arnold: I agree to both of you that adding the code in Pre_Render() event does good.

However this code works absolutely fine in IE7 even if it is in the Page_Load(). I checked it again to confirm the same!

After running the code in IE7, here is the markup that got generated with the thead and tbody tags

<table cellspacing="0" rules="all" border="1" id="GridView1" style="border-collapse:collapse;">
<th scope="col"><a href="javascript:__doPostBack('GridView1','Sort$CustomerID')">CustomerID</a></th><th scope="col"><a href="javascript:__doPostBack('GridView1','Sort$CompanyName')">CompanyName</a></th><th scope="col"><a href="javascript:__doPostBack('GridView1','Sort$ContactName')">ContactName</a></th><th scope="col"><a href="javascript:__doPostBack('GridView1','Sort$Address')">Address</a></th><th scope="col"><a href="javascript:__doPostBack('GridView1','Sort$City')">City</a></th>
<td>ALFKI</td><td>Alfreds Futterkiste</td><td>Maria Anders</td><td>Obere Str. 57</td><td>Berlin</td>

Travis said...

Putting it just in the Page_Load event is not enough. Sometimes the GridView is not populated at that time. Adding it to the PreRender event will take care of this case.

Also, if you allow sorting of the GridView, the thead and tbody tags will no longer be present upon postback. Again, adding the logic to the PreRender event will take care of it.

If you put it in Page_Load, it will work for the most part, but you'll have trouble when sorting or data binding the GridView after Page_Load. If you put it in PreRender, it will work without issue.

Travis said...

To be explicit, you should put the logic in the GridView_PreRender event.