Question Select, Add and Remove items from comboBoxes

Gigy

New member
Joined
Oct 22, 2013
Messages
2
Programming Experience
Beginner
Hi,
I have four comboBoxes which all need to be filled with 7 items once the form loads. Also, a default selection will be assigned as a default setting. (See below my code).
What I want to do is that whenever I need to select an item from one comboBox, all other three comboBoxes should not contain that item, but instead they should have all other 6 remaining items. The code runs just fine, but it doesn?t give the required 100% required output / result. Hope you can run the code and try to change the selection multiple times to get a clear idea about the problem.
Of course, I don?t need a case of duplication of selecting an item. Means that if I selected for example the items ?Name? from comboBox 4 instead of comboBox2, then comboBox2 should not show ?Name? as selected option but instead it will show all other remaining 6 items with non selected item. I might here assign a default value like ?_select_? and for this I will give selected index= -1 (means, TextBox will not display ?_select_? as an selected item.
For this, I might need to loop/iterate through all the comboBoxes. What if I need to do the following?
I want to declare a list to add all the four comboBoxes in, and then pass this list as a parameter to a function. This function will take also the comboBox that I?m going to change the selected item from and give it to another comboBox. This way, I will be able to loop/through all my four comboBoxes to remove and/or add items to populate them all each time with the same number of items. Only then, I can do changing of the current selection of items from each comboBox without duplication and a case where one or more of the comboBoxes might got empty of items will not occur.
Here is my code:
    public partial class Form1 : Form
    {
        string[] Items = { "Customer ID", "Name", "Age", "Gender", "Address1", "Address2", "Country" };
        bool[] allowEdit = { false, false, false, false };
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            LoadDefault();
        }

        private void LoadDefault()
        {
            comboBox1.Items.AddRange(Items);
            comboBox2.Items.AddRange(Items);
            comboBox3.Items.AddRange(Items);
            comboBox4.Items.AddRange(Items);
            comboBox1.SelectedIndex = 0;
            comboBox2.SelectedIndex = 1;
            comboBox3.SelectedIndex = 2;
            comboBox4.SelectedIndex = 3;
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            textBox1.Text = comboBox1.Text + " , " + comboBox2.Text + " , " + comboBox3.Text + " , " + comboBox4.Text;
        }
 
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (allowEdit[0])
            {
                string selectedItem = comboBox1.SelectedItem.ToString();
                comboBox2.Items.Remove(selectedItem);
                comboBox3.Items.Remove(selectedItem);
                comboBox4.Items.Remove(selectedItem);
            }
        }
        private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (allowEdit[1])
            {
                string selectedItem = comboBox2.SelectedItem.ToString();
                comboBox1.Items.Remove(selectedItem);
                comboBox3.Items.Remove(selectedItem);
                comboBox4.Items.Remove(selectedItem);
            }
        }
        private void comboBox3_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (allowEdit[2])
            {
                string selectedItem = comboBox3.SelectedItem.ToString();
                comboBox1.Items.Remove(selectedItem);
                comboBox2.Items.Remove(selectedItem);
                comboBox4.Items.Remove(selectedItem);
                
            }
        }
        private void comboBox4_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (allowEdit[3])
            {
                string selectedItem = comboBox4.SelectedItem.ToString();
                comboBox1.Items.Remove(selectedItem);
                comboBox2.Items.Remove(selectedItem);
                comboBox3.Items.Remove(selectedItem);
                
            }
        }
 
        private void comboBox1_MouseEnter(object sender, EventArgs e)
        {
            allowEdit[0] = true;
        }
        private void comboBox1_MouseLeave(object sender, EventArgs e)
        {
            allowEdit[0] = false;
        }
        private void comboBox2_MouseEnter(object sender, EventArgs e)
        {
            allowEdit[1] = true;
        }
        private void comboBox2_MouseLeave(object sender, EventArgs e)
        {
            allowEdit[1] = false;
        }
        private void comboBox3_MouseEnter(object sender, EventArgs e)
        {
            allowEdit[2] = true;
        }
        private void comboBox3_MouseLeave(object sender, EventArgs e)
        {
            allowEdit[2] = false;
        }
        private void comboBox4_MouseEnter(object sender, EventArgs e)
        {
            allowEdit[3] = true;
        }
        private void comboBox4_MouseLeave(object sender, EventArgs e)
        {
            allowEdit[3] = false;
        }
 
Last edited by a moderator:
This is a perfect example of a situation where you should write generic code that will work for all four ComboBoxes. I tested this code and it worked as expected with all four ComboBoxes having their SelectedIndexChanged event handled by the same comboBox_SelectedIndexChanged method:
private string[] allItems = { "first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eighth" };

private ComboBox[] comboBoxes;

private bool ignoreChanges;

private void Form1_Load(object sender, EventArgs e)
{
    this.comboBoxes = new[] { this.comboBox1, this.comboBox2, this.comboBox3, this.comboBox4 };

    foreach (var comboBox in this.comboBoxes)
    {
        comboBox.Items.AddRange(this.allItems);
    }

    this.comboBox1.SelectedItem = "second";
    this.comboBox2.SelectedItem = "seventh";
    this.comboBox3.SelectedItem = "fifth";
    this.comboBox4.SelectedItem = "first";
}

private void comboBox_SelectedIndexChanged(object sender, EventArgs e)
{
    if (!this.ignoreChanges)
    {
        // Ignore SelectedIndexChanged events while we make the updates.
        this.ignoreChanges = true;

        foreach (var comboBox in this.comboBoxes)
        {
            this.UpdateComboBox(comboBox);
        }

        // Process SelectedIndexChanged events again.
        this.ignoreChanges = false;
    }
}

private void UpdateComboBox(ComboBox comboBox)
{
    // Remember the item currently selected.
    var selectedItem = comboBox.SelectedItem;

    // Start with the full list of items.
    var items = new List<object>(this.allItems);

    // Remove items selected in other ComboBoxes.
    foreach (var box in this.comboBoxes)
    {
        if (box != comboBox)
        {
            items.Remove(box.SelectedItem);
        }
    }

    // Clear out the old list.
    comboBox.Items.Clear();

    // Load the new list.
    comboBox.Items.AddRange(items.ToArray());

    // Reselect the previously selected item.
    comboBox.SelectedItem = selectedItem;
}
 
Hello jmcilhinney and thanks for the help.

In this case, only the unassigned items will be populated when the form loads, and if I change the selection from one comboBox then the previously remembered selected item will be populated.
This worked, but this is what I'm trying to do, but still I face problems:
I want to have some items assigned to each comboBox when the form loads but also other items will be available in each comboBox so that I can later change the current selection.
And, whenever I change the selection the duplication of the selected items should not occur. Also, I don't want to reach a level when one or more comboBoxes left empty and out of items.

Example, lets assume that I have four items:
string Items = {"Name, "Age", "Country", "Address"};
Requirement No1: when the form loads, it should populate all the comboBoxes with four items. Means that all the comboBoxes will have the options: Name, Age, Country and Address.
Requirement No2: I need to assign the selectedItem to each comboBox when form loads Suppose:
ComboBox1.selectedItem = "Age";
ComboBox2.SelectedItem = "Address";
ComboBox3.SelectedItem = "Name";
ComboBox4.SelectedItem = "Country";
Requirement No3: If I change the current selection of the ComboBox1 then I will still can do that because all the comboBoxes contains 4items. Suppose I will change
the current selection to Name, then ComboBox1.selectedItem should be equal to "Name" and all other comboBoxes should contain Age as an new option to be selected.
CombBox3.selectedIndex should be now = -1; and ComboBox3.Text = "-Select-" and ComboBox3 should still contain 4items { Name,Age,Country, and address"}

Any idea?
 
Back
Top Bottom