代码之家  ›  专栏  ›  技术社区  ›  Darren Kopp

winforms组合框数据绑定gotcha

  •  47
  • Darren Kopp  · 技术社区  · 16 年前

    假设您正在执行以下操作

    List<string> myitems = new List<string>
    {
        "Item 1",
        "Item 2",
        "Item 3"
    };
    
    ComboBox box = new ComboBox();
    box.DataSource = myitems;
    
    ComboBox box2 = new ComboBox();
    box2.DataSource = myitems
    

    所以现在我们有两个组合框绑定到这个数组,并且一切都可以正常工作。但是,当您更改一个组合框的值时,它会将两个组合框都更改为您刚选择的组合框。

    现在,我知道数组总是通过引用传递的(当我学习c:d时就知道了),但是为什么组合框会一起改变呢?我不相信组合框控件正在修改集合。

    作为一个解决方案,这是否能够实现预期/期望的功能?

    ComboBox box = new ComboBox();
    box.DataSource = myitems.ToArray();
    
    3 回复  |  直到 5 年前
        1
  •  38
  •   Paul Fleming    12 年前

    这与如何在dotnet框架中设置数据绑定有关,尤其是 BindingContext . 在较高的层次上,这意味着如果没有另外指定,则每个表单和表单的所有控件共享相同的内容。 绑定上下文 . 当你设置 DataSource 财产 ComboBox 将使用 绑定上下文 得到一个 ConcurrenyMangager 这就把名单包装起来了。这个 ConcurrenyManager 跟踪列表中当前所选位置等内容。

    当你设置 数据来源 第二 组合框 它会用同样的 绑定上下文 (表格)将产生对该表格的引用。 ConcurrencyManager 如上所述,用于设置数据绑定。

    要获得更详细的解释,请参见 BindingContext .

        2
  •  20
  •   Paul Fleming    12 年前

    更好的解决方法(取决于数据源的大小)是声明两个 BindingSource 对象(从2.00开始是新的)将集合绑定到这些对象,然后将这些对象绑定到组合框。

    我附上一个完整的例子。

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication2
    {
        public partial class Form1 : Form
        {
            private BindingSource source1 = new BindingSource();
            private BindingSource source2 = new BindingSource();
    
            public Form1()
            {
                InitializeComponent();
                Load += new EventHandler(Form1Load);
            }
    
            void Form1Load(object sender, EventArgs e)
            {
                List<string> myitems = new List<string>
                {
                    "Item 1",
                    "Item 2",
                    "Item 3"
                };
    
                ComboBox box = new ComboBox();
                box.Bounds = new Rectangle(10, 10, 100, 50);
                source1.DataSource = myitems;
                box.DataSource = source1;
    
                ComboBox box2 = new ComboBox();
                box2.Bounds = new Rectangle(10, 80, 100, 50);
                source2.DataSource = myitems;
                box2.DataSource = source2;
    
                Controls.Add(box);
                Controls.Add(box2);
            }
        }
    }
    

    如果您想更加混淆自己,那么尝试总是在构造函数中声明绑定。这会导致一些 真的? 奇怪的错误,因此我总是在加载事件中绑定。

        3
  •  2
  •   Paul Fleming    12 年前

    这可能只是一个打字错误,但在您提供的代码中,在设置数据源时仅引用第一个组合框:

    ComboBox box = new ComboBox();
    box.DataSource = myitems;
    
    ComboBox box2 = new ComboBox();
    **box**.DataSource = myitems
    

    的数据源 box2 未设置。