Reputation: 3299
I have a GroupBox in which I dynamically add controls into it. The controls I add are of two types DevExpress.XtraEditors.TextEdit
and Windows.Forms.Label
I am trying to remove these controls using the following
foreach (Control control in salesBox.Controls)
{
control.Dispose();
salesBox.Controls.Remove(control);
}
This is correctly removing the TextEdit
controls but not the Label
controls. The loop is not iterating through the Label
controls.
Upvotes: 4
Views: 11887
Reputation: 112772
The easiest way to remove all controls from a controls collection is to call its Clear
method:
salesBox.Controls.Clear();
Modifying collections can invalidate enumerators and yield unpredictable results or even throw an InvalidOperationException
, depending on the collection type (see the "Remarks" section in IEnumerable.GetEnumerator Method on MSDN). Since foreach
uses an enumerator you should not alter the collection it is iterating.
Use a for
statement, if you have to delete selectively and also iterate backwards, in order not to get wrong index values after removing items:
for (int i = salesBox.Controls.Count - 1; i >= 0; i--) {
Control c = salesBox.Controls[i];
if (c is TextEdit || c is Label) {
salesBox.Controls.RemoveAt(i);
}
}
Upvotes: 6
Reputation: 942488
It doesn't work because you are modifying the collection you are iterating. Calling the Dispose() method also removes a control from the parent's Control collection. The side-effect is that you'll only dispose the even numbered controls. Either of these two loops will get the job done:
while (salesBox.Controls.Count > 0) salesBox.Controls[0].Dispose();
for (int ix = salesBox.Controls.Count-1; ix >= 0; ix---) salesBox.Controls[ix].Dispose();
Or keep them on a panel and dispose the panel.
Upvotes: 3
Reputation: 732
You cannot alter the contents of the collection within the Foreach. You would need to do something like this I believe.
List<Control> toRemove = salesBox.Controls.OfType<Control>().ToList();
foreach(Control c in toRemove)
{
salesBox.Controls.Remove(c);
c.Dispose();
}
Upvotes: 2
Reputation: 1197
Foreach
can't iterate because the length of the salesbox.Controls
changed. If you add or remove an item you'd better use for
You can do it by
for(int i=0;i<salesBox.Controls.Count;i++)
{ if(salesBox.Controls[i] is DevExpress.XtraEditors.TextEdit) //your condition here
{
salesBox.Controls.Remove(salesBox.Controls[i]);
i--;
}
}
Upvotes: 0