繁体   English   中英

当被要求时,Visual Basic 表单不会处理所有项目

[英]Visual Basic Form doesn't dispose all items when asked to

希望有人可以帮助..

我正在用 VB.NET forms 编写一个小 Windows 应用程序,

我创建了一个子例程,它在调用表单时处理表单上的所有项目:

Sub disposer() 'disposes of all the items in the form

        For Each i In Me.Controls

            i.dispose

        Next

End Sub

以上,如果我是正确的,应该处理表单中的所有内容,但是,它似乎只删除了表单上的一些项目,例如,只有一半的文本框。

会发生什么:您正在遍历 Form 的 Controls 集合(或另一个继承Control的 class )。

每次在其中一个成员上调用Dispose()时,都会主动将其从集合中删除,因此您正在修改您正在迭代的集合。

当您处置第一个 Control 时,它会从集合中删除,列表中的下一个 Control会取而代之
您的循环调用Enumerator.MoveNext() ,因此当您再次调用Dispose()时,您将处理索引 1 处的元素,该元素以前是索引 2 处的元素。
索引 1 处的元素,现在索引 0 处的元素被跳过。
此过程继续进行,结果是您正在处理集合中的一半控件。

您可以使用以下方法对其进行测试:

For Each ctrl As Control In Me.Controls
    ctrl.Dispose()
    Console.WriteLine(Me.Controls.Count)
Next

您会看到最终计数是初始计数的一半:一半的控件仍然非常活跃。

您可以从集合的顶部开始使用向后的For循环(从[Collection].Count - 10 )。
在这种情况下,当您处理控件时,集合会从顶部调整大小,因此Enumerator.MovePrevious()不会跳过集合中的任何元素。

For i As Integer = Me.Controls.Count - 1 To 0 Step -1
    Me.Controls(i).Dispose()
Next

您还可以使用前向循环并在索引 0 处处理。当索引 0 处的元素被处理时,下一行将在该索引处取而代之,因此您不会再跳过任何内容。 但是,在这种情况下,集合中的元素会不断地向底部移动,因此这是一个相当慢的过程。
如果该系列有少量物品,您不会注意到,但请记住。

For i As Integer = 0 To Me.Controls.Count - 1
    Me.Controls(0).Dispose()
Next

您还可以过滤控件集合,以仅考虑特定类型。
例如,要处理 Form 的所有 TextBox Controls 子项(或从 Control 派生的任何其他 class):

Dim textBoxes = Me.Controls.OfType(Of TextBox).ToList()
For i As Integer = textBoxes.Count - 1 To 0 Step -1
    textBoxes(i).Dispose()
Next

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM