C# ASP.NET中GridView含DropDownList时取消行编辑异常问题
解决GridView编辑状态下返回后取消按钮异常跳转问题
场景代码
前端GridView.aspx代码
<asp:TemplateField ItemStyle-HorizontalAlign="Center"> <ItemTemplate> <asp:ImageButton ID="btnedit" runat="server" CommandName="Edit" ImageUrl="edit_icon.gif" ToolTip= "Edit" /> </ItemTemplate> <EditItemTemplate> <asp:ImageButton ID="btncancel" runat="server" CommandName="Cancel" ImageUrl="cancel.gif" ToolTip="Cancel editing" /> </EditItemTemplate> </asp:TemplateField> <asp:TemplateField HeaderText="BS" ItemStyle-HorizontalAlign="Justify"> <ItemTemplate> <asp:Label ID="lbBS" runat="server" CssClass="ddl_Class_new" Text='<%# HttpUtility.HtmlDecode(MaP.SpliceText(Eval("BS").ToString(),11)) %>'> </asp:Label> </ItemTemplate> <asp:TemplateField HeaderText="F" ItemStyle-CssClass="ddl_Class_new" ItemStyle-HorizontalAlign="Left"> <ItemTemplate> <asp:Label ID="lblF" runat="server" Text='<%# Eval("F") %>'></asp:Label> </ItemTemplate> <EditItemTemplate> <asp:DropDownList ID="ddl" runat="server" CssClass="ddl_Class_new" AutoPostBack="true" BackColor="Yellow" OnSelectedIndexChanged="ddl"> <asp:ListItem Text= "A" Value="A"></asp:ListItem> <asp:ListItem Text= "B" Value="B"></asp:ListItem> </asp:DropDownList> </EditItemTemplate> </asp:TemplateField>
后台代码
protected void ddl(object sender, EventArgs e) { DropDownList list = (DropDownList)sender; string value = (string)list.SelectedValue; switch (value) { case "A": Server.Transfer("Default.aspx"); break; case "B": Server.Transfer("Default2.aspx"); break; } }
操作流程与问题
- 编辑GridView中的某一行,进入编辑状态后显示DropDownList(ddl)
- 选择ddl中的"A"选项,通过
Server.Transfer跳转至Default.aspx - 使用浏览器返回按钮回到GridView.aspx页面
- 问题:点击取消编辑按钮时,未退出GridView的编辑状态,反而再次跳转到Default.aspx
尝试过的无效代码
protected void gv_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e) { gv.EditIndex = -1; DropDownList ddl = (DropDownList)FindControl("ddl"); ddl.Items.Clear(); DataBind; }
解决方案
问题根源
Server.Transfer是服务器端跳转,浏览器地址栏不会更新,返回时页面从缓存加载,DropDownList仍保留之前选中的"A"值- 点击取消按钮触发页面回发时,DropDownList的
SelectedIndexChanged事件被再次触发,导致重复跳转 - 原Cancel事件代码存在错误:
DataBind缺少括号,且直接用FindControl无法定位到GridView编辑行内的ddl控件
修正步骤
1. 修复RowCancelingEdit事件代码
protected void gv_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e) { gv.EditIndex = -1; // 重新绑定GridView即可重置状态,无需手动清除ddl项 gv.DataBind(); }
2. 阻止取消回发时触发DropDownList事件
有两种可选方案:
方案一:使用Response.Redirect替代Server.Transfer
将跳转代码改为客户端跳转,这样浏览器历史记录会更新,返回时会重新请求GridView.aspx,页面状态完全重置:
protected void ddl(object sender, EventArgs e) { DropDownList list = (DropDownList)sender; string value = (string)list.SelectedValue; switch (value) { case "A": Response.Redirect("Default.aspx"); break; case "B": Response.Redirect("Default2.aspx"); break; } }
方案二:在回发时判断操作类型,禁用DropDownList事件
在Page_Load中添加判断,当回发是由取消按钮触发时,找到编辑行内的ddl并取消其事件绑定:
protected void Page_Load(object sender, EventArgs e) { if (IsPostBack) { string eventTarget = Request.Form["__EVENTTARGET"]; // 判断是否是取消编辑按钮触发的回发 if (!string.IsNullOrEmpty(eventTarget) && eventTarget.Contains("btncancel")) { if (gv.EditIndex != -1) { GridViewRow editRow = gv.Rows[gv.EditIndex]; DropDownList ddl = (DropDownList)editRow.FindControl("ddl"); if (ddl != null) { ddl.SelectedIndexChanged -= ddl; } } } } }
内容的提问来源于stack exchange,提问作者George A. Custer
相关产品推荐
相关产品推荐

