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

ASP.NET无需CommandField实现GridView行编辑(解决空间不足问题)

解决ASP.NET GridView无编辑列的行内编辑及外部按钮触发更新/取消问题

我明白你想要实现的效果:点击GridView的行直接进入编辑模式,不用显示自带的编辑/更新/取消按钮,而是用页面上的外部按钮(Button1和Button2)来完成更新和取消操作。之前的onclick事件没生效,主要有几个关键点需要调整,咱们一步步来解决:

第一步:修正GridView标记,移除默认编辑列

首先把GridView里的<asp:CommandField ShowEditButton="True" />删掉,因为你不想显示自带的编辑按钮。同时确保编辑列的模板设置正确(你的TemplateField已经用了TextBox,这部分没问题):

<asp:GridView ID="GridView1" runat="server" DataSourceID="SqlDataSource1" 
    AutoGenerateColumns="false" DataKeyNames="PKCOD" AllowPaging="True" 
    PageSize="10" CssClass="auto-style1" OnRowDataBound="GridView1_RowDataBound">
<Columns>
    <asp:TemplateField HeaderText="QUANTITA" SortExpression="QUANTITA">
        <EditItemTemplate>
            <asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("QUANTITA") %>'></asp:TextBox>
            <br />
            <asp:RangeValidator ID="RangeValidator1" runat="server" 
                ControlToValidate="TextBox1" EnableClientScript="False" 
                ErrorMessage="ErrorMessage" MaximumValue="999" MinimumValue="0" 
                Type="Integer">Valori tra 0 e 999</asp:RangeValidator>
        </EditItemTemplate>
        <ItemTemplate>
            <asp:Label ID="Label1" runat="server" Text='<%# Bind("QUANTITA") %>'></asp:Label>
        </ItemTemplate>
    </asp:TemplateField>
    <!-- 其他绑定列保持不变 -->
    <asp:BoundField DataField="CODICE" HeaderText="CODICE" ReadOnly="True" SortExpression="CODICE" />
    <asp:BoundField DataField="DESCRIZIONE" HeaderText="DESCRIZIONE" ReadOnly="True" SortExpression="DESCRIZIONE" />
    <asp:BoundField DataField="CATEGORIA" HeaderText="CATEGORIA" ReadOnly="True" SortExpression="CATEGORIA" Visible="False" />
    <asp:BoundField DataField="PKCOD" HeaderText="PKCOD" ReadOnly="True" SortExpression="PKCOD" InsertVisible="False" Visible="False" />
    <asp:BoundField DataField="USERNAME" HeaderText="USERNAME" ReadOnly="True" SortExpression="USERNAME" Visible="False" />
    <asp:BoundField DataField="USERID" HeaderText="USERID" ReadOnly="True" SortExpression="USERID" Visible="False" />
    <asp:BoundField DataField="USERDT" HeaderText="USERDT" ReadOnly="True" SortExpression="USERDT" Visible="False" />
    <asp:BoundField DataField="STATO" HeaderText="STATO" ReadOnly="True" SortExpression="STATO" Visible="False" />
</Columns>
</asp:GridView>

第二步:修复RowDataBound事件中的脚本问题

之前的onclick事件没生效,主要有两个原因:

  1. 直接拼接__doPostBack脚本可能会触发ASP.NET的事件验证错误
  2. 当GridView处于编辑模式时,原来的Update按钮获取方式(e.Row.Cells[0].Controls[0])已经失效,因为我们移除了CommandField

我们改用ClientScript.GetPostBackEventReference生成合法的回发脚本,同时手动注册事件验证(如果页面启用了事件验证):

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        if (e.Row.RowIndex == GridView1.EditIndex)
        {
            // 生成更新操作的回发脚本,模拟GridView内置的Update行为
            string updateScript = ClientScript.GetPostBackEventReference(GridView1, "Update$" + e.Row.RowIndex);
            Button1.Attributes["onclick"] = updateScript;

            // 生成取消操作的回发脚本,模拟GridView内置的Cancel行为
            string cancelScript = ClientScript.GetPostBackEventReference(GridView1, "Cancel$" + e.Row.RowIndex);
            Button2.Attributes["onclick"] = cancelScript;

            // 注册事件验证,避免回发时触发"无效参数"错误
            if (Page.ClientScript.IsEventValidationEnabled)
            {
                Page.ClientScript.RegisterForEventValidation(GridView1.UniqueID, "Update$" + e.Row.RowIndex);
                Page.ClientScript.RegisterForEventValidation(GridView1.UniqueID, "Cancel$" + e.Row.RowIndex);
            }
        }
        else
        {
            // 生成点击行进入编辑模式的脚本
            string editScript = ClientScript.GetPostBackEventReference(GridView1, "Edit$" + e.Row.RowIndex);
            e.Row.Attributes["onclick"] = editScript;
            // 给行添加鼠标悬停提示,提升体验
            e.Row.Style["cursor"] = "pointer";
            e.Row.ToolTip = "点击进入编辑模式";

            // 注册事件验证
            if (Page.ClientScript.IsEventValidationEnabled)
            {
                Page.ClientScript.RegisterForEventValidation(GridView1.UniqueID, "Edit$" + e.Row.RowIndex);
            }
        }
    }

    // 控制外部按钮的启用状态
    Button1.Enabled = GridView1.EditIndex >= 0;
    Button2.Enabled = GridView1.EditIndex >= 0;
}

第三步:绑定GridView的更新/取消事件

别忘了在GridView标记里添加OnRowUpdating和OnRowCancelingEdit事件,让更新和取消操作能触发后台逻辑:

<asp:GridView ID="GridView1" runat="server" 
    ...
    OnRowDataBound="GridView1_RowDataBound"
    OnRowUpdating="GridView1_RowUpdating"
    OnRowCancelingEdit="GridView1_RowCancelingEdit">

对应的后台事件示例:

protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
    // 获取编辑行的输入值和主键
    GridViewRow row = GridView1.Rows[e.RowIndex];
    TextBox txtQuantita = (TextBox)row.FindControl("TextBox1");
    int quantita = int.Parse(txtQuantita.Text);
    string pkCod = GridView1.DataKeys[e.RowIndex].Value.ToString();

    // 执行数据库更新逻辑(这里用SqlDataSource为例)
    SqlDataSource1.UpdateParameters["QUANTITA"].DefaultValue = quantita.ToString();
    SqlDataSource1.UpdateParameters["PKCOD"].DefaultValue = pkCod;
    SqlDataSource1.Update();

    // 退出编辑模式并重新绑定数据
    GridView1.EditIndex = -1;
    GridView1.DataBind();
}

protected void GridView1_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
    // 退出编辑模式并重新绑定数据
    GridView1.EditIndex = -1;
    GridView1.DataBind();
}

关键注意点

  • 如果页面启用了EnableEventValidation="true"(默认启用),必须调用RegisterForEventValidation注册回发事件,否则会抛出“无效的回发或回调参数”错误。
  • 确保DataKeyNames设置正确(你已经设置了PKCOD,没问题),这样更新时能正确获取主键值。
  • 外部按钮(Button1和Button2)不需要设置服务器端OnClick事件,因为我们已经通过客户端onclick属性绑定了回发脚本,直接触发GridView的内置操作。

这样调整后,点击GridView的行就能进入编辑模式,点击Button1会触发更新,Button2会触发取消,而且不会显示自带的编辑列,完全符合你的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:04:41