无法处理和删除控制列表中的控件

问题描述:

感谢您的阅读。无法处理和删除控制列表中的控件

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