GridView动态添加TextBox值获取失败及转数据集问题求助
问题解答
一、解决动态添加TextBox获取值为null的问题
这个问题的核心是ASP.NET页面生命周期的ViewState机制:动态创建的控件必须在每次回发时(比如点击Update按钮)重新创建,并且要保证控件的ID和第一次创建时完全一致,这样ASP.NET才能从ViewState中恢复控件的值。你现在的代码只在RowDataBound中创建了一次控件,回发时这些控件没有被重建,所以FindControl会返回null。
具体修复步骤:
在页面初始化阶段重新创建动态控件
你需要在Page_Init或者Page_Load的早期(优先选Page_Init,因为它在ViewState加载前执行)重新遍历GridView的行,按照之前的条件创建TextBox,确保ID和RowDataBound中生成的完全一致。示例代码:
protected void Page_Init(object sender, EventArgs e) { if (IsPostBack) { // 从ViewState取出之前保存的数据源,重新绑定GridView GVUploadDetails.DataSource = ViewState["GridDataSource"]; GVUploadDetails.DataBind(); // 重新创建动态TextBox,逻辑要和RowDataBound中一致 foreach (GridViewRow row in GVUploadDetails.Rows) { if (row.RowType == DataControlRowType.DataRow) { string columnName = "你的目标列名"; // 替换成实际列名 int columnLength = 10; // 替换成你设定的长度阈值 string cellValue = Convert.ToString(DataBinder.Eval(row.DataItem, columnName)); if (cellValue.Length > columnLength) { int colIndex = GetColumnIndexByName(row, columnName); TextBox txt = new TextBox(); txt.ID = "txt_" + row.RowIndex + "_" + colIndex; // 保证ID和之前生成的完全一致 row.Cells[colIndex].Controls.Add(txt); } } } } }注意:第一次绑定GridView时,要把数据源保存到
ViewState,这样回发时才能重新绑定:protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { DataTable dt = GetYourOriginalDataSource(); // 你的数据源获取逻辑 ViewState["GridDataSource"] = dt; GVUploadDetails.DataSource = dt; GVUploadDetails.DataBind(); } }正确获取TextBox的值
现在回发时控件已经重建,你可以通过lstErrorTracker里的标记来定位控件,避免硬编码ID:foreach (string key in lstErrorTracker) { string[] parts = key.Split('_'); int rowIndex = int.Parse(parts[0]); int colIndex = int.Parse(parts[1]); GridViewRow row = GVUploadDetails.Rows[rowIndex]; TextBox txt = row.Cells[colIndex].FindControl("txt_" + key) as TextBox; if (txt != null) { string updatedValue = txt.Text; // 这里处理你拿到的更新后的值 } }
二、将GridView数据转换为DataSet/DataTable
情况1:数据源本身是DataTable/DataSet
如果GridView绑定的数据源本来就是DataTable或DataSet,可以直接强转:
// 转DataTable DataTable dt = GVUploadDetails.DataSource as DataTable; // 转DataSet DataSet ds = GVUploadDetails.DataSource as DataSet;
情况2:数据源不是DataTable/DataSet(比如List)
需要手动遍历GridView的行和列构建DataTable:
DataTable dt = new DataTable(); // 先添加表头列 foreach (TableCell headerCell in GVUploadDetails.HeaderRow.Cells) { dt.Columns.Add(headerCell.Text); } // 遍历数据行填充DataTable foreach (GridViewRow row in GVUploadDetails.Rows) { if (row.RowType == DataControlRowType.DataRow) { DataRow dr = dt.NewRow(); for (int i = 0; i < row.Cells.Count; i++) { // 优先取单元格内TextBox的值,没有则取单元格文本 TextBox txt = row.Cells[i].FindControl($"txt_{row.RowIndex}_{i}") as TextBox; dr[i] = txt != null ? txt.Text : row.Cells[i].Text; } dt.Rows.Add(dr); } } // 转DataSet的话,把DataTable加入即可 DataSet ds = new DataSet(); ds.Tables.Add(dt);
内容的提问来源于stack exchange,提问作者Anirudh Agarwal
相关产品推荐
相关产品推荐

