更改DataSource后,ComboBox会记住SelectedIndex

时间:2014-03-14 19:18:35

标签: c# winforms combobox

背景

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

  1. DataSource属性设置为新对象会将SelectedIndex值设置为0
  2. DataSource属性设置为以前使用的对象"记住"之前的SelectedIndex
  3. 以下是一些示例代码来说明这一点:

    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);
        }
    

    这会产生以下输出:

    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
    

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

    问题

    这怎么可能,反正是为了防止这种行为?

    是ComboBox"内存"无限期,或者是否受到易受垃圾收集影响的对象的支持?前一种情况意味着调整DataSource导致内存消耗,后一种情况表明ComboBox的行为在设置DataSource时是不可预测的。

1 个答案:

答案 0 :(得分:2)

我不知道DataSource对象的所有内部工作方式,但可能是ComboBox保留列表的关联CurrencyManager信息,以便在重新连接DataSource时记住以前的位置

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

comboBox.DataSource = new BindingSource(list1, null);

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