Search code examples
c#runtime-errorpictureboxdynamically-generated

Error in removing a dynamically created PictureBox


I am creating a card game program using C# and suddenly this thing happened when i want to remove every single PictureBox representing cards in hand Visual Studio doesn't read all of the PictureBox in the control whenever I add this.Controls.Remove(pb) or pb.Dispose() which is weird...

Here is the code and the output when I'm not using the dispose code line:

private void removeCiH(string target)
{
    foreach (PictureBox pb in this.Controls.OfType<PictureBox>())
    {
        Console.WriteLine(pb.Name);
        string x = pb.Name;
        //this.Controls.Remove(pb);
        //pb.Dispose();
    }
}

Output:

p0

p1

p2

p3

p4

p5

And here is the code and the output when I'm using the dispose line code:

private void removeCiH(string target)
{
    foreach (PictureBox pb in this.Controls.OfType<PictureBox>())
    {
        Console.WriteLine(pb.Name);
        string x = pb.Name;
        this.Controls.Remove(pb);
        pb.Dispose();
    }
}

Output:

p0

p2

p4

When I use Dispose, VS won't read half of the PictureBox which is weird

Please help me

In case needed, here is how I dynamically create the PictureBox

private void paintCiH(PlayerCards _pc, string target)
{
    int x, y, c;
    x = 156;
    c = 0;
    if (target == "p")
    {
        y = 420;
        foreach (Card card in _pc.CiH)
        {
            var newPict = new PictureBox
            {
                Name = target + c,
                Size = new Size(81, 121),
                Location = new Point(x + ((328 / 6) * c), y),
                BackgroundImage = Image.FromFile("img//card_front.png"),
                Image = Image.FromFile("img//Cards//" + card.img)
            };
            //Add it to the event handler and  form
            newPict.Click += new EventHandler(this.card_Click);
            this.Controls.Add(newPict);
            c++;
        }
    }
    else
    {
        y = -99;
        foreach (Card card in _pc.CiH)
        {
            var newPict = new PictureBox
            {
                Name = target + c,
                Size = new Size(81, 121),
                Location = new Point(x + ((328 / 6) * c), y),
                BackgroundImage = Image.FromFile("//img//card_back.png")
            };
            //Add it to the event handler and  form
            newPict.Click += new EventHandler(this.card_Click);
            this.Controls.Add(newPict);
            c++;
        }
    }
}

Thanks, before that :)


Solution

  • Try this to avoid modifying the collection in foreach loop:

    var controlsToRemove = this.Controls.OfType<PictureBox>().ToArray();
    
    foreach (PictureBox pb in controlsToRemove)
    {
        Console.WriteLine(pb.Name);
        string x = pb.Name;
        this.Controls.Remove(pb);
        pb.Dispose();
    }