Background
Lately, I have observed two undesirable behaviors of the Winform ComboBox
control:
DataSource
property to a new object sets the SelectedIndex
value to 0DataSource
property to a previously used object "remembers" the previously SelectedIndex
valueHere is some sample code to illustrate this:
private void Form_Load(object sender, EventArgs e)
{
string[] list1 = new string[] { "A", "B", "C" };
string[] list2 = new string[] { "D", "E", "F" };
Debug.Print("Setting Data Source: list1");
comboBox.DataSource = list1;
Debug.Print("Setting SelectedIndex = 1");
comboBox.SelectedIndex = 1;
Debug.Print("Setting Data Source: list2");
comboBox.DataSource = list2;
Debug.Print("Setting SelectedIndex = 2");
comboBox.SelectedIndex = 2;
Debug.Print("Setting Data Source: list1");
comboBox.DataSource = list1;
this.Close();
}
private void comboBox_SelectedIndexChanged(object sender, EventArgs e)
{
Debug.Print("Selected Index Changed, SelectedIndex: {0}", comboBox.SelectedIndex);
}
private void comboBox_DataSourceChanged(object sender, EventArgs e)
{
Debug.Print("Data Source Changed, SelectedIndex: {0}", comboBox.SelectedIndex);
}
This produces the following output:
Setting Data Source: list1 Data Source Changed, SelectedIndex: -1 Selected Index Changed, SelectedIndex: 0 Setting SelectedIndex = 1 Selected Index Changed, SelectedIndex: 1 Setting Data Source: list2 Data Source Changed, SelectedIndex: 1 Selected Index Changed, SelectedIndex: 0 Setting SelectedIndex = 2 Selected Index Changed, SelectedIndex: 2 Setting Data Source: list1 Data Source Changed, SelectedIndex: 2 Selected Index Changed, SelectedIndex: 1
It is this last debug statement that is particularly interesting.
Questions
How is this possible and is there anyway to prevent this behavior?
Is the ComboBox's "memory" indefinite, or is it supported by objects which are susceptible to garbage collection? The former case means adjusting DataSource results in memory consumption, the latter case indicates the ComboBox's behavior is not predictable when setting the DataSource.
I don't know all of the inner workings of the DataSource object, but it's probably the ComboBox keeping the associated CurrencyManager information for the list that allows it to remember the previous position when the DataSource gets reconnected.
You can avoid this behavior by wrapping the list inside a new BindingSource object:
comboBox.DataSource = new BindingSource(list1, null);
This will default the position property back to zero (if there are records).
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