I need to keep track of the selected item on a ListBox to update/disable other controls according to the currently selected value.
This is the code to reproduce the issue:
public partial class Form1 : Form
{
private readonly BindingList<string> List = new BindingList<string>();
public Form1()
{
InitializeComponent();
listBox1.DataSource = List;
listBox1.SelectedValueChanged += (s, e) => System.Diagnostics.Debug.WriteLine("VALUE");
listBox1.SelectedIndexChanged += (s, e) => System.Diagnostics.Debug.WriteLine("INDEX");
addButton.Click += (s, e) => List.Add("Item " + (List.Count + 1));
removeButton.Click += (s, e) => List.RemoveAt(List.Count - 1);
logSelectionButton.Click += (s, e) =>
{
System.Diagnostics.Debug.WriteLine("Selected Index: " + listBox1.SelectedIndex);
System.Diagnostics.Debug.WriteLine("Selected Value: " + listBox1.SelectedValue);
};
}
}
My form has a list box listBox1
and three buttons: addButton
, removeButton
and logSelectionButton
.
If you press addButton
(starting with an empty list), then removeButton
and finally addButton
again, neither SelectedValueChanged
nor SelectedIndexChanged
will fire at the last addButton
press, even though if you press logSelectionButton
before and after the last addButton
press, you'll see that the values of both SelectedIndex
and SelectedValue
have changed from -1 to 0 and from null
to "Item 1" respectively, and that "Item 1" looks selected on the list box.
This would cause any other controls I need to update according to the selected item to stay disabled until the user manually selects an item on the list box, even though the first item is already selected.
I can't think of any workaround. Perhaps also subscribing to my BindingList's ListChanged
event to see whether the list is empty or not, but then I don't know if the items in the list box will be updated before or after my event handler fires, which will cause other problems.
Seems like you found a bug in ListControl
internal handling of the PositionChanged
event when data bound (if you turn Exceptions on in VS, you'll see an exception when the first item is added to the empty list).
Since ListControl
derived classes like ListBox
, ComboBox
etc. in data bound mode synchronize their selection with the Position
property of the BindingManagerBase
, the reliable workaround (and basically a more general abstract solution) is to handle CurrentChanged
event of the underlying data source binding manager:
listBox1.BindingContext[List].CurrentChanged += (s, e) =>
System.Diagnostics.Debug.WriteLine("CURRENT");
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