Render Gridview Header as Thead and Footer as tfoot

ASP.NET GridView control is one of the data binding control most often used .But it has one problem that when rendering on browser it generate all rows including header and footer in <tbody >section rather than creating separate <thead> and <tfoot>.This is how GridView is rendered as html.Note that even header is generated as row in tbody section.

  1. <table id="MainContent_grdNormal" >  
  2.     <tbody>  
  3.         <tr class="header content-wrapper" >  
  4.             <th scope="col">EmpId</th>  
  5.             <th scope="col">EmpName</th>  
  6.             <th scope="col">City</th>  
  7.         </tr>  
  8.         <tr>  
  9.             <td>L1Z 5F4</td>  
  10.             <td>Nathaniel</td>  
  11.             <td>Ilbono</td>  
  12.         </tr>  
  13.         <tr >  
  14.             <td>B7F 4U4</td>  
  15.             <td>Ross</td>  
  16.             <td>Dover</td>  
  17.         </tr>  
  18.         <tr>  
  19.             <td>R9C 1T9</td>  
  20.             <td>Patrick</td>  
  21.             <td>Edam</td>  
  22.         </tr>  
  23.     </tbody>  
  24. </table>  
Now to force a Gridview to render <thead> and <tfoot>,we need to add 3 lines of code after grid is binded. Below is the code to achieve the same.
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5. using System.Web.UI;  
  6. using System.Web.UI.WebControls;  
  7. using System.Data;  
  8. using System.Data.SqlClient;  
  9. namespace GridHeaders {  
  10.     public partial class _Default: Page {  
  11.         protected void Page_Load(object sender, EventArgs e) {  
  12.             if (!IsPostBack) {  
  13.                 gridbind();  
  14.                 AddHeaders();  
  15.             }  
  16.         }  
  17.         protected void AddHeaders() {  
  18.             if (grdNormal.Rows.Count > 0) {  
  19.                 //This replaces <td> with <th>    
  20.                 grdNormal.UseAccessibleHeader = true;  
  21.                 //This will add the <thead> and <tbody> elements    
  22.                 grdNormal.HeaderRow.TableSection = TableRowSection.TableHeader;  
  23.                 //This adds the <tfoot> element. Remove if you don't have a footer row    
  24.                 grdNormal.FooterRow.TableSection = TableRowSection.TableFooter;  
  25.             }  
  26.         }  
  27.         protected void gridbind() {  
  28.             DataTable dt = new DataTable();  
  29.             dt.Columns.Add("EmpId"typeof(string));  
  30.             dt.Columns.Add("EmpName"typeof(string));  
  31.             dt.Columns.Add("City"typeof(string));  
  32.             DataRow dr1 = dt.NewRow();  
  33.             dr1[0] = "L1Z 5F4";  
  34.             dr1[1] = "Nathaniel";  
  35.             dr1[2] = "Ilbono";  
  36.             dt.Rows.Add(dr1);  
  37.             DataRow dr2 = dt.NewRow();  
  38.             dr2[0] = "B7F 4U4";  
  39.             dr2[1] = "Ross";  
  40.             dr2[2] = "Dover";  
  41.             dt.Rows.Add(dr2);  
  42.             DataRow dr3 = dt.NewRow();  
  43.             dr3[0] = "R9C 1T9";  
  44.             dr3[1] = "Patrick";  
  45.             dr3[2] = "Edam";  
  46.             dt.Rows.Add(dr3);  
  47.             grdNormal.DataSource = dt;  
  48.             grdNormal.DataBind();  
  49.         }  
  50.     }  
  51. }  
Note: Call AddHeaders() method after binding Gridview otherwise you will get table must contain row sections in order of header, body, then footer error.