From an MSDN article on the subject, we can see that we create a TableHeaderRow
that contains TableHeaderCell
s.
But they add the table header like this:
myTable.Row.AddAt(0, headerRow);
which outputs the HTML:
<table id="Table1" ... >
<tr>
<th scope="column" abbr="Col 1 Head">Column 1 Header</th>
<th scope="column" abbr="Col 2 Head">Column 2 Header</th>
<th scope="column" abbr="Col 3 Head">Column 3 Header</th>
</tr>
<tr>
<td>(0,0)</td>
<td>(0,1)</td>
<td>(0,2)</td>
</tr>
...
and it should have <thead>
and <tbody>
(so it works seamless with tablesorter) :)
<table id="Table1" ... >
<thead>
<tr>
<th scope="column" abbr="Col 1 Head">Column 1 Header</th>
<th scope="column" abbr="Col 2 Head">Column 2 Header</th>
<th scope="column" abbr="Col 3 Head">Column 3 Header</th>
</tr>
</thead>
<tbody>
<tr>
<td>(0,0)</td>
<td>(0,1)</td>
<td>(0,2)</td>
</tr>
...
</tbody>
the HTML aspx code is
<asp:Table ID="Table1" runat="server" />
How can I output the correct syntax?
Just as information, the GridView
control has this built in as we just need to set the Accesbility and use the HeaderRow
gv.UseAccessibleHeader = true;
gv.HeaderRow.TableSection = TableRowSection.TableHeader;
gv.HeaderRow.CssClass = "myclass";
but the question is for the Table
control.
Just found a way to do this, we do need to use our own controls that inherit from the base control, for example a Table
public class myTable : System.Web.UI.WebControls.Table
{
protected override void OnPreRender(EventArgs e)
{
Table table = Controls[0] as Table;
if (table != null && table.Rows.Count > 0)
{
// first row is the Table Header <thead>
table.Rows[0].TableSection = TableRowSection.TableHeader;
// last row is the Footer Header <tfoot> (comment for not using this)
table.Rows[table.Rows.Count - 1].TableSection = TableRowSection.TableFooter;
FieldInfo field = typeof(WebControl).GetField("tagKey", BindingFlags.Instance | BindingFlags.NonPublic);
foreach (TableCell cell in table.Rows[0].Cells)
field.SetValue(cell, HtmlTextWriterTag.Th);
}
base.OnPreRender(e);
}
}
works fine with DataGrid
as well
public class myDataGrid : System.Web.UI.WebControls.DataGrid
{
protected override void OnPreRender(EventArgs e)
{
Table table = Controls[0] as Table;
if (table != null && table.Rows.Count > 0)
{
// first row is the Table Header <thead>
table.Rows[0].TableSection = TableRowSection.TableHeader;
// last row is the Footer Header <tfoot> (comment for not using this)
table.Rows[table.Rows.Count - 1].TableSection = TableRowSection.TableFooter;
FieldInfo field = typeof(WebControl).GetField("tagKey", BindingFlags.Instance | BindingFlags.NonPublic);
foreach (TableCell cell in table.Rows[0].Cells)
field.SetValue(cell, HtmlTextWriterTag.Th);
}
base.OnPreRender(e);
}
}
then for example you just need to use it instead the base control:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
myGridView dg = new myGridView();
dg.DataSource = new string[] { "1", "2", "3", "4", "5", "6" };
dg.DataBind();
ph.Controls.Add(dg);
}
}
and in aspx page, just add a place holder like:
<asp:PlaceHolder ID="ph" runat="server" />