感谢阅读。
我有一个C#.NET表单,其中包含可在主面板中切换控件的按钮。在升级到Visual Studio 2012和Advanced Installer之前,我没有遇到任何问题。目标框架是4.0,而不是4.5。
当我更改控件时,我会在添加新控件之前处理并删除前一个控件,但是当没有任何控件时(即第一个控件加载时)我会收到错误。
原始循环在修改集合时发生了一些关于迭代的事情,所以现在我试图在确定它之后删除一个控件。
此错误:索引0超出范围。
这一切在dev机器上运行正常,使用旧的内置VS安装程序不是问题。
有什么想法吗? 4.0框架问题?缺少参考未被部署?
谢谢!
panelMain.SuspendLayout();
int control_count = panelMain.Controls.Count;
if (control_count > 1) {
Log.Write("More than one control found in main panel.", ErrorLevel.Error);
}
if (control_count > 0) {
Control current_ctrl = panelMain.Controls[0];
current_ctrl.Dispose();
panelMain.Controls.Remove(current_ctrl);
}
//foreach (Control ctrl in panelMain.Controls) {
// ctrl.Dispose();
// panelMain.Controls.Remove(ctrl);
//}
答案 0 :(得分:2)
您已注释掉的foreach循环的问题是您无法向当前枚举的集合中添加项目或从中删除项目。这意味着如果你想循环一个集合并删除项目,那么你必须使用for循环。如果要删除多个项目,则必须向后循环。
第二个if语句的问题是,处理控件会自动将其从父控件集合中删除。这意味着,只要在控件上调用Dispose,Controls集合中就不再有项目,因此Remove调用失败。
所以,故事的寓意是你应该使用for循环,向后循环并使用Dispose来销毁和删除。
答案 1 :(得分:0)
如果有人感兴趣,这是一个简单的递归方法来处理控件。使用上面jmcilhinney的建议。
注意:请务必阅读有关Visible属性的所有注释并将其重新设置为true。
// Start by calling a parent control containing the controls you want to
// destroy such as a form, groupbox or panel
private void DisposeControls(Control ctrl)
{
// Make control disappear first to avoid seeing each child control
// disappear. This is optional (if you use - make sure you set parent
// control's Visible property back to true if you create controls
// again)
ctrl.Visible = false;
for (int i = ctrl.Controls.Count - 1; i >= 0; i--)
{
Control innerCtrl = ctrl.Controls[i];
if (innerCtrl.Controls.Count > 0)
{
// Recurse to drill down through all controls
this.DisposeControls(innerCtrl);
}
innerCtrl.Dispose();
}
}