如何在DataGridView中实现ComboBox单元格值变更时联动修改其他单元格值
在DataGridView中实现ComboBox单元格联动修改另一单元格的值
需求说明
当DataGridView里的「producto」列(ComboBox类型单元格)选项发生变化时,自动从数据库查询对应产品的价格,同步填充到同一行的「precio」列中。
原代码的问题分析
你的现有代码存在几个关键问题需要修正:
sender在CellValueChanged事件中是DataGridView对象,不是DataGridViewComboBoxCell,直接强制转换会引发空引用错误- SQL命令的初始化顺序有误:先添加参数再实例化
SqlCommand,导致参数没有绑定到正确的命令实例上 - 未判断行/列索引的有效性,表头行触发事件时会抛出异常
- 数据库资源(连接、命令、适配器)没有正确释放,可能造成连接泄漏
修正后的完整代码
private void DgvDetalleVta_CellValueChanged(object sender, DataGridViewCellEventArgs e) { // 1. 先验证行/列索引有效性,确保是目标列(producto列) if (e.RowIndex < 0 || e.ColumnIndex < 0) return; DataGridView dgv = sender as DataGridView; if (dgv.Columns[e.ColumnIndex].Name != "producto") return; // 2. 获取ComboBox单元格的选中值 DataGridViewComboBoxCell cbCell = dgv.Rows[e.RowIndex].Cells[e.ColumnIndex] as DataGridViewComboBoxCell; if (cbCell?.Value == null) return; string productoNombre = cbCell.Value.ToString(); // 3. 查询数据库获取对应价格,用using确保资源自动释放 DataTable precioTabla = new DataTable(); // 替换为你的数据库连接字符串获取逻辑 using (SqlConnection conn = new SqlConnection(conexion.conexion.ConnectionString)) { string sqlQuery = "SELECT Precio FROM Producto WHERE Nombre = @Nombre"; using (SqlCommand command = new SqlCommand(sqlQuery, conn)) { // 参数化查询,防止SQL注入 command.Parameters.AddWithValue("@Nombre", productoNombre); conn.Open(); using (SqlDataAdapter adaptador = new SqlDataAdapter(command)) { adaptador.Fill(precioTabla); } } } // 4. 将查询到的价格赋值给precio列 if (precioTabla.Rows.Count > 0) { dgv.Rows[e.RowIndex].Cells["Column5"].Value = precioTabla.Rows[0]["Precio"].ToString(); } else { // 处理未查询到价格的场景 dgv.Rows[e.RowIndex].Cells["Column5"].Value = "0"; } }
关键注意点
- 有效性判断:先过滤表头行和非目标列,避免不必要的执行和异常
- 资源管理:用
using语句包裹数据库相关对象,确保资源自动释放,避免连接泄漏 - 安全防护:采用参数化查询替代直接字符串拼接,防止SQL注入风险
- 异常处理:可以根据实际需求添加
try-catch块,处理数据库连接失败、查询错误等异常情况 - 列名匹配:确保代码中的列名(
"producto"、"Column5")和你的DataGridView实际列名完全一致
内容的提问来源于stack exchange,提问作者Erick Vazquez
相关产品推荐
相关产品推荐

