我在按钮单击事件处理程序中有一个foreach
循环,我用它来摆脱所有坐在Y轴上同一点的控件。我有一个控件添加一行,然后我需要用户可以选择删除他们并不想添加的行。
当我单独使用foreach
循环时,它总是错过两个项目 - 每次都是相同的两个项目。我确认Y值实际上是相同的。如果我继续运行该函数,它会在三次运行后删除该行上的所有控件。但是,如果我使用所有相同的值嵌套foreach
循环,它就可以工作。请参阅下面的代码。
这似乎是一种非常草率的方式,但它也是唯一对我有用的解决方案。我看到其他一些帖子说要在循环中声明第二个变量(即Control z = c; if(z.Location....)
)。这并没有对这里的行为产生任何影响。任何人都可以解释为什么foreach
循环本身并不起作用?如何在没有重复嵌套的情况下修复它?
工作:
internal void MinButt_Click(object sender, EventArgs e)
{
Scratch.tScratch.panel2.Controls.RemoveByKey("Record" + arrDynamY[0].ToString());
foreach (Control c in Scratch.tScratch.panel2.Controls)
{
if (c.Location.Y == arrDynamY[1])
{
c.Dispose();
}
foreach (Control ctrl in Scratch.tScratch.panel2.Controls)
{
if (ctrl.Location.Y == arrDynamY[1])
{
ctrl.Dispose();
}
}
}
}
每次错过相同的两个控件:
internal void MinButt_Click(object sender, EventArgs e)
{
Scratch.tScratch.panel2.Controls.RemoveByKey("Record" + arrDynamY[0].ToString());
foreach (Control c in Scratch.tScratch.panel2.Controls)
{
if (c.Location.Y == arrDynamY[1])
{
c.Dispose();
}
}
}
答案 0 :(得分:3)
您应首先获取用于删除和删除它们的控件,如下所示:
var controlsToRemove = from Control c in Scratch.tScratch.panel2.Controls
where c.Location.Y == arrDynamY[1]
select c;
foreach (var c in controlsToRemove.ToArray())
{
Scratch.tScratch.panel2.Controls.Remove(c);
c.Dispose();
}
答案 1 :(得分:1)
您正在修改(在这种情况下处理)您正在迭代的集合的项目,我相信这是导致意外行为的原因,您可以使用for
循环来避免此问题:< / p>
for (int i = Scratch.tScratch.panel2.Controls.Length - 1; i >= 0; i-- )
if (Scratch.tScratch.panel2.Controls[i].Location.Y == arrDynamY[1])
Scratch.tScratch.panel2.Controls[i].Dispose();
我假设Scratch.tScratch.panel2.Controls
可以作为数组访问。
答案 2 :(得分:0)
也许在单独的循环中执行dispose,它可能会影响其他控件
试试这个
internal void MinButt_Click(object sender, EventArgs e)
{
Scratch.tScratch.panel2.Controls.RemoveByKey("Record" + arrDynamY[0].ToString());
var controlsToDispose = new List<Control>();
foreach (Control c in Scratch.tScratch.panel2.Controls)
{
if (c.Location.Y == arrDynamY[1])
{
controlsToDispose.Add(c);
}
}
foreach (Control c in controlsToDispose )
{
c.Dispose();
}
}
答案 3 :(得分:-1)
这是因为当您在控件上调用Dispose()时,它只会停留在内存中,直到GC启动。请尝试以下操作。
List<Control> controlsToDispose = new List<Control>();
foreach (Control c in Scratch.tScratch.panel2.Controls)
{
if (c.Location.Y == arrDynamY[1])
{
controlsToDispose.Add(c);
c.Dispose();
}
}
while(controlsToDispose.Count>0)
{
Control ctrl = controlsToDispose[0];
controlsToDispose.RemoveAt(0);
ctrl.Dispose();
}