Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ComboBox remembers SelectedIndex after changing DataSource

Background

Lately, I have observed two undesirable behaviors of the Winform ComboBox control:

  1. Setting the DataSource property to a new object sets the SelectedIndex value to 0
  2. Setting the DataSource property to a previously used object "remembers" the previously SelectedIndex 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.

like image 702
nicholas Avatar asked Mar 14 '14 19:03

nicholas


1 Answers

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).

like image 138
LarsTech Avatar answered Nov 13 '22 11:11

LarsTech