【问题标题】:ComboBoxes are linked (and that is bad)组合框是链接的(这很糟糕)
【发布时间】:2015-10-28 07:13:54
【问题描述】:

我正在做简单的 WinForms 应用程序,但遇到了一些奇怪的问题。

我的表格:

它非常简单:3 个组合框和两个按钮 - 确定和取消。

查看:

private void applyOrderButton_Click(object sender, EventArgs e)
    {
        List<string> testList = new List<string>()
        {
            "A",
            "B",
            "C"
        };

        comboBox1st.DataSource = testList;
        comboBox2nd.DataSource = testList;
        comboBox3rd.DataSource = testList;

        comboBox1st.SelectedIndex = 2;
        comboBox2nd.SelectedIndex = 1;
        comboBox3rd.SelectedIndex = 0;
        //Presenter.DoTest();
    }

校准方法applyOrderButton_Click() 后会发生什么(单击确定按钮后会发生)我所有的组合框都更改了选定位置。但是,这些组合框中的每一个都具有相同的选定索引 - 在这种特殊情况下,它将是“A”。

然后,我使用光标更改更改组合框 selectedIndex(例如,我选择第三个组合框以显示“C”)对所有三个组合框执行更改。我做错了什么?

【问题讨论】:

  • 所有三个盒子共享同一个源,实际上是同一个实例。列表中的当前位置由枚举器的当前元素控制。如果你改变它,它就会到处改变..

标签: c# winforms combobox


【解决方案1】:

您正在遇到一个存在于 WinForms 后台的东西,称为“CurrencyManager”。

它的工作是在所有引用相同数据源的可绑定控件之间同步“当前记录”。

例如,如果您添加了一个标签并将其绑定到同一个列表,并绑定它以显示其中一个对象的属性,那么它将始终显示您在其中选择的同一对象的属性值组合框。

这样做的一个好处是,您可以轻松地添加一个表单来编辑对象列表、将文本框等绑定到其中一个对象的属性,并添加一个允许您移动到下一行或上一行的导航器。您不必手动确保所有文本框都引用正确的对象,CurrencyManager 会为您完成这一切。

但是,在您的情况下,由于您将相同的数据源绑定到所有三个组合框,因此 CurrencyManager 将确保所有三个组合框都选择同一行。如果您在其中一个组合框中选择新行,CurrencyManager 将修复所有其他组合框以引用同一行。

您可以通过多种方式解决此问题:

  1. 您可以覆盖每个组合框的绑定上下文:

    comboBox2nd.BindingContext = new BindingContext();
    comboBox3rd.BindingContext = new BindingContext();
    

    请注意,如果您走这条路线,则需要在分配 SelectedIndex 或 SelectedItem 属性之前执行此操作,否则 CurrencyManager 将在您分配新的 BindingContext 之前更新其他两个组合框。

  2. 您可以为每个组合框分配不同的数据源:

    combobox2nd.DataSource = testList.ToList();
    combobox3rd.DataSource = testList.ToList();
    

【讨论】:

    【解决方案2】:

    只需像这样将新上下文分配给其他组合框:

    List<string> testList = new List<string>()
        {
            "A",
            "B",
            "C"
        };
    
    comboBox1st.DataSource = testList;
    
    comboBox2nd.BindingContext = new BindingContext();
    comboBox2nd.DataSource = testList;
    
    comboBox3rd.BindingContext = new BindingContext();
    comboBox3rd.DataSource = testList;
    
    comboBox1st.SelectedIndex = 2;
    comboBox2nd.SelectedIndex = 1;
    comboBox3rd.SelectedIndex = 0;
    

    CurrencyManager 用于保持数据绑定控件彼此同步(显示来自同一记录的数据)。 CurrencyManager 对象通过管理由数据源提供的绑定数据的集合来实现此目的。对于与 Windows 窗体关联的每个数据源,窗体至少维护一个 CurrencyManager。因为可能有多个数据源与一个表单相关联,所以 BindingContext 对象管理任何特定表单的所有 CurrencyManager 对象。更广泛地说,所有容器控件都至少有一个 BindingContext 对象来管理它们的 CurrencyManager。

    【讨论】:

      猜你喜欢
      • 2011-09-24
      • 2015-08-18
      • 1970-01-01
      • 2011-10-06
      • 2011-10-10
      • 1970-01-01
      • 2011-05-23
      • 2010-10-30
      • 1970-01-01
      相关资源
      最近更新 更多