0

Rank noob again learning C# with Winforms. I was practicing adding checkboxes to a panel, and then removing them. The "start_button" button adds checkboxes. This works. The "remove_button" button is supposed to delete all of them. But it doesn't. By playing around with the # of checkboxes, I figured out that it removes every other checkbox. Another click and it removes every other of the remaining ones, and so on until they are all gone.

Why?

Thanks, Aram

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace playingWithPanels
{
public partial class Form1 : Form
{
    CheckBox chkBox;
    TextBox txtBox;
    public Form1()
    {
        InitializeComponent();
    }


    private void start_button_Click(object sender, EventArgs e)
    {
        txtBox = new TextBox();
        txtBox.BringToFront();
        txtBox.Text = "Textbox";
        txtBox.Location = new Point(30, 10);
        panel1.Controls.Add(txtBox);
        for (int i =0;i<20;i++)
        {
        chkBox = new CheckBox();
        chkBox.BringToFront();
        chkBox.Text = "Checkbox_" + i.ToString();
        chkBox.Name = "Checkbox_" + i.ToString();
            chkBox.AutoSize = true;
        chkBox.Location = new Point(30, 40 + 25 * i);
        panel1.Controls.Add(chkBox);
        }
    }

    private void remove_button_Click(object sender, EventArgs e)
    {
        foreach (var ctrl in panel1.Controls.OfType<CheckBox>())
        {
            panel1.Controls.Remove(ctrl);
        }
    }
}
}
  • What is the value of `panel1.Controls.OfType().Count()` at the **start** of the `remove_button_Click` code? At the end? – mjwills Sep 28 '18 at 03:45
  • It's generally bad to modify a collection as you are iterating over it (especially with `foreach`). See the remarks section of [`IEnumerable.GetEnumerable()`](https://learn.microsoft.com/dotnet/api/system.collections.ienumerable.getenumerator#remarks) where it states "If changes are made to the collection, such as adding, modifying, or deleting elements, the behavior of the enumerator is undefined." I cannot explain the specific behavior you're seeing, but I'd say it qualifies as "undefined". – Lance U. Matthews Sep 28 '18 at 03:55
  • 2
    Possible duplicate of [foreach control c# skipping controls](https://stackoverflow.com/questions/17627038/foreach-control-c-sharp-skipping-controls) – Lance U. Matthews Sep 28 '18 at 04:00

1 Answers1

4

Because you use iterator and modify collection during that. Use the following approach:

    var controls = panel1.Controls.OfType<CheckBox>().ToArray();
    foreach (var ctrl in controls)
    {
        panel1.Controls.Remove(ctrl);
    }
Access Denied
  • 8,723
  • 4
  • 42
  • 72