You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GridView使用HeaderTemplate时首列(idemp)空白问题排查

解决GridView首列空白(使用HeaderTemplate后员工ID列不显示)的问题

问题描述

我尝试从MySQL数据库获取员工数据并在GridView中展示,使用HeaderTemplate自定义表头,但发现员工ID对应的第一列始终空白。以下是我的代码:

ASPX页面代码

<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server" Width="99%" GridLines="Both" OnRowDataBound="GridView1_RowDataBound" AutoGenerateColumns="false">
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<tr>
<th style="padding: 2.5px; width: 10%;" >eid</th>
<th style="padding: 2.5px; width: 55%;" >First Name</th>
<th style="padding: 2.5px;" >Last Name</th>
</HeaderTemplate>
</asp:TemplateField>
<asp:BoundField DataField="idemp" />
<asp:BoundField DataField="fname" />
<asp:BoundField DataField="lname" />
<asp:TemplateField>
<ItemTemplate>
<asp:GridView ID="GridView2" runat="server" Width="99%" GridLines="Both" AutoGenerateColumns="false" CssClass="ChildGrid">
</asp:GridView>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
</form>

后台C#代码

namespace WebApplication2
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// Populate the GridView.
bindGridview();
}
}
public void bindGridview()
{
DataTable dt = new DataTable();
string constr = @"server=127.0.0.1;user id=root;pwd=n0711p2010p;database=emp";
using (MySqlConnection con = new MySqlConnection(constr))
{
MySqlCommand cmd = new MySqlCommand("select idemp,fname,lname from emp", con);
con.Open();
MySqlDataReader dtreader = cmd.ExecuteReader();
dt.Load(dtreader);
if (dt.Rows.Count >0)
{
GridView1.DataSource = dt;
GridView1.DataBind();
con.Close();
}
}
}
//RowDataBound Event
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
//Checking the RowType of the Row
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataTable dt = new DataTable();
string constr = @"server=127.0.0.1;user id=root;pwd=n0711p2010p;database=emp";
using (MySqlConnection con = new MySqlConnection(constr))
{
con.Open();
GridView child_gridview = (GridView)e.Row.FindControl("GridView2");
String CountryId = (e.Row.RowIndex+1).ToString();
MySqlCommand cmd = new MySqlCommand("select salary,post from emp where idemp="+CountryId, con);
MySqlDataReader dtreader = cmd.ExecuteReader();
dt.Load(dtreader);
if (dt.Rows.Count > 0)
{
child_gridview.DataSource = dt;
child_gridview.DataBind();
}
}
}
}
}
}

当前输出中GridView首列空白,希望解决该问题并实现预期展示效果。


问题原因分析

  1. 表头与数据列结构错位:你把整个表头行(<tr>+三个<th>)放在了一个单独的TemplateField中,这个字段没有对应的ItemTemplate,导致数据行的第一列无内容显示,呈现空白。后续的BoundField数据列会排在这个空白列之后,造成表头和数据的错位。
  2. 子GridView未定义列:子GridView2设置了AutoGenerateColumns="false"但未配置任何列,即使绑定数据也无法渲染内容。
  3. 子表数据查询逻辑错误:用e.Row.RowIndex+1作为idemp的值查询子表数据不可靠——行索引不一定等于数据库中idemp的实际值,应该从当前数据行的绑定数据中直接获取。

解决方案

1. 修正ASPX页面的GridView结构

删除单独包裹表头的TemplateField,改为给每个BoundField设置自定义表头样式,同时为子GridView2添加列定义:

<head runat="server">
    <title>Employee Details</title>
    <style>
        .ChildGrid { margin: 10px 0; }
    </style>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:GridView ID="GridView1" runat="server" Width="99%" GridLines="Both" 
                OnRowDataBound="GridView1_RowDataBound" AutoGenerateColumns="false">
                <Columns>
                    <!-- 员工ID列:绑定数据并设置表头样式 -->
                    <asp:BoundField DataField="idemp" HeaderText="eid" 
                        ItemStyle-Width="10%" ItemStyle-Padding="2.5px"
                        HeaderStyle-Padding="2.5px" HeaderStyle-Width="10%" />
                    <!-- 名字列 -->
                    <asp:BoundField DataField="fname" HeaderText="First Name" 
                        ItemStyle-Width="55%" ItemStyle-Padding="2.5px"
                        HeaderStyle-Padding="2.5px" HeaderStyle-Width="55%" />
                    <!-- 姓氏列 -->
                    <asp:BoundField DataField="lname" HeaderText="Last Name" 
                        ItemStyle-Padding="2.5px" HeaderStyle-Padding="2.5px" />
                    <!-- 子GridView列 -->
                    <asp:TemplateField HeaderText="Salary & Post">
                        <ItemTemplate>
                            <asp:GridView ID="GridView2" runat="server" Width="99%" GridLines="Both" AutoGenerateColumns="false" CssClass="ChildGrid">
                                <Columns>
                                    <asp:BoundField DataField="salary" HeaderText="Salary" />
                                    <asp:BoundField DataField="post" HeaderText="Post" />
                                </Columns>
                            </asp:GridView>
                        </ItemTemplate>
                    </asp:TemplateField>
                </Columns>
            </asp:GridView>
        </div>
    </form>
</body>

2. 修正后台代码的子GridView数据获取逻辑

从当前数据行的绑定数据中获取idemp值,并使用参数化查询避免SQL注入:

namespace WebApplication2
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                bindGridview();
            }
        }

        public void bindGridview()
        {
            DataTable dt = new DataTable();
            string constr = @"server=127.0.0.1;user id=root;pwd=n0711p2010p;database=emp";
            using (MySqlConnection con = new MySqlConnection(constr))
            {
                MySqlCommand cmd = new MySqlCommand("SELECT idemp, fname, lname FROM emp", con);
                con.Open();
                using (MySqlDataReader dtreader = cmd.ExecuteReader())
                {
                    dt.Load(dtreader);
                }
                if (dt.Rows.Count > 0)
                {
                    GridView1.DataSource = dt;
                    GridView1.DataBind();
                }
            }
        }

        protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                // 从当前数据行获取真实的idemp值
                DataRowView rowView = (DataRowView)e.Row.DataItem;
                int empId = Convert.ToInt32(rowView["idemp"]);

                DataTable dt = new DataTable();
                string constr = @"server=127.0.0.1;user id=root;pwd=n0711p2010p;database=emp";
                using (MySqlConnection con = new MySqlConnection(constr))
                {
                    con.Open();
                    // 参数化查询,避免SQL注入并保证数据准确性
                    MySqlCommand cmd = new MySqlCommand("SELECT salary, post FROM emp WHERE idemp = @EmpId", con);
                    cmd.Parameters.AddWithValue("@EmpId", empId);
                    
                    using (MySqlDataReader dtreader = cmd.ExecuteReader())
                    {
                        dt.Load(dtreader);
                    }

                    GridView childGrid = (GridView)e.Row.FindControl("GridView2");
                    if (dt.Rows.Count > 0)
                    {
                        childGrid.DataSource = dt;
                        childGrid.DataBind();
                    }
                }
            }
        }
    }
}

关键改进点总结

  • 让表头列与数据列一一对应,避免单独用TemplateField包裹整个表头。
  • 为子GridView明确配置列,确保数据正常渲染。
  • 使用参数化查询获取子表数据,既保证数据准确性(不再依赖行索引),又避免SQL注入风险。
  • 优化资源释放:用using语句自动释放MySqlDataReader等资源。

内容的提问来源于stack exchange,提问作者nisarg parekh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:15:08