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事件没生效,主要有两个原因:
- 直接拼接
__doPostBack脚本可能会触发ASP.NET的事件验证错误 - 当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
相关产品推荐
相关产品推荐

