Telerik RadGrid批量编辑模式下无法获取单元格值求助
解决Telerik RadGrid批量编辑模式下获取所有单元格值并转DataTable的问题
我明白你现在的痛点:用了RadGrid的批量编辑模式,点击按钮却拿不到编辑后的单元格值,没法转成DataTable传给存储过程。别着急,咱们一步步来解决这个问题。
首先得明确:批量编辑模式下,用户在客户端的修改默认存在客户端缓存里,必须先把这些修改同步到服务端,才能在后台获取到最新值。下面分两种场景给你方案:
一、用RadGrid内置的批量保存按钮(简单省心)
如果可以用内置按钮,配置起来最方便:
1. 完善RadGrid的配置
确保你的RadGrid标签里加上这些关键配置:
<telerik:RadGrid RenderMode="Lightweight" ID="RadGrid1" runat="server" CellSpacing="0" GridLines="Both" OnItemDataBound="RadGrid1_ItemDataBound" AllowPaging="false" AutoGenerateColumns="false" AllowAutomaticUpdates="true" <!-- 开启自动更新 --> OnNeedDataSource="RadGrid1_NeedDataSource"> <!-- 绑定数据源的事件 --> <MasterTableView EditMode="Batch"> <!-- 开启批量编辑 --> <BatchEditingSettings EditType="Cell" /> <!-- 按单元格编辑,也可以选Row --> <Columns> <!-- 你的列定义,比如GridBoundColumn等 --> <telerik:GridBoundColumn DataField="ID" UniqueName="ID" HeaderText="ID" ReadOnly="true" /> <telerik:GridBoundColumn DataField="Name" UniqueName="Name" HeaderText="名称" /> <!-- 其他列... --> </Columns> <CommandItemSettings ShowSaveChangesButton="true" /> <!-- 显示内置保存按钮 --> </MasterTableView> </telerik:RadGrid>
2. 在服务端获取编辑后的DataTable
当用户点击内置的「保存更改」按钮后,RadGrid会自动把客户端的修改同步到服务端数据源。此时你可以在需要的地方(比如自定义按钮点击事件)获取完整的DataTable:
protected void btnExportToSP_Click(object sender, EventArgs e) { // 先让Grid重新绑定,确保最新数据加载到服务端 RadGrid1.Rebind(); // 构建DataTable DataTable dt = new DataTable(); // 先添加对应列(根据Grid的绑定列来) foreach (GridColumn col in RadGrid1.Columns) { if (col is GridBoundColumn boundCol) { // 这里可以根据实际数据类型调整,比如int、DateTime等 Type colType = typeof(string); if (boundCol.DataType != null) colType = boundCol.DataType; dt.Columns.Add(boundCol.UniqueName, colType); } } // 遍历Grid的每一行,填充DataTable foreach (GridDataItem item in RadGrid1.Items) { DataRow dr = dt.NewRow(); foreach (GridColumn col in RadGrid1.Columns) { if (col is GridBoundColumn boundCol) { // 获取编辑后的单元格值 dr[boundCol.UniqueName] = item[boundCol.UniqueName].Text; } } dt.Rows.Add(dr); } // 现在dt就是包含所有编辑后数据的表,传给存储过程 SendDataTableToStoredProcedure(dt); } // 调用存储过程的方法 private void SendDataTableToStoredProcedure(DataTable dt) { using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["YourConnString"].ConnectionString)) { SqlCommand cmd = new SqlCommand("YourStoredProcedureName", conn); cmd.CommandType = CommandType.StoredProcedure; // 注意:存储过程需要定义对应的表值参数 SqlParameter tvpParam = cmd.Parameters.AddWithValue("@YourTableParam", dt); tvpParam.SqlDbType = SqlDbType.Structured; tvpParam.TypeName = "dbo.YourDefinedTableType"; // 对应SQL里创建的表类型 conn.Open(); cmd.ExecuteNonQuery(); } }
二、用自定义按钮触发批量保存(更灵活)
如果必须用自己的按钮,需要先在客户端触发批量修改的提交,再回传到服务端:
1. 客户端脚本提交修改
给自定义按钮加上客户端点击事件:
<asp:Button ID="btnCustomSave" runat="server" Text="保存到数据库" OnClientClick="return submitBatchChanges();" OnClick="btnCustomSave_Click" /> <script type="text/javascript"> function submitBatchChanges() { var grid = $find("<%= RadGrid1.ClientID %>"); var batchManager = grid.get_batchEditingManager(); // 如果有未保存的修改,先提交 if (batchManager.hasChanges()) { batchManager.saveChanges(); // 延迟确保提交完成后再触发回传 setTimeout(function() { __doPostBack('<%= btnCustomSave.UniqueID %>', ''); }, 500); return false; // 阻止默认回传,等提交完成后手动触发 } return true; } </script>
2. 服务端逻辑和第一种场景一致
在btnCustomSave_Click事件里,同样用上面的代码构建DataTable并传给存储过程即可。
关键注意事项
- ViewState要启用:确保RadGrid的
ViewStateMode="Enabled",否则回传时会丢失数据。 - 表值参数的SQL配置:必须先在SQL Server里创建对应的表类型,比如:
CREATE TYPE dbo.YourDefinedTableType AS TABLE ( ID INT, Name VARCHAR(100), -- 对应DataTable的所有列 )
然后存储过程的参数要定义为@YourTableParam YourDefinedTableType READONLY。
- 数据类型匹配:构建DataTable时,列的类型要和数据库表、存储过程的表类型一致,避免类型转换错误。
这样操作下来,你就能成功获取批量编辑后的所有单元格值,转成DataTable传给存储过程了。
内容的提问来源于stack exchange,提问作者Amjad Mehmood
相关产品推荐
相关产品推荐

