如何更新DataGridView单元格值?绑定DataView后修改不显示求助
问题解决:DataGridView绑定DataView后手动修改单元格值不显示
核心原因
DataGridView与DataView是双向绑定关系,控件会自动从数据源同步值。你直接修改row.Cells[4].Value后,控件的绑定机制会再次从DataView拉取数据,覆盖手动设置的值;另外如果第4列绑定了DataView中的字段,控件会优先使用数据源的值,导致自定义内容无法显示。
解决方案
提供两种可靠实现方式,按需选择:
方式1:利用CellFormatting事件动态渲染单元格(仅显示,不修改数据源)
该方法在单元格每次渲染时触发,直接设置显示值,不会被数据源覆盖,适合仅需展示额外数据的场景。
修改InitData方法
private DataView _dvMarket; public void InitData(DataView dvMarket) { _dvMarket = dvMarket; dgvMarket.DataSource = null; dgvMarket.AutoGenerateColumns = false; // 确保第4列不绑定数据源字段(若原本有绑定,清空DataPropertyName) dgvMarket.Columns[4].DataPropertyName = string.Empty; dgvMarket.DataSource = _dvMarket; // 注册CellFormatting事件(避免重复注册) dgvMarket.CellFormatting -= DgvMarket_CellFormatting; dgvMarket.CellFormatting += DgvMarket_CellFormatting; }
实现CellFormatting事件处理方法
private void DgvMarket_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) { // 仅处理目标列(索引为4),排除表头行 if (e.ColumnIndex == 4 && e.RowIndex >= 0) { DataRowView rowView = dgvMarket.Rows[e.RowIndex].DataBoundItem as DataRowView; if (rowView == null) return; // 从数据源取ID(建议直接用字段名,比如rowView["ID"].ToString(),比索引更可靠) string ID = rowView.Row[2].ToString(); DataRow drData = Handler.GetRowInfo(ID); string mark = ""; if (drData != null) { string isMark = drData["is_mark"].ToString(); // 忽略大小写判断 mark = isMark.Equals("False", StringComparison.OrdinalIgnoreCase) ? "yes" : "no"; } // 设置单元格显示值 e.Value = mark; // 标记已完成格式化,跳过默认数据源取值逻辑 e.FormattingApplied = true; } }
方式2:给DataView的DataTable添加内存列(同步到数据源)
如果需要额外值参与排序、筛选等操作,可以给DataTable添加一个内存计算列,无需修改数据库,绑定后控件会自动显示该列值。
修改InitData方法
private DataView _dvMarket; public void InitData(DataView dvMarket) { // 给DataTable添加内存列(仅在不存在时添加) if (!dvMarket.Table.Columns.Contains("Mark")) { dvMarket.Table.Columns.Add("Mark", typeof(string)); } // 循环给每一行赋值Mark列 foreach (DataRowView rowView in dvMarket) { string ID = rowView.Row[2].ToString(); DataRow drData = Handler.GetRowInfo(ID); string mark = ""; if (drData != null) { string isMark = drData["is_mark"].ToString(); mark = isMark.Equals("False", StringComparison.OrdinalIgnoreCase) ? "yes" : "no"; } rowView["Mark"] = mark; } _dvMarket = dvMarket; dgvMarket.DataSource = null; dgvMarket.AutoGenerateColumns = false; // 将第4列绑定到新增的Mark列 dgvMarket.Columns[4].DataPropertyName = "Mark"; dgvMarket.DataSource = _dvMarket; }
原代码问题说明
- 绑定DataView后循环修改单元格值,会被控件的绑定同步机制覆盖;
- 使用
FormattedValue获取ID存在格式风险,直接从DataBoundItem取数据源值更可靠; - 循环内调用
dgvMarket.Refresh()无效,绑定同步是后台触发的。
内容的提问来源于stack exchange,提问作者sharon
相关产品推荐
相关产品推荐

