Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ComboBox会在更改数据源后记住SelectedIndex_C#_Winforms_Combobox - Fatal编程技术网

C# ComboBox会在更改数据源后记住SelectedIndex

C# ComboBox会在更改数据源后记住SelectedIndex,c#,winforms,combobox,C#,Winforms,Combobox,背景 最近,我观察到WinformComboBox控件的两种不良行为: 将DataSource属性设置为新对象将SelectedIndex值设置为0 将DataSource属性设置为以前使用的对象会“记住”以前选择的索引值 下面是一些示例代码来说明这一点: private void Form_Load(object sender, EventArgs e) { string[] list1 = new string[] { "A", "B", "C" };

背景

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

  • DataSource
    属性设置为新对象将
    SelectedIndex
    值设置为0
  • DataSource
    属性设置为以前使用的对象会“记住”以前选择的索引值
  • 下面是一些示例代码来说明这一点:

    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 正在设置数据源:列表1 数据源已更改,已选择索引:-1 所选索引已更改,所选索引:0 设置SelectedIndex=1 所选索引已更改,所选索引:1 正在设置数据源:list2 数据源已更改,已选择索引:1 所选索引已更改,所选索引:0 设置SelectedIndex=2 所选索引已更改,所选索引:2 正在设置数据源:列表1 数据源已更改,已选择索引:2 所选索引已更改,所选索引:1 这是最后一条特别有趣的调试语句

    问题

    这是怎么可能的,有没有办法防止这种行为


    组合框的“内存”是不确定的,还是受易受垃圾收集影响的对象支持?前一种情况表示调整数据源会导致内存消耗,后一种情况表示在设置数据源时组合框的行为是不可预测的。

    我不知道数据源对象的所有内部工作方式,但可能是保存列表的相关CurrencyManager信息的组合框使其能够在重新连接数据源时记住以前的位置

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

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

    这将默认position属性返回到零(如果有记录)。

    我的猜测是ComboBox保留了相关的CurrencyManager信息,以便在重新连接它时,它可以获取以前的位置。要“杀死”它,请尝试使用
    comboBox.DataSource=newbindingsource(list1,null)
    @LarsTech,您的建议不起作用,但我确实注意到将
    DataSource
    设置为新的
    BindingSource
    可以防止出现“内存”(例如
    DataSource=newbindingsource{DataSource=list1}
    。如果你想把它写下来作为一个答案,我可能会接受它作为一个体面的解决办法。尽管如此,我仍然有兴趣了解默认行为的基础……你评论中的示例和我的示例基本相同。你确定我的示例不起作用吗?我误解了。我以为你设置
    DataSource
    对于新的
    BindingSource
    在传统赋值之间,它会修复它。现在我明白了,您的意思是始终使用
    BindingSource
    作为源。(此外,这种方法允许您通过设置
    位置
    属性来设置默认值:不支持-1除外)。