You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinForms双DataGridView行刷新同步异常问题排查求助

WinForms DataGridView 同步刷新问题解决方案

问题根源分析

  1. 属性变更通知不完整:Product类的PropertyChanged事件未传递具体属性名称,导致BindingSource无法向所有关联的DataGridView行发送更新通知,仅当前选中/编辑的行能实时响应。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 07:10:55