C#--BindingList

BindingList<T> 的作用:

    • 自动数据绑定通知:当集合中的元素被添加、删除或修改时,会自动通知 UI 控件更新

    • 支持排序和搜索:实现了 IBindingList 接口,支持高级数据绑定功能

    • 支持属性更改通知:当集合中的元素属性变化时,也能通知 UI(需要结合 INotifyPropertyChanged)

在代码中的具体优势:

cs 复制代码
// 添加新记录时,DataGridView 会自动刷新
dataSource.Insert(insertIndex, newRecord);

// 修改计数时,UI 自动更新
existingRecord.Count = _value;

// 不需要手动调用 dataGridView.Refresh() 或 dataGridView.DataSource = null

对比普通 List:

cs 复制代码
// 如果用 List<T>,需要:
list.Add(newRecord);
dataGridView.DataSource = null;
dataGridView.DataSource = list; // 需要重新绑定

// 如果用 BindingList<T>:
bindingList.Add(newRecord); // 自动更新 UI
用了 BindingList 为什么还要用 INotifyPropertyChanged?
底层原理:
cs 复制代码
// 1. BindingList 的监听机制
public class BindingList<T> : Collection<T>, IBindingList, ICancelAddNew, IRaiseItemChangedEvents
{
    // 当添加/删除元素时,触发 ListChanged 事件
    protected override void InsertItem(int index, T item)
    {
        base.InsertItem(index, item);
        OnListChanged(new ListChangedEventArgs(ListChangedType.ItemAdded, index));
    }
    
    // 如果 T 实现了 INotifyPropertyChanged,会监听 PropertyChanged 事件
    private void HookPropertyChanged(T item)
    {
        if (item is INotifyPropertyChanged inpc)
        {
            inpc.PropertyChanged += new PropertyChangedEventHandler(Child_PropertyChanged);
        }
    }
}

// 2. DataGridView 的响应机制
// DataGridView 会订阅:
// - BindingList.ListChanged(集合变化)
// - 每个 TossingRecord.PropertyChanged(属性变化)

// 3. 完整的通知链条:
// 当 Count 变化时:
record.Count = 10;
    ↓
OnPropertyChanged("Count") 被调用
    ↓
PropertyChanged 事件触发
    ↓
BindingList 监听到事件
    ↓
BindingList 触发 ListChanged(ListChangedType.ItemChanged)
    ↓
DataGridView 收到通知
    ↓
DataGridView 更新对应单元格显示
为什么需要两者结合:
cs 复制代码
// 如果没有 INotifyPropertyChanged:
record.Count = 10; // DataGridView 不知道这个变化

// 有了 INotifyPropertyChanged:
record.Count = 10; // 触发 PropertyChanged → BindingList → DataGridView

使用 BindingSource 作为中介

cs 复制代码
public partial class TossingReport : UserControl
{
    private BindingList<TossingRecord> dataSource;
    private BindingSource bindingSource;
    
    public TossingReport()
    {
        dataSource = new BindingList<TossingRecord>();
        bindingSource = new BindingSource();
        bindingSource.DataSource = dataSource;
        dataGridView.DataSource = bindingSource;
        
        // 可以添加过滤、排序等功能
        bindingSource.Filter = "Count > 0";
        bindingSource.Sort = "Count DESC";
    }
}

总结对比:

相关推荐
福兮说3 分钟前
URL 编码的七个坑:c++ 传到后端变空格、%25 套娃、截断 emoji 直接报错
开发语言·前端·javascript·node.js·url
小的时候可菜了26 分钟前
JS 异步的本质:从单线程到 thenable(一条进化链)
开发语言·前端·javascript
可乐鸡翅yeah_34 分钟前
hls.js 配置 loadStartPosition,点播起始播放位置踩坑
开发语言·javascript·网络协议·ecmascript·m3u8在线
en.en..1 小时前
Linux 进程退出exit(函数)
java·开发语言·算法
Cx330❀1 小时前
【Qt 进阶指南】详解 Qt 常用标准对话框与主窗口组件架构
开发语言·qt·ui·性能优化·架构·图形渲染
Light Gao1 小时前
Encoder 与 Decoder 详解:从 Embedding 到 Seq2Seq 的完整数据流
java·开发语言·embedding
HZZD_HZZD1 小时前
弱网下CoAP还省吗?合众致达Cat.1电表90天实测:MQTT重连流量占52%、续航差距从38%拉大到73%
开发语言·物联网·php·腾讯云
web打印社区1 小时前
Windows 网页静默打印设置步骤:客户端、防火墙与联调清单
开发语言·前端·javascript·chrome·pdf·ecmascript
小师兄吃牛肉1 小时前
什么是R语言?如何快速学习R语言
开发语言·学习·r语言
Evand J1 小时前
【MATLAB例程】三维快速扩展随机树(RRT)路径规划与到达角(AOA)、到达时间差(TDOA)融合定位,附下载链接
开发语言·matlab·代码·定位·例程