为什么更改一个组合框中的SelectedItem会更改所有其他组合框?

9
我用以下方式填充了组合框:
foreach (Control c in this.Controls)
{
     if (c is ComboBox)
     {
         (c as ComboBox).DataSource = DataSet1.Tables[0];
         (c as ComboBox).DisplayMember = "Articles";
     }
}

但问题是,当我更改一个组合框中的选定项时,所有其他组合框中的选定项也会被更改?
3个回答

15

将它们分别绑定到 DataSet1.Table[0] 的不同实例上。

例如:

foreach (Control c in this.Controls)
{
    if (c is ComboBox)
    {
        DataTable dtTemp = DataSet1.Tables[0].Copy();
        (c as ComboBox).DataSource = dtTemp 
        (c as ComboBox).DisplayMember = "Articles";
    }
}

谢谢大师。问题已解决。 - Alegro
1
根据您的ComboBoxes数量和DataTable中的数据量,这可能会导致应用程序内存占用量大量增加,因为存在数据重复。 - cadrell0
@cadrell0 - 很好的观点,我没有考虑到这一点,并且假设它只适用于几个组合框。 - GrandMasterFlush
1
以下答案 link 表明不需要额外的内存。 cmbApprover1.BindingContext = new BindingContext(); - Behzad Ebrahimi

6
更好的做法是使用DataView来避免数据重复。此外,如果可以避免,不要多次转换类型。
foreach (Control c in this.Controls)
{
    ComboBox comboBox = c as ComboBox;

    if (comboBox != null)
    {        
        comboBox.DataSource = new DataView(DataSet1.Tables[0]);
        comboBox.DisplayMember = "Articles";
    }
}

编辑

我刚刚意识到你可以使用LINQ更加简洁地完成这个操作。

foreach (ComboBox comboBox in this.Controls.OfType<ComboBox>())
{
    comboBox.DataSource = new DataView(DataSet1.Tables[0]);
    comboBox.DisplayMember = "Articles";
}

这是一种更好的做法。采用被接受的答案会占用更大的内存空间。 - SQLMason

5

我遇到了相同的问题,但是我正在使用泛型。我使用了组合框的绑定上下文来解决这个问题。(在你不知道绑定列表大小的情况下非常有用 - 在你的情况下只有5个项目)

在下面的代码中,DisplayBindItem只是一个具有Key和Value的类。

    List<DisplayBindItem> cust = (from x in _db.m01_customers
            where x.m01_customer_type == CustomerType.Member.GetHashCode()
            select new DisplayBindItem
            {
                Key = x.m01_id.ToString(),
                Value = x.m01_customer_name
            }).ToList();

    cmbApprover1.BindingContext = new BindingContext();
    cmbApprover1.DataSource = cust;
    cmbApprover1.DisplayMember = "Value";
    cmbApprover1.ValueMember = "Key";

    //This does the trick :)
    cmbApprover2.BindingContext = new BindingContext();
    cmbApprover2.DataSource = cust ;
    cmbApprover2.DisplayMember = "Value";
    cmbApprover2.ValueMember = "Key";

以下是您可以参考的类。

    public class DisplayBindItem
    {
        private string key = string.Empty;

    public string Key
    {
        get { return key; }
        set { key = value; }
    }
    private string value = string.Empty;

    public string Value
    {
        get { return this.value; }
        set { this.value = value; }
    }

    public DisplayBindItem(string k, string val)
    {
        this.key = k;
        this.value = val;
    }

    public DisplayBindItem()
    { }
}

如果这个解决了你的问题,请标记为答案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接