ComboBox记住更改数据源后的SelectedIndex

nic*_*las 5 c# combobox winforms

背景

最近,我观察到Winform ComboBox控件的两个不良行为:

  1. DataSource属性设置为新对象会将SelectedIndex值设置为0
  2. DataSource属性设置为先前使用的对象可以“记住”先前的SelectedIndex

下面是一些示例代码来说明这一点:

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);
    }
Run Code Online (Sandbox Code Playgroud)

这将产生以下输出:

设置数据源:list1
数据源已更改,SelectedIndex:-1
所选索引已更改,SelectedIndex:0
设置SelectedIndex = 1
所选索引已更改,SelectedIndex:1
设置数据源:list2
数据源已更改,SelectedIndex:1
所选索引已更改,SelectedIndex:0
设置SelectedIndex = 2
选定索引已更改,选定索引:2
设置数据源:list1
数据源已更改,SelectedIndex:2
所选索引已更改,SelectedIndex:1

这最后一个调试语句特别有趣。

问题

这怎么可能,并且有什么方法可以防止这种行为?

ComboBox的“内存”是不确定的,还是容易受到垃圾回收的对象支持?前一种情况意味着调整DataSource会导致内存消耗,后一种情况表明在设置DataSource时ComboBox的行为不可预测。

Lar*_*ech 2

我不知道 DataSource 对象的所有内部工作原理,但可能是 ComboBox 保留了列表的关联CurrencyManager 信息,使其能够在 DataSource 重新连接时记住先前的位置。

您可以通过将列表包装在新的 BindingSource 对象中来避免此行为:

comboBox.DataSource = new BindingSource(list1, null);
Run Code Online (Sandbox Code Playgroud)

这会将位置属性默认设置为零(如果有记录)。