ASP.Net中使用BoundField列编辑GridView无法获取新值的问题
解决GridView编辑时无法获取新值的问题
我来帮你排查下这个问题——你遇到的编辑行后只能获取旧值的情况,最常见的原因是页面回发时重复绑定了GridView,另外你获取TextBox的方式也可以更可靠,下面一步步来解决:
1. 先检查Page_Load中的数据绑定逻辑
这是最容易踩的坑:如果你的BindAppSettingGrid()方法在每次页面回发时都执行(比如直接写在Page_Load里没加判断),那么点击更新按钮时,页面会先重新绑定GridView,把用户输入的新值覆盖掉,导致你拿到的还是旧数据。
你需要把数据绑定放在!IsPostBack判断里,确保只有首次加载页面时才绑定数据:
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { BindAppSettingGrid(); // 仅首次加载时绑定 } }
2. 优化获取编辑值的方式
你当前通过Cells索引找控件的方式容易出错(比如列顺序调整、新增隐藏列都会导致索引变化),推荐两种更可靠的方法:
方法一:用GridViewUpdateEventArgs的NewValues属性
GridView在更新时会自动把用户输入的新值存在e.NewValues集合里,直接取就行,不用依赖控件位置:
protected void grdAppSetting_RowUpdating(object sender, GridViewUpdateEventArgs e) { // 直接从NewValues获取新值,OldValues存的是编辑前的旧值(适合取ReadOnly的KeyName) string newValue = e.NewValues["Value"].ToString(); string keyName = e.OldValues["Key Name"].ToString(); if (appSettingsSection != null) { appSettingsSection.Settings[keyName].Value = newValue; configuration.Save(); } grdAppSetting.EditIndex = -1; BindAppSettingGrid(); }
方法二:改用TemplateField自定义编辑控件
如果想更灵活控制编辑控件,把BoundField换成TemplateField,自己定义TextBox的ID,之后用FindControl精准查找:
修改你的ASPX代码:
<asp:GridView ID="grdAppSetting" AutoGenerateEditButton="true" AutoGenerateDeleteButton="true" HeaderStyle-BackColor="#1abc9c" HeaderStyle-ForeColor="White" CssClass="t-transform m-t-30" HeaderStyle-BorderWidth="5px" runat="server" OnRowCancelingEdit="grdAppSetting_RowCancelingEdit1" OnRowDeleting="grdAppSetting_RowDeleting" OnRowUpdating="grdAppSetting_RowUpdating" OnRowEditing="grdAppSetting_RowEditing" AutoGenerateColumns="false" BorderColor="#1abc9c"> <Columns> <asp:TemplateField HeaderText="Key Name" ItemStyle-CssClass="p-l-10" ItemStyle-Width="100"> <ItemTemplate> <%# Eval("Key Name") %> </ItemTemplate> </asp:TemplateField> <asp:TemplateField HeaderText="Value" ItemStyle-Height="40px" ItemStyle-Width="50%" ItemStyle-CssClass="p-l-10"> <ItemTemplate> <%# Eval("Value") %> </ItemTemplate> <EditItemTemplate> <asp:TextBox ID="txtValue" CssClass="form-control" runat="server" Text='<%# Bind("Value") %>'></asp:TextBox> </EditItemTemplate> </asp:TemplateField> </Columns> </asp:GridView>
然后在后台代码里获取值:
protected void grdAppSetting_RowUpdating(object sender, GridViewUpdateEventArgs e) { // 通过ID精准查找编辑行的TextBox TextBox txtValue = grdAppSetting.Rows[e.RowIndex].FindControl("txtValue") as TextBox; if (txtValue != null) { string newValue = txtValue.Text; string keyName = grdAppSetting.Rows[e.RowIndex].Cells[1].Text; if (appSettingsSection != null) { appSettingsSection.Settings[keyName].Value = newValue; configuration.Save(); } } grdAppSetting.EditIndex = -1; BindAppSettingGrid(); }
3. 关于你当前获取TextBox方式的说明
你写的((grdAppSetting.Rows[e.RowIndex].Cells[2].Controls[0]) as TextBox).Text本身逻辑没问题,但前提是:
- 页面没有在回发时重新绑定GridView(否则控件会被重建,丢失用户输入)
- Cells的索引是正确的(因为AutoGenerateEditButton会生成一列,所以你的Value列确实是Cells[2])
但这种方式依赖列的位置,不够健壮,还是推荐上面两种方法。
先优先检查Page_Load里的绑定逻辑,这大概率是问题的根源!
内容的提问来源于stack exchange,提问作者Raji
相关产品推荐
相关产品推荐

