This seems like a fundamentally simple question. I have a WinForms dialog box with a listbox. This control is not populated via data-binding but is filled with calls to
listBox.Items.Add (obj);
It is possible that this call can be made asynchronously from various places and I would like to hook the listbox and watch for changes in its data members so that I can perform other UI changes (such as enable or disable controls which interact with the listbox based on the number of items in the list).
Unfortunately, unless I'm being completely clueless, there does not seem to be an event or virtual method which can be hooked to detect this. I can hook for select changes and (for CheckedListBox) I can hook for check-state changes. But not for changes to the underlying data collection.
I know this is possible in Win32 (there is a window message for this). What am I missing?
[Edited by Simon]
I was pointed to the correct solution (which I have marked as the accepted answer) which is to override the WndProc method of the ListBox and handle the listbox messages manually. Here is the solution that I settled on (and works). It could be modified to provide more details in the event, or split the messages into separate events, but for my needs this is sufficient.
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 { }; }
To determine the items that are selected, you can use the Selected property of the list box. The Selected property of a list box is an array of values where each value is either True (if the item is selected) or False (if the item is not selected).
You can populate the list box items either from the properties window or at runtime. To add items to a ListBox, select the ListBox control and get to the properties window, for the properties of this control. Click the ellipses (...) button next to the Items property.
The Windows Forms CheckedListBox control extends the ListBox control. It does almost everything that a list box does and also can display a check mark next to items in the list. Other differences between the two controls are that checked list boxes only support DrawMode.
In Windows Forms, ListBox control is used to show multiple elements in a list, from which a user can select one or more elements and the elements are generally displayed in multiple columns. The ListBox class is used to represent the windows list box and also provide different types of properties, methods, and events.
I don't know of any event that you can watch to show that an item has been added to a ListBox. Perhaps you can use the Win32 method you described instead (i.e. grab a handle, use WndProc, etc.).
Alternately, perhaps you can use another class that adds items instead. For example, rather than calling the Add method on the ListBox directly, you could have user-actions call the Add method inside the new class which then adds the item to the ListBox. You could set an event inside that class that would allow you to watch what's been added.
I also like the idea of subclassing the ListBox as mentioned by another poster....
Here's a post on another forum that recommends creating a child class that includes that behaviour.
http://www.eggheadcafe.com/forumarchives/netframeworkcompactframework/jul2005/post23265940.asp
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With