Reputation: 547
This has happened to me many times. Although I have found a way around it, it feels unprofessional and I would like to know why this happens.
Suppose I have a FlowLayoutPanel
with several 10s of buttons therein.
I intend to loop through all controls and check if a certain condition is met. If it is, then I wish to remove this control. So I'd do something like this:
foreach (Control c in flp_p_products.Controls)
{
if(condition(c))
flp_p_products.Controls.Remove(c);
}
However, on more than one occasion, in different projects, it is not rare that I find that one control manages to slip out of the loop - and I do not know why.
It is only when I add
while(flp_p_controls.Count > 0)
at the beginning of my foreach...
loop that all of the children are looped through.
Is there something I'm not realizing?
Upvotes: 0
Views: 49
Reputation: 941495
Removing an element from a collection and continuing to iterate it usually causes an InvalidOperationException. That however was not done for the Control.ControlCollection class. So what goes wrong is that the foreach loop skips the control that's after the one you removed.
You must iterate backwards to avoid this issue:
for (int ix = flp_p_products.Controls.Count - 1; ix >= 0; ix--)
{
var c = flp_p_products.Controls[ix];
// etc..
}
Upvotes: 1
Reputation: 20620
It is probably because you are modifying the collection at the same time you are iterating over it.
You can iterate the collection and collect the ids of the controls you want to affect. Then use that list to modify the controls.
Upvotes: 0