DataGridView单元格格式化后,更新数据库存入原始值问题
问题根源与解决方案
你遇到的核心问题是:CellFormatting事件仅用于修改DataGridView的界面显示内容,不会改变绑定的DataTable中的底层数据。当你调用dataAdapter.Update(dataTable)时,程序会使用DataTable里的原始值(S010/S011)去更新数据库,而非你格式化后的BE/BI。
解决方案:修改底层数据源而非仅修改显示
根据你的需求,有两种常用的解决思路,你可以根据实际场景选择:
1. 在SQL查询阶段直接转换(推荐,最高效)
如果数据库最终需要存储的是BE/BI这类转换后的值,或者你只是想让DataTable加载时就得到转换后的数据,可以直接在查询语句中用CASE WHEN完成转换:
SELECT CASE WHEN YourTargetColumn LIKE '%S010%' THEN 'BE' WHEN YourTargetColumn LIKE '%S011%' THEN 'BI' ELSE YourTargetColumn END AS YourTargetColumn, -- 保留其他需要查询的列 Column1, Column2, ... FROM xxxxxxxxxxxx
这样dataAdapter.Fill(dataTable)后,DataTable里的目标列已经是BE/BI,后续更新数据库时自然会使用这些值。
2. 填充DataTable后修改底层数据
如果你需要在代码中控制转换逻辑,可以在DataBind()函数填充完dataTable后,遍历修改其中的行数据:
private void DataBind() { dataGridViewCND.DataSource = null; dataTable.Clear(); string query = "SELECT xxxxxxxxxxxx FROM xxxxxxxxxxxx"; SqlConnection con = new SqlConnection(conStringLocal); con.Open(); SqlCommand command = con.CreateCommand(); command.CommandText = query; dataAdapter = new SqlDataAdapter(query, con); commandBuilder = new SqlCommandBuilder(dataAdapter); dataAdapter.Fill(dataTable); // 遍历DataTable,修改目标列的值 foreach(DataRow row in dataTable.Rows) { // 先判断单元格是否为空,避免空引用异常 if(row.IsNull("YourTargetColumn")) continue; string originalValue = row["YourTargetColumn"].ToString(); if(originalValue.Contains("S010")) { row["YourTargetColumn"] = "BE"; } else if(originalValue.Contains("S011")) { row["YourTargetColumn"] = "BI"; } } bindingSource = new BindingSource { DataSource = dataTable }; dataGridViewCND.DataSource = bindingSource; }
为什么CellFormatting不适合你的场景?
再强调一下:CellFormatting的设计目的是将底层数据转换为友好的显示格式,比如把日期转换为"yyyy-MM-dd"字符串、把数字转换为货币格式等。它不会修改绑定的数据源,所以当你执行更新操作时,程序依然会使用DataTable中的原始数据。
内容的提问来源于stack exchange,提问作者A. Petit
相关产品推荐
相关产品推荐

