无法处理和删除控制列表中的控件
问题描述:
感谢您的阅读。无法处理和删除控制列表中的控件
我有一个C#.NET窗体的按钮,在主面板中切换控件。在升级到Visual Studio 2012和Advanced Installer之前,我没有任何问题。目标框架是4.0,而不是4.5。
当我更改控件时,我在添加新控件之前先处理并删除了前一个控件,但是当没有任何控件(即第一个控件加载时)出现错误。
原始循环在修改集合时与某些迭代有关,所以现在我试图在确保它在那里后删除一个控件。
此错误与:索引0超出范围。
这一切都可以在开发机器上正常工作,这不是使用旧的内置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);
//}
答
你已经注释到的foreach循环的问题是你不能添加项目或从你正在枚举的集合中删除项目。这意味着如果你想遍历一个集合并移除项目,那么你必须使用for循环。如果你想删除多个项目,那么你必须向后循环。
第二个if语句的问题在于,处置控件会自动将其从其父控件集合中删除。这意味着,只要您在控件上调用Dispose,Controls集合中就不再有一个项目,因此Remove调用失败。
因此,故事的寓意是,您应该使用for循环,向后循环并使用Dispose来销毁和删除。
答
这是一个简单的递归方法来处置控制,如果任何人有兴趣。使用上面的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();
}
}