WinFormscombobox数据绑定陷阱

假设你正在做类似下面的事情

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 

所以现在我们有2个combobox绑定到该数组,并一切工作正常。 但是,当您更改一个combobox的值时,它会将两个combobox更改为您刚select的combobox。

现在,我知道数组总是以引用的方式传递(知道当我学习C:D时),但为什么combobox在一起变化呢? 我不相信combobox控件正在修改集合。

作为解决办法,不要达到预期/期望的function性

 ComboBox box = new ComboBox(); box.DataSource = myitems.ToArray(); 

这与在dotnet框架中build立数据绑定的方式有关,特别是BindingContext 。 在高层次上,这意味着如果你没有另外指定每个表单和表单的所有控件共享相同的BindingContext 。 当您设置DataSource属性时, ComboBox将使用BindingContext来获取包装列表的ConcurrenyMangagerConcurrenyManager跟踪列表中当前所选位置等事物。

当你设置第二个ComboBoxDataSource ,它将使用相同的BindingContext (表单),这将产生对上面用于设置数据绑定的相同ConcurrencyManager的引用。

要获得更详细的解释,请参阅BindingContext 。

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

我附上一个完整的例子。

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

如果你想更加迷惑自己,那么试着总是在构造函数中声明绑定。 这可能会导致一些真正好奇的错误,因此我总是在Load事件中绑定。

这可能只是一个错字,但在您提供的代码中,只有在设置数据源时才引用第一个combobox:

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

box2的数据源未设置。