Vb.net 不理解从面板上卸下控制装置
我有一个面板,面板上有大约六个控件。我想从面板中删除控件,最后使用MyPanel.Clear()删除了这些控件。但在此之前,我尝试了通过单击按钮运行的以下代码:Vb.net 不理解从面板上卸下控制装置,vb.net,Vb.net,我有一个面板,面板上有大约六个控件。我想从面板中删除控件,最后使用MyPanel.Clear()删除了这些控件。但在此之前,我尝试了通过单击按钮运行的以下代码: For Each b As Control In MyItem.MyPanel.Controls MyItem.MyPanel.Controls.Remove(b) Next 我会单击按钮并观看它,以及调试中的MyItem.MyPanel.Controls.Count。当它通过时,计数将减少:到5到
For Each b As Control In MyItem.MyPanel.Controls
MyItem.MyPanel.Controls.Remove(b)
Next
我会单击按钮并观看它,以及调试中的MyItem.MyPanel.Controls.Count。当它通过时,计数将减少:到5到4到3,然后它将退出。如果我再次点击按钮,它会再删除两个,然后在第三次点击时删除最后一个,因此它们都符合要求,并且都被删除,没有任何更改。为什么要点击三下?我想,我显然遗漏了一些简单的东西,但我不知道它是什么,我真的很想理解它。如果我必须删除特定的控件,看起来我会遇到问题。奇怪的是,VB.NET甚至允许您这样做,但实际上您所做的是编辑正在迭代的集合。为了更好地理解,假设您正在使用一个从1到6的常规for循环,在第一次迭代中删除对象1,留下5个对象,使旧的2号对象成为第一个对象。在下一次迭代中,您将删除第二个东西,它以前是第三个,依此类推。大多数语言这是一个运行时错误。奇怪的是,VB.NET甚至允许您这样做,但实际上您所做的是编辑正在迭代的集合。为了更好地理解,假设您正在使用一个从1到6的常规for循环,在第一次迭代中删除对象1,留下5个对象,使旧的2号对象成为第一个对象。在下一次迭代中,您将删除第二个东西,它以前是第三个,依此类推。大多数语言这是一个运行时错误。发生的情况是从第一个位置开始删除控件,然后移动到最后一个位置。如果列表中有6条记录,并且您开始像您一样删除它们,则按程序您会说:
remove(0)
remove(1)
...
remove(5)
当你这么做的时候,名单越来越小了。删除第一个项目后,它会从6个位置下降到5个位置,然后是4个位置,然后是3个位置,以此类推。因此,在代码执行的中途,它会尝试删除位置3(第4个项目)处的项目,但由于您已经删除了3个项目,因此列表的大小仅包含3个项目,并且该位置不存在
要正确地删除它们,您必须从列表的后面开始,然后移到前面
也许是这样的:
For i As Integer = (MyItem.MyPanel.Controls.Count- 1) To 0 Step -1
MyItem.mypanel.Controls(i).Dispose()
Next
发生的情况是,您正在删除从第一个位置开始并移动到最后一个位置的控件。如果列表中有6条记录,并且您开始像您一样删除它们,则按程序您会说:
remove(0)
remove(1)
...
remove(5)
当你这么做的时候,名单越来越小了。删除第一个项目后,它会从6个位置下降到5个位置,然后是4个位置,然后是3个位置,以此类推。因此,在代码执行的中途,它会尝试删除位置3(第4个项目)处的项目,但由于您已经删除了3个项目,因此列表的大小仅包含3个项目,并且该位置不存在
要正确地删除它们,您必须从列表的后面开始,然后移到前面
也许是这样的:
For i As Integer = (MyItem.MyPanel.Controls.Count- 1) To 0 Step -1
MyItem.mypanel.Controls(i).Dispose()
Next
我自己也遇到过这个问题,奇怪的是,它甚至允许您在修改所引用循环中的集合时执行此操作。这应该是一个更好的方法。
如果要根据类型删除它们
For i = Panel1.Controls.Count - 1 To 0 Step -1
If TypeOf Panel1.Controls(i) Is Label Then
Panel1.Controls.Remove(Panel1.Controls(i))
End If
Next
我自己也遇到过这个问题,奇怪的是,它甚至允许您在修改所引用循环中的集合时执行此操作。这应该是一个更好的方法。
如果要根据类型删除它们
For i = Panel1.Controls.Count - 1 To 0 Step -1
If TypeOf Panel1.Controls(i) Is Label Then
Panel1.Controls.Remove(Panel1.Controls(i))
End If
Next
这是有道理的。但是,如何删除特定类型的控件?您是否需要列出一个对象ID列表,然后遍历该列表并删除每个ID?有更好的办法吗?你能在调用clear之前指定类型吗?@Kevin你通常会在VB.NET中看到错误,但实际发生的是它正在调用,如果集合被编辑,则由该方法的实现者实际抛出异常。我想Windows窗体团队只是没有为控件集合做这件事。这是有道理的。但是,如何删除特定类型的控件?您是否需要列出一个对象ID列表,然后遍历该列表并删除每个ID?有更好的办法吗?你能在调用clear之前指定类型吗?@Kevin你通常会在VB.NET中看到错误,但实际发生的是它正在调用,如果集合被编辑,则由该方法的实现者实际抛出异常。我想Windows窗体团队只是没有为控件集合做这件事。