Reputation: 726
I'm trying to recreate a game in C# and I have a control that is composed with 3 objects:
The problem is, I have this code:
Orb[,] map = orbsAmmo;
for (Int32 x = 0; x < 2; x++)
for (Int32 y = 0; y < 2; y++)
orbsAmmo[x, y] = null;
for (Int32 index = this.Controls.Count - 1; index >= 0; index--)
if (this.Controls[index] is Orb) {
this.Controls[index].Parent = null;
//this.Controls[index].Dispose();
this.Controls.RemoveAt(index);
}
//GC.Collect();
return map;
That works fine and removes the controls from the controls list, but the two Orbs that are supposed to be launched are still in the same location. If I try to see if the controls list still have the Orbs only appears the PictureBox of the Player.
I added the GC.Collect();
to collect the garbage, nothing happened.
It is something that I'm not seeing or missing?
SOLVED
Basically, the error occurs when I create the Orbs, I had Orb.parent = PictureBox
to overlay correctly the images, because of the transparency, and doing that piece of code I had to remove the Orbs from the PictureBox and not from the main control, like I was trying to do.
Now it works fine and correctly.
Upvotes: 0
Views: 479
Reputation: 941217
for (Int32 index = this.Controls.Count - 1; index >= 0; index--)
if (this.Controls[index] is Orb) {
this.Controls[index].Parent = null;
//this.Controls[index].Dispose();
this.Controls.RemoveAt(index);
}
This code is buggy and will randomly remove controls. A control must have a Parent. If you set it to null then it will be removed from the parent's Control collection. You will now call RemoveAt() for another control. This may well be control that is not an Orb.
Calling the Dispose() method is not optional for controls. When you remove them from their Parent then they'll be re-hosted to the hidden parking window. Where they'll live, ready to moved to another parent. With high odds that this never happens, your program will leak controls. This cannot go endlessly, Windows refuses to allow you to create more windows after you've consumed 10,000 of them.
Not exactly a match with the complaint. Another thing that needs to happen for a control to visibly disappear is for the parent to repaint its background. Broken painting is common in gaming code.
Upvotes: 1
Reputation: 10552
You could try using a foreach
and linq
to dispose the orbs
IEnumerable<Control> c = GetAllOrbs(this);
foreach (Orb item in c.ToArray())
{
item.Dispose();
//or if you prefer just to remove them use this:
//item.Parent.Controls.Remove(item);
}
.
public IEnumerable<Control> GetAllOrbs(Control control)
{
var controls = control.Controls.Cast<Control>();
return controls.SelectMany(ctrl => GetAllOrbs(ctrl, type)).Concat(controls).Where(c => c.GetType() == typeof(Orb));
}
You question is not clear, but from what i see in the code you want to remove the orbs.
Upvotes: 0
Reputation: 26199
if you are clearing/disposing
Controls by index
you will be definitely missing some of them because each time you clear/dispose a control their index will be changed
.
Example : if you remove a Control
at index0
-> control at index 1 becomes index 0, so next time when you try to remove control at index 1
you will skip to clear control at index 0
Try This:
this.Controls.Clear();
or
this.ControlPanel.Controls.Clear();
Upvotes: 0