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

如何更新DataGridView绑定List的循环逻辑以同步状态?

解决List绑定DataGridView后状态同步更新的问题

你现在的问题核心在于普通List<T>不支持数据变更通知,而且原有循环逻辑既绕了弯路(遍历DataGridView再反向查询List),还存在错误的数据源更新方式。下面给你一套完整的修正方案:

1. 替换数据源类型:用BindingList<Dados>代替普通List<Dados>

普通List<T>没有实现IBindingList接口,无法向DataGridView发送数据变更通知。换成BindingList<T>后,只要实体类实现了属性变更通知,DataGridView会自动同步更新。

修改初始化代码:

// 声明时改为BindingList
BindingList<Dados> SendMsg;

// 窗体加载时初始化
SendMsg = new BindingList<Dados>(GetDados());
gvSent.DataSource = SendMsg;

2. 让Dados类实现INotifyPropertyChanged接口

这一步是让属性变更时能触发通知,BindingList会把这个通知传递给DataGridView,实现实时更新:

public class Dados : INotifyPropertyChanged
{
    private string _status;
    
    public long MessageSentId { get; set; }

    public string Status
    {
        get => _status;
        set
        {
            if (_status != value)
            {
                _status = value;
                OnPropertyChanged(nameof(Status));
            }
        }
    }

    // 实现INotifyPropertyChanged接口
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    // 你的其他属性也建议按照这个模式实现,确保变更能被通知
}

3. 重构点击事件的循环逻辑

不需要遍历DataGridView再去查List,直接操作数据源集合即可,既高效又避免UI和数据源的耦合:

private void btnSend_Click(object sender, EventArgs e)
{
    // 收集需要更新的MessageSentId(如果是选中行更新,可直接遍历SelectedRows)
    var targetIds = new List<long>();
    foreach (DataGridViewRow row in gvSent.Rows)
    {
        if (row.Cells[0].Value != null && long.TryParse(row.Cells[0].Value.ToString(), out long id))
        {
            targetIds.Add(id);
        }
    }

    // 直接更新BindingList中的元素,无需重新绑定数据源
    foreach (var item in SendMsg.Where(s => targetIds.Contains(s.MessageSentId)))
    {
        item.Status = "S";
        MessageBox.Show(item.MessageSentId.ToString());
    }
}

如果你的需求是仅更新选中行,可以简化成:

private void btnSend_Click(object sender, EventArgs e)
{
    foreach (DataGridViewRow row in gvSent.SelectedRows)
    {
        if (row.Cells[0].Value != null && long.TryParse(row.Cells[0].Value.ToString(), out long id))
        {
            var targetItem = SendMsg.FirstOrDefault(s => s.MessageSentId == id);
            if (targetItem != null)
            {
                targetItem.Status = "S";
                MessageBox.Show(id.ToString());
            }
        }
    }
}

原有逻辑的问题说明

  • 普通List<T>没有变更通知机制,修改元素属性后DataGridView无法感知,自然不会更新。
  • 你使用的query.Update(...)如果是LINQ扩展方法(比如EF的),它返回的是受影响的行数而非更新后的集合,所以gvSent.DataSource = query是完全错误的,会导致数据源类型不匹配。
  • 遍历DataGridView再查询List的方式,既低效又容易出错(比如UI和数据源不同步时),正确的做法是直接操作数据源集合。

内容的提问来源于stack exchange,提问作者Will

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:09:42