ASP.NET C#:GridView动态添加行二次点击数据丢失问题求助
解决GridView二次点击按钮初始行被清空的问题
问题根源
每次页面回发(如点击生成数据按钮)时,未持久化GridView的数据源。默认情况下,回发后会重新创建数据源并绑定,导致之前添加的行被覆盖。需将数据源存储在ViewState或Session中,保留历史数据。
修正后的.aspx标记代码
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>GridView数据处理</title> </head> <body> <form id="form1" runat="server"> <div> <asp:TextBox ID="txtNumber" runat="server" PlaceHolder="输入乘数"></asp:TextBox> <asp:DropDownList ID="ddlMultiplier" runat="server"> <asp:ListItem Text="2" Value="2"></asp:ListItem> <asp:ListItem Text="3" Value="3"></asp:ListItem> <asp:ListItem Text="4" Value="4"></asp:ListItem> </asp:DropDownList> <asp:Button ID="btnGenerate" runat="server" Text="生成多行数据" OnClick="btnGenerate_Click" /> <asp:Button ID="btnSave" runat="server" Text="保存修改" OnClick="btnSave_Click" /> <br /><br /> <asp:GridView ID="gvData" runat="server" AutoGenerateColumns="False" OnRowEditing="gvData_RowEditing" OnRowUpdating="gvData_RowUpdating" OnRowCancelingEdit="gvData_RowCancelingEdit"> <Columns> <asp:BoundField DataField="OriginalNumber" HeaderText="原始数字" /> <asp:BoundField DataField="Multiplier" HeaderText="乘数" /> <asp:TemplateField HeaderText="结果"> <ItemTemplate> <asp:Label ID="lblResult" runat="server" Text='<%# Eval("Result") %>'></asp:Label> </ItemTemplate> <EditItemTemplate> <asp:TextBox ID="txtResult" runat="server" Text='<%# Eval("Result") %>'></asp:TextBox> </EditItemTemplate> </asp:TemplateField> <asp:CommandField ShowEditButton="True" /> </Columns> </asp:GridView> </div> </form> </body> </html>
修正后的C#后台代码
using System; using System.Data; public partial class _Default : System.Web.UI.Page { private const string DataTableViewStateKey = "GridViewData"; protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { DataTable dt = new DataTable(); dt.Columns.Add("OriginalNumber", typeof(int)); dt.Columns.Add("Multiplier", typeof(int)); dt.Columns.Add("Result", typeof(int)); ViewState[DataTableViewStateKey] = dt; gvData.DataSource = dt; gvData.DataBind(); } } protected void btnGenerate_Click(object sender, EventArgs e) { DataTable dt = (DataTable)ViewState[DataTableViewStateKey]; int originalNumber; int multiplier; if (int.TryParse(txtNumber.Text, out originalNumber) && int.TryParse(ddlMultiplier.SelectedValue, out multiplier)) { for (int i = 1; i <= multiplier; i++) { DataRow dr = dt.NewRow(); dr["OriginalNumber"] = originalNumber; dr["Multiplier"] = i; dr["Result"] = originalNumber * i; dt.Rows.Add(dr); } ViewState[DataTableViewStateKey] = dt; gvData.DataSource = dt; gvData.DataBind(); txtNumber.Text = string.Empty; } } protected void btnSave_Click(object sender, EventArgs e) { DataTable dt = (DataTable)ViewState[DataTableViewStateKey]; foreach (GridViewRow row in gvData.Rows) { if (row.RowType == DataControlRowType.DataRow) { int rowIndex = row.DataItemIndex; TextBox txtResult = row.FindControl("txtResult") as TextBox; if (txtResult != null) { int result; if (int.TryParse(txtResult.Text, out result)) { dt.Rows[rowIndex]["Result"] = result; } } } } ViewState[DataTableViewStateKey] = dt; // 此处可添加数据持久化到数据库的逻辑 Response.Write("修改已保存"); } protected void gvData_RowEditing(object sender, GridViewEditEventArgs e) { gvData.EditIndex = e.NewEditIndex; gvData.DataSource = (DataTable)ViewState[DataTableViewStateKey]; gvData.DataBind(); } protected void gvData_RowUpdating(object sender, GridViewUpdateEventArgs e) { DataTable dt = (DataTable)ViewState[DataTableViewStateKey]; GridViewRow row = gvData.Rows[e.RowIndex]; TextBox txtResult = row.FindControl("txtResult") as TextBox; if (txtResult != null) { int result; if (int.TryParse(txtResult.Text, out result)) { dt.Rows[e.RowIndex]["Result"] = result; } } gvData.EditIndex = -1; ViewState[DataTableViewStateKey] = dt; gvData.DataSource = dt; gvData.DataBind(); } protected void gvData_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e) { gvData.EditIndex = -1; gvData.DataSource = (DataTable)ViewState[DataTableViewStateKey]; gvData.DataBind(); } }
关键修正点
- 持久化数据源:使用
ViewState存储DataTable,确保页面回发时保留历史数据,避免每次点击按钮重新创建数据源导致旧数据丢失。 - 追加数据逻辑:点击生成按钮时,先从
ViewState取出已有DataTable,再添加新行,而非重新初始化。 - 编辑同步:编辑和保存操作时,同步更新
ViewState中的DataTable,保证数据一致性。
内容的提问来源于stack exchange,提问作者Bruno Alves
相关产品推荐
相关产品推荐

