如何更新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
相关产品推荐
相关产品推荐

