Alegro
Alegro

Reputation: 7956

Why changing SelectedItem in one Combo changes all other Combos?

I populated comboboxes in this way

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

But, problem is when I change SelectedItem in one Combo - it becomes changed in all other Combos?

Upvotes: 10

Views: 7214

Answers (3)

Hash
Hash

Reputation: 350

I faced the same problem but I was working with generics. I've used the binding context of the combo box to get rid of this. (Very useful when you don't know the size of the binding list - in your case it's 5 items)

In the below code DisplayBindItem is just a class with Key and 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";

The Class for you reference.

    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()
    { }
}

Please mark as answer if this solves your problem.

Upvotes: 6

cadrell0
cadrell0

Reputation: 17307

A better approach would be to use a DataView to avoid duplicating the data. Also, don't cast multiple times if it can be avoided.

foreach (Control c in this.Controls)
{
    ComboBox comboBox = c as ComboBox;

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

Edit

I just realized you can do this even cleaner with LINQ

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

Upvotes: 6

GrandMasterFlush
GrandMasterFlush

Reputation: 6409

Bind them each to a separate instance of the DataSet1.Table[0].

ie)

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

Upvotes: 16

Related Questions