0
votes

i have windows form which have a button, when button is clicked it dynamically generated controls, also a button which is dynamically generated is added so that it will remove the controls which are in line, means aside the button, a row of control will be removed when button clicked my code is

int c = 0;
        private void button1_Click(object sender, EventArgs e)
        {
            int v;
            v = c++;
            panel1.VerticalScroll.Value = VerticalScroll.Minimum;

            Button btn = new Button();
            btn.Name = "btn" + v;
            btn.Text = "Remove";
            btn.Location = new Point(750, 5 + (30 * v));
            btn.Click += new EventHandler(btn_Click);

            ComboBox combo = new ComboBox();
            combo.Name = "combobox" + v;
            combo.Location = new Point(30, 5 + (30 * v));
            combo.Tag = btn;

            ComboBox combo2 = new ComboBox();
            combo2.Name = "combobox2" + v;
            combo2.Location = new Point(170, 5 + (30 * v));
            combo2.Tag = btn;

            TextBox txt = new TextBox();
            txt.Name = "txtbx" + v;
            txt.Location = new Point(300, 5 + (30 * v));
            txt.Tag = btn;

            TextBox txt2 = new TextBox();
            txt2.Name = "txtbx2" + v;
            txt2.Location = new Point(450, 5 + (30 * v));
            txt2.Tag = btn;

            TextBox txt3 = new TextBox();
            txt3.Name = "txtbx3" + v;
            txt3.Location = new Point(600, 5 + (30 * v));
            txt3.Tag = btn;

            panel1.Controls.Add(combo);
            panel1.Controls.Add(btn);
            panel1.Controls.Add(txt);
            panel1.Controls.Add(combo2);
            panel1.Controls.Add(txt2);
            panel1.Controls.Add(txt3);   
        }
        private void btn_Click(object sender, EventArgs e)// this is the dynamically added button's event which will remove the combobox and textbox
        {
            Button btnh = sender as Button;
            foreach (Control item in panel1.Controls.OfType<TextBox>())
            {
                if (item.Tag == sender || item == sender)
                    panel1.Controls.Remove(item);
            }
            foreach (Control item in panel1.Controls.OfType<ComboBox>())
            {
                if (item.Tag == sender || item == sender)
                    panel1.Controls.Remove(item);
            }
            panel1.Controls.Remove(btnh);
        }

my error is nothing but the problem is it dosnt removes all the controls it leaves controls and i dont know whats the problem my code is simple and easy but i dont know where it lacks

2
Is this execution only in C# or are you doing any interop?bonCodigo
Take a look at this MSDN Link 'Control.Tag Property'-msdn.microsoft.com/en-us/library/…MethodMan
i am working in windows form i dont know about others, sorry my english is not so good, if i misunderstood youshariq_khan
@DJKRAZE i am binding the object to other object so that it can be removed,shariq_khan
Ok just wanted to get a clearer understanding on where your train of though was.. thanksMethodMan

2 Answers

3
votes

The problem is that you are removing items while you are looping through the collection. The foreach-statement might skip items in that case. Store the items to be removed in a list first:

List<Control> toBeRemoved = panel1.Controls
    .Cast<Control>()
    .Where(c => c.Tag == sender)
    .ToList();
foreach (Control c in toBeRemoved) {
    panel1.Controls.Remove(c);
}

You can also remove in a loop easily, if you loop backwards:

for (int i = panel1.Controls.Count - 1; i >= 0; i--) {
    if (panel1.Controls[i].Tag == sender) {
        panel1.Controls.RemoveAt(i);
    }
}
3
votes

Removing items in a foreach loop often leads to issues with the list changing while you're traversing it.

This linq should do the trick:

private void btn_Click(object sender, EventArgs e)// this is the dynamically added button's event which will remove the combobox and textbox
    {
        Button btnh = sender as Button;
        panel1.Controls.OfType<TextBox>().Where(i => i.Tag == sender || i == sender).ToList().ForEach(i => panel1.Controls.Remove(i));
        panel1.Controls.OfType<ComboBox>().Where(i => i.Tag == sender || i == sender).ToList().ForEach(i => panel1.Controls.Remove(i));

        panel1.Controls.Remove(btnh);
    }

Why the linq foreach works I'm not sure though :)