为何ListBox与ComboBox会自动关联同步选中项?
我有一个包含ListBox和ComboBox的窗体,二者通过.DataSource属性绑定同一个数组来填充数据,代码如下:
public partial class Form1 : Form { static readonly Random rng = new Random(); public Form1() { InitializeComponent(); } protected override void OnLoad(EventArgs e) { base.OnLoad(e); int[] list = Enumerable.Range(0, 20).Select((i) => rng.Next(501)).ToArray(); listBox1.DataSource = list; comboBox1.DataSource = list; } }
窗体未添加其他代码,但运行时选中ListBox中的项,ComboBox会自动选中同一项,反之亦然。请问这种自动关联的机制是什么?ComboBox如何接收ListBox操作触发的数据绑定更新或事件?
这种自动关联的核心是WinForms数据绑定中的CurrencyManager(货币管理器),具体逻辑如下:
共享数据源的控件会复用同一个
CurrencyManager
当你给ListBox或ComboBox设置.DataSource时,控件会从所在窗体的BindingContext中,获取对应数据源的CurrencyManager实例。由于两个控件绑定的是同一个数组对象,它们会共享同一个CurrencyManager实例。CurrencyManager负责跟踪当前选中项CurrencyManager的核心作用是维护绑定数据源的“当前选中位置”,通过Position属性记录选中项的索引。当任意一个绑定控件修改选中状态时,本质是修改了CurrencyManager的Position值。事件通知实现跨控件同步
CurrencyManager内部维护了事件触发机制:当Position属性发生变化时,会触发PositionChanged事件。所有绑定到该CurrencyManager的控件都会监听这个事件,一旦收到通知,就会根据新的Position值更新自身的选中项,从而实现ListBox和ComboBox的选中状态自动联动。
简言之,两个控件并没有直接互相监听事件,而是通过共享的CurrencyManager作为中间协调者,完成了选中状态的同步。
内容的提问来源于stack exchange,提问作者John Alexiou

