如何检测项是否添加到ListBox(或CheckedListBox)控件

这似乎是一个基本上简单的问题。 我有一个带有列表框的WinForms对话框。 此控件不是通过数据绑定填充,而是通过调用填充

listBox.Items.Add (obj); 

这个调用可能是从各个地方异步进行的,我想挂钩列表框并观察其数据成员的变化,以便我可以执行其他UI更改(例如启用或禁用与列表框交互的控件)关于列表中的项目数)。

不幸的是,除非我完全无能为力,否则似乎没有一个事件或虚拟方法可以被钩住来检测这个。 我可以挂钩选择更改和(对于CheckedListBox)我可以挂钩检查状态更改。 但不是对基础数据集的更改。

我知道这在Win32中是可能的(有一个窗口消息)。 我错过了什么?


[西蒙编辑]

我被指向正确的解决方案(我已经标记为已接受的答案),它将覆盖ListBox的WndProc方法并手动处理列表框消息。 这是我解决(并且有效)的解决方案。 可以对其进行修改以在事件中提供更多详细信息,或将消息拆分为单独的事件,但是对于我的需求,这已足够。

 using System; using System.Windows.Forms; public class CheckedListBoxEx : CheckedListBox { public CheckedListBoxEx() { } private const int LB_ADDSTRING = 0x180; private const int LB_INSERTSTRING = 0x181; private const int LB_DELETESTRING = 0x182; private const int LB_RESETCONTENT = 0x184; protected override void WndProc(ref Message m) { if (m.Msg == LB_ADDSTRING || m.Msg == LB_INSERTSTRING || m.Msg == LB_DELETESTRING || m.Msg == LB_RESETCONTENT) { ItemsChanged(this, EventArgs.Empty); } base.WndProc(ref m); } public event EventHandler ItemsChanged = delegate { }; } 

我不知道您可以观看任何事件以显示项目已添加到ListBox。 也许您可以使用您描述的Win32方法(即抓住句柄,使用WndProc等)。

或者,也许您可​​以使用另一个添加项目的类。 例如,您可以让用户操作在新类中调用Add方法,然后将该项添加到ListBox,而不是直接在ListBox上调用Add方法。 您可以在该类中设置一个事件,以便您可以查看已添加的内容。

我也喜欢像另一张海报所提到的inheritanceListBox的想法….

这是另一个论坛上的post,建议创建一个包含该行为的子类。

http://www.eggheadcafe.com/forumarchives/netframeworkcompactframework/jul2005/post23265940.asp

这个解决方案似乎有效 – 在我的情况下,我在VB中实现了它。 我刚刚创建了一个ExtendedListbox类,它inheritance了listbox控件,实现了INotifyPropertyChanged并隐藏了Items Property。

 Imports System.ComponentModel Public Class ExtendedListBox:Inherits ListBox:Implements INotifyPropertyChanged Public Shadows Property Items() As ObjectCollection Get RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Items")) Return MyBase.Items End Get Set(value As ObjectCollection) RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Items")) MyBase.Items.Clear() For Each o As Object In value MyBase.Items.Add(o) Next End Set End Property Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged End Class 

不幸的是,使用inheritance或事件没有简单的方法。 您应该能够覆盖Items类的Add方法,但是您无法实现它! 您可以拦截消息循环以确定何时发生这种情况,但这超出了我的经验。

我从你的问题中注意到的一件事是你提到的项目是异步添加的。 不要那样做。 如果您在表单的线程上同步(如果您的问题是控件没有更新),您的问题可能会得到解决。