【问题标题】:Why does GridView not render the header row as thead after postback?为什么 GridView 在回发后不将标题行呈现为thead?
【发布时间】:2011-09-30 22:17:33
【问题描述】:

在绑定网格后设置TableSection = TableRowSection.TableHeader 最初有效,将标题行放在thead 中。回发后(网格未重新绑定),标题行恢复为表格正文。我希望标题行保持领先;有人可以解释为什么不是这种情况或我做错了什么吗?

示例:

单击该按钮可导致回发。回发后标头不是橙色,因为它不再位于 thead 中。

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>

代码

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();
        }
    }
}

【问题讨论】:

标签: asp.net gridview tableheader


【解决方案1】:

改为使用 Pre_Render_Complete 事件来添加表格部分。这将确保始终添加 thead 部分。正如您目前在 DataBound 上所做的那样,只有在绑定数据时才会添加该部分。

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

随意更改我用来检查标题行的行检查,就像您目前所做的那样。

【讨论】:

  • 我使用的是标准的GridView,而不是从它继承,所以我将一个事件处理程序附加到PreRender,这很有效。我不明白为什么-gv1.HeaderRow.TableSection 在此分配之前和之后的值为TableHeader。设置器中是否发生了一些负责正确渲染的事情?
  • 不幸的是,我无法回答您为什么会出现这种情况,只能说它有效。我的 OnPrerenderComplete 覆盖实际上是在页面级别。通常,如果我在一个页面上有多个网格,我会将所有表头部分加载到一个位置。根据您的后续问题,我可能会对此机制进行一些调查/实验
  • 有趣。当单步执行我的页面 OnPreRenderComplete 时,在分配之前将 HeaderRow.TableSection 显示为 TableBody,确保启用了 ViewState。 ViewState 在 PreRenderComplete 事件 (msdn.microsoft.com/en-us/library/ms178472.aspx) 之后保存,所以这不是问题。
  • 我需要在用户控件中使用它,所以我使用了 OnPreRender 事件,它工作正常。
  • 谢谢。它仍然为我抛出了异常,因此我扩展了您的方法以满足我的需求。在这里查看我的答案:stackoverflow.com/a/19846059/555798
【解决方案2】:

必须在 DataBind 方法之后设置 TableSection。

 gv1.DataSource = this.Page.Controls;
 gv1.DataBind();
 gv1.HeaderRow.TableSection = TableRowSection.TableHeader; 

【讨论】:

  • 是的,我正在这样做。问题是为什么网格在回发后呈现默认方式,即使TableSection 仍设置为TableHeader
  • 来自forums.asp.net/t/1004097.aspx?GridView+HeaderRow+null+ - 当您的数据表为空(或者,在这种情况下,this.Page.Controls 为空)时,HeaderRow 为空
【解决方案3】:

只需将下面的代码放在gridview的prerender事件中

protected void gv_PreRender(object sender, EventArgs e)
{
    if (gv.Rows.Count > 0)
    {
        gv.UseAccessibleHeader = true;
        gv.HeaderRow.TableSection = TableRowSection.TableHeader;
    }
}

【讨论】:

    猜你喜欢
    • 2010-09-23
    • 2018-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-04
    • 1970-01-01
    • 2020-08-15
    • 1970-01-01
    相关资源
    最近更新 更多