Johnny Prescott
Johnny Prescott

Reputation: 271

WPF foreach textbox loop

I'm trying to understand why this code doesn't work.

Can someone help?

        foreach (TextBox replyBox in textboxPanel.Children.OfType<TextBox>())
        {
            if (replyBox.Name.Contains("Reply"))
            {
                textboxPanel.Children.Remove(replyBox);
            }
        }

It return a message saying the type has changed.

I've seen some other post using panel.controls but I don't have that for my panel somehow.

regards,

Upvotes: 0

Views: 6011

Answers (3)

egonr
egonr

Reputation: 982

The basic foreach loop is immutable.

https://msdn.microsoft.com/en-us/library/ttw7t8t6.aspx

The foreach statement is used to iterate through the collection to get the information that you want, but can not be used to add or remove items from the source collection to avoid unpredictable side effects. If you need to add or remove items from the source collection, use a for loop.

I would solve your problem this way:

rootPanel.Children.OfType<TextBox>().ToList()
            .ForEach(item =>
            {
                if (item.Text.Contains("Reply"))
                {
                    rootPanel.Children.Remove(item);
                }
            });

you could also use LINQ:

rootPanel.Children.OfType<TextBox>()
            .Where(textbox => textbox.Text.Contains("Reply"))
            .ToList().ForEach(item => rootPanel.Children.Remove(item));

The reason this works is because you are iterating through the list created by ToList().

Upvotes: 3

sujith karivelil
sujith karivelil

Reputation: 29006

You are trying to remove an item from the iterating collection, instead of that you can try collect all textBoxes that you waned to remove, then iterate through them and remove one by one from the textboxPanel as i described below:

Try something like this :

var textBoxesToRemove = textboxPanel.Children.OfType<TextBox>().Where(x => x.Name.Contains("Reply"));
foreach (TextBox  txtToRemove in textBoxesToRemove)
{
    textboxPanel.Children.Remove(txtToRemove);
}

Upvotes: 2

Akash KC
Akash KC

Reputation: 16310

Removing from same collection which have been used for iteration might have created issue. You can do like this :

var childerns = textboxPanel.Children.OfType<TextBox>();
foreach (TextBox replyBox in childerns)
        {
            if (replyBox.Name.Contains("Reply"))
            {
                textboxPanel.Children.Remove(replyBox);
            }
        }

Upvotes: 0

Related Questions