繁体   English   中英

WinForms ComboBox 数据绑定问题

[英]WinForms ComboBox data binding gotcha

假设您正在执行以下操作

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 个组合框绑定到该数组,一切正常。 但是当您更改一个组合框的值时,它会将两个组合框更改为您刚刚选择的组合框。

现在,我知道数组总是通过引用传递(在我学习 C :D 时了解到这一点),但是为什么组合框会一起改变? 我不相信组合框控件正在修改集合。

作为一种解决方法,这不会实现预期/所需的功能

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

这与如何在 dotnet 框架中设置数据绑定有关,尤其是BindingContext 在高层次上,这意味着如果您没有另外指定每个表单和表单的所有控件共享相同的BindingContext 当您设置DataSource属性时, ComboBox将使用BindingContext来获取包装列表的ConcurrenyMangager ConcurrenyManager会跟踪诸如列表中当前选择的位置之类的事情。

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

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

更好的解决方法(取决于数据源的大小)是声明两个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);
        }
    }
}

如果您想让自己更加困惑,请尝试始终在构造函数中声明绑定。 这可能会导致一些非常奇怪的错误,因此我总是在 Load 事件中绑定。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM