WinForms双DataGridView行刷新同步异常问题排查求助
WinForms DataGridView 同步刷新问题解决方案
问题根源分析
- 属性变更通知不完整:
Product类的PropertyChanged事件未传递具体属性名称,导致BindingSource无法向所有关联的DataGridView行发送更新通知,仅当前选中/编辑的行能实时响应。 - UI与数据模型脱节:直接操作
DataGridViewCheckBoxCell的状态而非数据模型,导致非选中行的UI无法自动同步底层值的变化。
具体解决方案
1. 修复Product类的属性变更通知实现
确保属性变更时传递正确的属性名称,让BindingSource精准通知所有关联控件更新:
using System.ComponentModel; using System.Runtime.CompilerServices; public class Product : INotifyPropertyChanged { public string Code { get; set; } public string Name { get; set; } private int quantity; public int Quantity { get => quantity; set { if (quantity != value) { quantity = value; OnPropertyChanged(); // 若Amount是计算属性,可在此触发其变更通知(如果Amount是Product成员) // OnPropertyChanged(nameof(Amount)); } } } private bool isSelected; public bool IsSelected { get => isSelected; set { if (isSelected != value) { isSelected = value; OnPropertyChanged(); } } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
2. 将复选框列绑定到数据模型
把DataGridView1的复选框列与Product.IsSelected属性绑定,而非使用非绑定列:
- 在设计器中选中DataGridView1的复选框列,设置
DataPropertyName为IsSelected。 - 移除代码中直接操作单元格的逻辑,改为通过修改数据模型控制选中状态。
3. 优化集合类型与添加按钮逻辑
将ProductCollection改为继承BindingList<Product>(自带集合变更通知能力),同时修改添加按钮代码操作数据模型而非UI控件:
public class ProductCollection : BindingList<Product> { } // 添加按钮点击事件代码 private void AddProductsButton_Click(sender, EventArgs e) { var selectedProducts = bs1.Cast<Product>().Where(p => p.IsSelected).ToList(); foreach (var product in selectedProducts) { bs2.Add(product); product.IsSelected = false; // 修改模型触发UI自动刷新 } }
额外优化建议
- 如果Amount是计算列(非
Product类属性),可通过CellFormatting事件实时计算显示:
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) { if (e.ColumnIndex == dataGridView1.Columns["Amount"].Index && e.RowIndex >= 0) { var product = dataGridView1.Rows[e.RowIndex].DataBoundItem as Product; if (product != null) { // 替换为实际单价获取逻辑 decimal unitPrice = GetUnitPrice(product.Code); e.Value = product.Quantity * unitPrice; } } }
- 若仍存在局部刷新延迟,可在属性变更后调用
BindingSource.ResetItem()强制刷新指定项:
var index = bs1.IndexOf(targetProduct); if (index >= 0) bs1.ResetItem(index);
内容的提问来源于stack exchange,提问作者Santhosh Shanmugam
相关产品推荐
相关产品推荐

