Background
Lately, I have observed two undesirable behaviors of the Winform ComboBox
control:
- Setting the
DataSource
property to a new object sets theSelectedIndex
value to 0 - Setting the
DataSource
property to a previously used object "remembers" the previouslySelectedIndex
value
Here 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:
This will default the position property back to zero (if there are records).