Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does GridView not render the header row as thead after postback?

Setting TableSection = TableRowSection.TableHeader after the grid is bound works initially, putting the header row in thead. After a postback (where the grid is not re-bound) the header row reverts to the table body. I expect the header row to stay in thead; can someone explain why this is not the case or what I am doing wrong?

Sample:

Click the button to cause a postback. The header is not orange after the postback since it's not in thead anymore.

aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="gridtest.aspx.cs" Inherits="ffff.gridtest" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <style type="text/css">
    thead th { background-color:Orange;}
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <div><asp:Button ID="Button1" runat="server" Text="Button" />
    &nbsp;this button is here just to trigger a postback</div>
    <asp:GridView ID="gv1" runat="server"></asp:GridView>
    </form>
</body>
</html>

code

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace ffff
{
    public partial class gridtest : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            gv1.DataBound += new EventHandler(gv1_DataBound);
            if (!IsPostBack) { BindGrid(); }
        }
        void Page_PreRender(object sender, EventArgs e)
        {
            if (gv1.HeaderRow != null)
                System.Diagnostics.Debug.WriteLine(gv1.HeaderRow.TableSection); // still TableHeader after postback
        }
        void gv1_DataBound(object sender, EventArgs e)
        {
            if (gv1.HeaderRow != null)
            {
                gv1.HeaderRow.TableSection = TableRowSection.TableHeader;
            }
        }
        private void BindGrid()
        {
            gv1.DataSource = this.Page.Controls;
            gv1.DataBind();
        }
    }
}
like image 285
lincolnk Avatar asked Jul 08 '11 01:07

lincolnk


3 Answers

Use the Pre_Render_Complete event instead to add the table section. This will ensure the thead section is always added. As you are currently doing it on DataBound the section will only be added when the data is bound.

protected override void OnPreRenderComplete(EventArgs e)
    {
        if (gv1.Rows.Count > 0)
        {
            gv1.HeaderRow.TableSection = TableRowSection.TableHeader;                
        }
    }

Feel free to change the row check I use to checking the Header Row exists as you currently do.

like image 80
Jon P Avatar answered Oct 23 '22 10:10

Jon P


You must set TableSection after DataBind method.

 gv1.DataSource = this.Page.Controls;
 gv1.DataBind();
 gv1.HeaderRow.TableSection = TableRowSection.TableHeader; 
like image 5
Nakajima Shigeru Avatar answered Oct 23 '22 10:10

Nakajima Shigeru


Just put the below code in prerender event of gridview

protected void gv_PreRender(object sender, EventArgs e)
{
    if (gv.Rows.Count > 0)
    {
        gv.UseAccessibleHeader = true;
        gv.HeaderRow.TableSection = TableRowSection.TableHeader;
    }
}
like image 3
Vinay Avatar answered Oct 23 '22 09:10

Vinay