Ok. This is kind of a weird problem. I have a form in my program that I add more controls to in order to allow users to enter more data if need be. I also have a button that clears the form and resets it to its initial state. The problem is I have to push the clear button multiple times in order for all the fields I added to be removed. I am not sure why this is. Here is the loop I am using to remove the fields.

foreach (Control ctrl in grpIngredients.Controls)
            {
                if (ctrl.Name == "txtAmt6")
                {
                    TextBox txtAmt6 = (TextBox)grpIngredients.Controls["txtAmt6"];
                    grpIngredients.Controls.Remove(txtAmt6);
                }
                else if (ctrl.Name == "txtAmt7") 
                {
                        TextBox txtAmt7 = (TextBox)grpIngredients.Controls["txtAmt7"];
                        grpIngredients.Controls.Remove(txtAmt7);
                }           
                else if (ctrl.Name == "txtAmt8") 
                {
                        TextBox txtAmt8 = (TextBox)grpIngredients.Controls["txtAmt8"];
                        grpIngredients.Controls.Remove(txtAmt8);
                }           
                else if (ctrl.Name == "txtAmt9")
                {
                        TextBox txtAmt9 = (TextBox)grpIngredients.Controls["txtAmt9"];
                        grpIngredients.Controls.Remove(txtAmt9);
                }           
                else if (ctrl.Name == "txtAmt10")
                {
                        TextBox txtAmt10 = (TextBox)grpIngredients.Controls["txtAmt10"];
                        grpIngredients.Controls.Remove(txtAmt10);
                }
                else if (ctrl.Name == "txtAmt11") 
                {
                        TextBox txtAmt11 = (TextBox)grpIngredients.Controls["txtAmt11"];
                        grpIngredients.Controls.Remove(txtAmt11);
                }           
                else if (ctrl.Name == "txtAmt12") 
                {
                        TextBox txtAmt12 = (TextBox)grpIngredients.Controls["txtAmt12"];
                        grpIngredients.Controls.Remove(txtAmt12);
                }           
                else if (ctrl.Name == "txtAmt13") 
                {
                        TextBox txtAmt13 = (TextBox)grpIngredients.Controls["txtAmt13"];
                        grpIngredients.Controls.Remove(txtAmt13);
                }           
                else if (ctrl.Name == "txtAmt14") 
                {
                        TextBox txtAmt14 = (TextBox)grpIngredients.Controls["txtAmt14"];
                        grpIngredients.Controls.Remove(txtAmt14);
                }           
                else if (ctrl.Name == "txtAmt15") 
                {
                        TextBox txtAmt15 = (TextBox)grpIngredients.Controls["txtAmt15"];
                        grpIngredients.Controls.Remove(txtAmt15);
                }           
                else if (ctrl.Name == "txtAmt16") 
                {
                        TextBox txtAmt16 = (TextBox)grpIngredients.Controls["txtAmt16"];
                        grpIngredients.Controls.Remove(txtAmt16);
                }           
                else if (ctrl.Name == "cboName6")  
                {
                        ComboBox cboName6 = (ComboBox)grpIngredients.Controls["cboName6"];
                        grpIngredients.Controls.Remove(cboName6);
                }           
                else if (ctrl.Name == "cboName7") 
                {
                        ComboBox cboName7 = (ComboBox)grpIngredients.Controls["cboName7"];
                        grpIngredients.Controls.Remove(cboName7);
                }           
                else if (ctrl.Name == "cboName8") 
                {
                        ComboBox cboName8 = (ComboBox)grpIngredients.Controls["cboName8"];
                        grpIngredients.Controls.Remove(cboName8);
                }           
                else if (ctrl.Name == "cboName9") 
                {
                        ComboBox cboName9 = (ComboBox)grpIngredients.Controls["cboName9"];
                        grpIngredients.Controls.Remove(cboName9);
                }           
                else if (ctrl.Name == "cboName10") 
                {
                        ComboBox cboName10 = (ComboBox)grpIngredients.Controls["cboName10"];
                        grpIngredients.Controls.Remove(cboName10);
                }           
                else if (ctrl.Name == "cboName11") 
                {
                        ComboBox cboName11 = (ComboBox)grpIngredients.Controls["cboName11"];
                        grpIngredients.Controls.Remove(cboName11);
                }           
                else if (ctrl.Name == "cboName12") 
                {
                        ComboBox cboName12 = (ComboBox)grpIngredients.Controls["cboName12"];
                        grpIngredients.Controls.Remove(cboName12);
                }           
                else if (ctrl.Name == "cboName13") 
                {
                        ComboBox cboName13 = (ComboBox)grpIngredients.Controls["cboName13"];
                        grpIngredients.Controls.Remove(cboName13);
                }           
                else if (ctrl.Name == "cboName14") 
                {
                        ComboBox cboName14 = (ComboBox)grpIngredients.Controls["cboName14"];
                        grpIngredients.Controls.Remove(cboName14);
                }           
                else if (ctrl.Name == "cboName15") 
                {
                        ComboBox cboName15 = (ComboBox)grpIngredients.Controls["cboName15"];
                        grpIngredients.Controls.Remove(cboName15);
                }           
                else if (ctrl.Name == "cboName16") 
                {
                        ComboBox cboName16 = (ComboBox)grpIngredients.Controls["cboName16"];
                        grpIngredients.Controls.Remove(cboName16);
                }

I have tried using a Switch also instead of the if/else if but get the same result. Is there any reason why this would be stopping in the middle of the loop? Thanks for the help.

P.S. This is a long code block. Is there a way to make the block smaller and add a scrollbar?

Recommended Answers

All 6 Replies

This code is quite long and redundant. A better way to do this would be to keep track of all added controls using a HashSet<Control>. Here's some example code that I tested prior to posting this reply:

public partial class MyForm: Form
{
    // A hashset that will contain references to controls added by the user
    Hashset<Control> added;
    ...

    // Default form constructor
    public MyForm()
    {
        ...
        // Initialise our hashset
        added = new HashSet<Control>();
    }

    ...

    // Handle the "Add Control" button click
    private void btnAddControl_Click(...)
    {
        // Create the control here
        var control = new ...
        ...

        // Add the control to both the hashset and our form
        added.Add(control);
        this.Controls.Add(control);
    }

    // Handle the "Reset Form" button click
    private void btnResetForm_Click(...)
    {
        // Iterate through each control in added and remove it from our form
        foreach (var control in added)
            this.Controls.Remove(control);

        // Clear our hashset so we can use it again
        added.Clear();
    }
}

To answer your original question, the reason it only removes one control is because you are using if/else if. The first one that matches causes all the others to be excluded. Remove all the 'else' keywords and it will work how you think it should.

To the second poster, why choose a HashSet<> when a List<> would work just as well, and have less overhead? It's not like he needs to look them up again, just iterate through them.

Be aware that making changes to the list you are enumerating WILL also cause values to be skipped as the list is updated and your enumerator is invalidated.

Yamachi's solution will get around this problem as the enumerated list is not the one being modified.

commented: exactly it :) +3

@Momerath: I thought that using a HashSet would prevent the user from being able to add duplicate control entries. After testing it, I see that this is not the case, and second your suggestion of using a List<T> instead of a HashSet<T>.

@Yamachi: It would if it was the same reference. This is a problem that I've seen people encounter all the time and has to do with what 'Equals' means to an object :)

I thought about using a List<T> but I am programmaticly (is that a word?) incrementing the name of the controls after they are created and I am not sure how to get a control like that into a list. What I ended up doing is taking my increment variable and set bool to true if the value matches a certain number. Then when I remove the controls I check if the bool is true. If it is then I know the controls exist and I remove them, otherwise I skip that set.

Thanks for all your help.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.