Reputation: 36
I am trying to remove all buttons from panel. somehow it remove only half with my code. i do not know why. this is in c# windows form. can someone explain please. thank you. code as follows: Added using
for(int ii=1; ii<=6; ii++)
{
for(int jj=1; jj<=5; jj++)
{
Button b = new Button();
b.TabStop = false;
b.Width = 146;
b.Height = 91;
b.Click += new EventHandler(b_Click);
panel.Controls.Add(b);
}
}
Remove using
foreach (Control c in panel.Controls)
{
c.Click -= new EventHandler(this.b_Click);
panel.Controls.Remove(c);
c.Dispose();
}
Upvotes: 1
Views: 5155
Reputation: 873
Your list of controls is iterating to the half because the iterator increase while the amount of items are decrease. In the middle of the (internal) index of your Control-List is bigger than the amount of items.
Save the list of items first:
List<Button> buttons = panel.Controls.OfType<Button>().ToList();
foreach (Button btn in buttons)
{
btn.Click -= new EventHandler(this.b_Click); //It's unnecessary
panel.Controls.Remove(btn);
btn.Dispose();
}
edit: Why do you remove the Click-Event, if you dispose the button? After Disposing, the events are cleared and the button could not be used either.´
If you want a 1 line solution, you could only use Dispose. It will remove the buttons automatically from the panel an clear all events etc.
panel.Controls.OfType<Button>().ToList().ForEach(btn => btn.Dispose());
Upvotes: 6
Reputation: 5514
You are not allowed to modify a collection (Controls
) while iterating it, so that code shouldn't work.
Try simply:
panel.Controls.Clear();
You'll be fine without the call to Dispose
.
Edit: if you do only want to remove all Button
's (and have other and possibly nested controls), you can do something like this:
private void FindControls<T>( List<T> list, Control parent ) where T : Control
{
foreach( Control c in parent.Controls )
{
if( c is T )
list.Add( (T)c );
FindControls( list, c );
}
}
// and use like so:
var list = new List<Button>();
FindControls( list, this );
foreach( var b in list )
b.Parent.Controls.Remove( b );
Upvotes: 0
Reputation: 1277
foreach (Control c in panel1.Controls.OfType<Button>().ToList())
{
panel1.Controls.Remove(c);
c.Dispose();
}
Upvotes: 2
Reputation: 2376
Unfortunately the compiler allows this sort of thing, but usually results in a run-time exception. You need to iterate over a collection that is not being modified.
List<Control> ctrls = new List<Control>(panel.Controls)
foreach (Control c in ctrls)
{
if(c is Button)
{
c.Click -= new EventHandler(this.b_Click);
panel.Controls.Remove(c);
c.Dispose();
}
}
Upvotes: 0