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.
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.
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);
}
}
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();
}
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--;
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.