Asp.Net中获取自动生成列GridView编辑后的值问题
You’re just running into a common postback/control lifecycle issue with GridView user controls—totally fixable. Let’s walk through why you can’t access the edited values and how to get your update logic working.
Common Reasons You Can’t Retrieve New Values
- Dynamic controls aren’t recreated on postback: If you’re generating GridView columns dynamically (which you need to for arbitrary DataTables), you have to rebuild the column structure every time the page loads (specifically in the
Page_Initevent), not just on the first load. If you skip this, ASP.NET can’t map the postback values to the controls. - Incorrect control access: You might be using the wrong method to find the edit controls, or targeting the wrong row in the GridView.
- Overlooking
e.NewValuesfor BoundFields: If you’re using BoundFields instead of TemplateFields, you don’t even need to find the textbox—GridView’sGridViewUpdateEventArgsgives you direct access to the updated values via theNewValuescollection.
Step-by-Step Fixes
1. Ensure Dynamic Columns Are Recreated on Every Postback
Since your control needs to bind to any DataTable, you’ll need to rebuild the GridView columns in the Page_Init event (this is critical for maintaining control state across postbacks). Here’s how to adjust your setup:
public partial class EditableGridViewControl : System.Web.UI.UserControl { // Store the DataTable in Session to persist across postbacks private DataTable GridData { get => Session["EditableGridData"] as DataTable; set => Session["EditableGridData"] = value; } protected void Page_Init(object sender, EventArgs e) { // Recreate columns on every postback if we have stored data if (GridData != null) { InitGridColumns(GridData); } } // Public method to initialize the grid with a new DataTable public void InitializeGrid(DataTable sourceTable) { GridData = sourceTable; InitGridColumns(sourceTable); BindGrid(); } private void InitGridColumns(DataTable dt) { EditableGrid.Columns.Clear(); // Add BoundFields for each column in the DataTable foreach (DataColumn col in dt.Columns) { BoundField boundField = new BoundField { DataField = col.ColumnName, HeaderText = col.ColumnName, ReadOnly = false // Allow editing for all columns }; EditableGrid.Columns.Add(boundField); } // Add Edit/Delete command field CommandField commandField = new CommandField { ShowEditButton = true, ShowDeleteButton = true, CancelText = "Cancel", UpdateText = "Save" }; EditableGrid.Columns.Add(commandField); } private void BindGrid() { EditableGrid.DataSource = GridData; EditableGrid.DataBind(); } }
2. Correctly Retrieve Edited Values in RowUpdating
Pick the approach that matches your GridField setup:
For BoundFields (Simpler Option!)
Use the e.NewValues collection to get updated values directly without finding controls:
protected void EditableGrid_RowUpdating(object sender, GridViewUpdateEventArgs e) { int rowIndex = e.RowIndex; DataRow rowToUpdate = GridData.Rows[rowIndex]; // Update each column with the new value from postback foreach (DictionaryEntry entry in e.NewValues) { string columnName = entry.Key.ToString(); object newValue = entry.Value; if (newValue != null) { rowToUpdate[columnName] = newValue; } } // Replace this with your actual database update logic SaveDataToDatabase(GridData); // Exit edit mode and rebind the grid EditableGrid.EditIndex = -1; BindGrid(); }
For TemplateFields (Custom Edit Controls)
If you’re using custom textboxes in TemplateFields, find the control in the edited row:
protected void EditableGrid_RowUpdating(object sender, GridViewUpdateEventArgs e) { GridViewRow editedRow = EditableGrid.Rows[e.RowIndex]; // Example: Get value from a TextBox with ID "txtCustomerName" TextBox txtCustomerName = (TextBox)editedRow.FindControl("txtCustomerName"); if (txtCustomerName != null) { GridData.Rows[e.RowIndex]["CustomerName"] = txtCustomerName.Text; } // Repeat for other custom controls... SaveDataToDatabase(GridData); EditableGrid.EditIndex = -1; BindGrid(); }
3. Add Required Event Handlers for Edit/Delete Flow
Don’t forget these basic handlers to manage edit mode and deletion:
protected void EditableGrid_RowEditing(object sender, GridViewEditEventArgs e) { EditableGrid.EditIndex = e.NewEditIndex; BindGrid(); } protected void EditableGrid_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e) { EditableGrid.EditIndex = -1; BindGrid(); } protected void EditableGrid_RowDeleting(object sender, GridViewDeleteEventArgs e) { GridData.Rows[e.RowIndex].Delete(); SaveDataToDatabase(GridData); BindGrid(); }
Key Tips for Your Generic Control
- Persist the DataTable: Use
Session(orViewStatefor small datasets) to keep the DataTable between postbacks—avoid reloading it from scratch every time unless necessary. - Make it flexible: Add public properties to let parent pages toggle edit/delete functionality, set custom header texts, or add validation rules.
- Validate inputs: Add server-side validation to ensure edited values are valid before updating your data source.
This setup will give you a fully functional, reusable GridView user control that works with any DataTable, supports editing/deleting, and correctly retrieves updated values.
内容的提问来源于stack exchange,提问作者user1238784

