我正在尝试用C#重新创建一个游戏,我有一个由3个对象组成的控件:
问题是,我有这段代码:
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;
工作正常并从控件列表中删除控件,但应该启动的两个Orb仍在同一位置。如果我试图查看控件列表是否仍然只有Orbs出现播放器的PictureBox。
我添加了GC.Collect();
收集垃圾,没有发生任何事情。
这是我没有看到或遗失的东西?
解决
基本上,当我创建Orbs时出现错误,我有Orb.parent = PictureBox
正确覆盖图像,因为透明度,并且做了那段代码我不得不从PictureBox中删除Orbs而不是主要控制,就像我试图做的那样。
现在它工作正常。
答案 0 :(得分:1)
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);
}
此代码有问题,会随机删除控件。控件必须拥有父级。如果将其设置为null,则它将从父级的Control集合中删除。现在,您将为另一个控件调用RemoveAt()。这可能是一个不是Orb的控制。
对于控件,调用Dispose()方法不是可选的。当您从父母中删除它们时,它们将被重新托管到隐藏的停放窗口。他们住在哪里,准备搬到另一个父母那里。由于这种情况从未发生过,因此您的程序将泄漏控件。这不可能无穷无尽,Windows拒绝让你在消耗10,000个窗口后创建更多的窗口。
与投诉不完全匹配。控件明显消失需要发生的另一件事是父母重新绘制其背景。破碎的绘画在游戏代码中很常见。
答案 1 :(得分:0)
如果你是clearing/disposing
index
进行控制,那么你肯定会错过其中一些,因为每次你清除/处置一个控件index will be changed
。
示例:如果您在Control
移除index0
- &gt;索引1处的控件变为索引0,因此下次当您尝试在index 1
处删除控件时,您将跳过清除index 0
处的控件
试试这个:
this.Controls.Clear();
或
this.ControlPanel.Controls.Clear();
答案 2 :(得分:0)
您可以尝试使用foreach
和linq
来处置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));
}
你的问题不清楚,但是从你在代码中看到的你要删除的球体。