无法从控制列表中处置和删除控件

时间:2014-01-31 03:23:12

标签: c# .net visual-studio

感谢阅读。

我有一个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);
//}

2 个答案:

答案 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();
        }
    }