【问题标题】:ComboBox remembers SelectedIndex after changing DataSourceComboBox 在更改 DataSource 后记住 SelectedIndex
【发布时间】:2014-03-14 19:18:35
【问题描述】:

背景

最近,我观察到 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);
    }

这会产生以下输出:

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

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

问题

这怎么可能?有没有办法阻止这种行为?

ComboBox 的“内存”是无限期的,还是受到易受垃圾回收影响的对象的支持?前一种情况表示调整DataSource会导致内存消耗,后一种情况表示设置DataSource时ComboBox的行为是不可预测的。

【问题讨论】:

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

标签: c# winforms combobox


【解决方案1】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 2011-11-14
    • 1970-01-01
    • 2018-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多