Reputation: 681
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
Upvotes: 0
Views: 1914
Reputation: 241
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 :)
Upvotes: 3
Reputation: 112772
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);
}
}
Upvotes: 3