0

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 :)

habib
  • 2,366
  • 5
  • 25
  • 41
  • This is because when you remove a control from the parent, the total number of controls is getting lesser as so the loop. Try yourself by putting a counter inside the loop. – kashi_rock Jul 17 '18 at 09:05
  • foreach is iterating over your controls list and as you can see it removes the first item, because the iterator is at the first place. then it moves to the next one. but you removed the first item so the second item is now your initial third item p2 and if it removes this, it moves on... but what makes me wonder is that you don't get an exception while changing the collection while iterating. You should be able to fix this, if you start iterating from the last to the first item. – Martin Backasch Jul 17 '18 at 09:06
  • ohh wow i seriously didn't even think about that to happened thanks guys – Nathanael Aldo Jul 17 '18 at 09:12

1 Answers1

0

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();
}
Alessandro D'Andria
  • 8,663
  • 2
  • 36
  • 32
  • Thank you, It's working! Been spinning around to solve it by myself and i didn't even think that its an iteration problem Once again thank you – Nathanael Aldo Jul 17 '18 at 09:16