【笔记】 WPF中CollectionChangedEventManager功能详细介绍

一、它是什么

  • CollectionChangedEventManager 是 WPF 提供的弱事件管理器(WeakEventManager 的特化),用于订阅实现了 INotifyCollectionChanged(例如 ObservableCollection)的 CollectionChanged 事件,而不会因为普通事件订阅的强引用导致内存泄漏。
  • 命名空间:System.Collections.Specialized;程序集:WindowsBase。

二、为何使用

  • 直接用 += 订阅时,发布者会强引用订阅者,长生命周期的集合可能"绑死"短生命周期对象,造成泄漏。
  • 使用弱事件后,管理器对监听方只保留弱引用:监听方被 GC 后,管理器会自动移除,不需要发布者手动 -=。

三、核心 API

  • AddHandler(INotifyCollectionChanged source, EventHandler handler)
  • RemoveHandler(INotifyCollectionChanged source, EventHandler handler)
  • 也支持 AddListener/RemoveListener 搭配 IWeakEventListener,但日常用 AddHandler/RemoveHandler 更简单。

四、工作原理(简化)

  • 第一次对某个 source 调用 AddHandler 时,管理器会用常规 += 订阅 source.CollectionChanged,并把"监听者"以弱引用存起来。
  • 当所有监听者都被移除或回收后,管理器会对该 source 做 -=,从而释放对 source 的强引用,不再阻止其被回收。

五、线程与 Dispatcher

  • WeakEventManager 是 Dispatcher 关联的,订阅和事件回调通常需在 UI 线程执行。
  • 如果集合可能在后台线程触发 CollectionChanged(不推荐),需要自行通过 Dispatcher 切回 UI 线程,或用 BindingOperations.EnableCollectionSynchronization 做跨线程同步。

六、常见注意点

  • 重复 AddHandler 会导致重复回调;确保 Add/Remove 成对或先 Remove 再 Add。
  • 弱事件不等于"完全不用移除"。如果监听者仍然存活,事件会一直回调;当你明确切换数据源或对象生命周期结束时,及时 RemoveHandler 更可控。
  • 闭包/lambda 订阅:AddHandler 存的仍是弱引用到委托目标(闭包对象),不会因此额外泄漏;但若外部还有强引用,监听者自然不会被回收。
  • 事件触发频繁时,弱事件有一点额外分派开销,但通常可以忽略。

七、适配场景

  • 视图/视模对共享集合的监听(视图先销毁,集合仍在);
  • 单例/全局管理对象监听多数据源;
  • 任意"发布者生命周期大于订阅者"的事件关系。

八、与 PropertyChangedEventManager 的区别

  • CollectionChangedEventManager 针对 INotifyCollectionChanged.CollectionChanged。
  • PropertyChangedEventManager 针对 INotifyPropertyChanged.PropertyChanged。
  • 用法与语义类似,分别用于"集合变化"和"属性变化"。

十、简单用法示例

  • 订阅:
csharp 复制代码
CollectionChangedEventManager.AddHandler(source, OnCollectionChanged);
  • 取消订阅:
csharp 复制代码
CollectionChangedEventManager.RemoveHandler(source, OnCollectionChanged);
  • 处理器:
csharp 复制代码
private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    // 根据 e.Action 处理 Add/Remove/Reset 等
}

总结

  • CollectionChangedEventManager 通过弱引用订阅 CollectionChanged,解决典型的事件导致的内存泄漏问题。

了解更多

CollectionChangedEventManager Class

WeakEventManager 类

PropertyChangedEventManager Class

System.Windows.Controls 命名空间 | Microsoft Learn

控件库 - WPF .NET Framework | Microsoft Learn

WPF 介绍 | Microsoft Learn

使用 Visual Studio 创建新应用教程 - WPF .NET | Microsoft Learn

https://github.com/HeBianGu

HeBianGu的个人空间-HeBianGu个人主页-哔哩哔哩视频

GitHub - HeBianGu/WPF-Control: WPF轻量控件和皮肤库

GitHub - HeBianGu/WPF-ControlBase: Wpf封装的自定义控件资源库

相关推荐
蒸蒸yyyyzwd32 分钟前
学习笔记 复盘
笔记·八股
旖旎夜光42 分钟前
【C++ 基础入门】命名空间、输入输出、缺省参数与函数重载
开发语言·c++·笔记·学习
一支蜉蝣4 小时前
Day26 XD安全学习笔记--PHP 应用&模版引用&Smarty渲染&MVC 模型&数据联动&RCE 安全
笔记·网络安全·html·php
東隅已逝,桑榆非晚4 小时前
算法3.双指针法-快乐数
c++·笔记·学习·算法
欢欢李4 小时前
【LTE L3 笔记 01】LTE空口特点
笔记·无线通信·物理层·lte·空口协议
ZZHow10245 小时前
神经网络与深度学习笔记_Day1
人工智能·pytorch·笔记·python·深度学习·神经网络·机器学习
ACP广源盛139246256736 小时前
选型笔记:HDMI2.1 四进一出切换中继方案 GSV6705@ACP 评估
笔记·硬件架构·硬件工程·视频·国产芯片
Z21-X6 小时前
云原生运维实战笔记:华为云存储类服务全景解析——EVS、OBS、SFS与CBR深度实践
运维·笔记·学习·云原生·华为云
1314lay_10076 小时前
ABAP 程序性能优化总结
经验分享·笔记·性能优化
浪扼飞舟7 小时前
WPF(控件的继承树、内容控件、布局控件)
wpf