简体   繁体   English

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

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

hope someone can help..希望有人可以帮助..

I'm writing a little Windows application with VB.NET forms,我正在用 VB.NET forms 编写一个小 Windows 应用程序,

I've created a subroutine which disposes all the items on the form when it is called:我创建了一个子例程,它在调用表单时处理表单上的所有项目:

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

        For Each i In Me.Controls

            i.dispose

        Next

End Sub

The above, if I'm correct should dispose of everything in the form, however, it appears to only get rid of some items on the form, for example, only half the textboxes, for example.以上,如果我是正确的,应该处理表单中的所有内容,但是,它似乎只删除了表单上的一些项目,例如,只有一半的文本框。

What happens: you're iterating over the collection of Controls of a Form (or another class that inherits Control ).会发生什么:您正在遍历 Form 的 Controls 集合(或另一个继承Control的 class )。

Each time you call Dispose() on one of its members, you actively remove it from the collection, so you're modifying the collection you're iterating over.每次在其中一个成员上调用Dispose()时,都会主动将其从集合中删除,因此您正在修改您正在迭代的集合。

When you dispose of the first Control, this is removed from the collection and the next Control in the list takes its place .当您处置第一个 Control 时,它会从集合中删除,列表中的下一个 Control会取而代之
Your loop calls Enumerator.MoveNext() , so when you call Dispose() again, you're disposing of the element at index 1, which was previously the element at index 2.您的循环调用Enumerator.MoveNext() ,因此当您再次调用Dispose()时,您将处理索引 1 处的元素,该元素以前是索引 2 处的元素。
The element which was at index 1, now at index 0, is skipped.索引 1 处的元素,现在索引 0 处的元素被跳过。
This process goes on, the result is that you're disposing of half of the Controls in the collection.此过程继续进行,结果是您正在处理集合中的一半控件。

You can test it with:您可以使用以下方法对其进行测试:

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

You'll see that the final count is half the measure of the initial count: half of the Controls are still very much alive.您会看到最终计数是初始计数的一半:一半的控件仍然非常活跃。

You can use a backwards For loop (from [Collection].Count - 1 to 0 ), starting from the top of the collection.您可以从集合的顶部开始使用向后的For循环(从[Collection].Count - 10 )。
In this case, when you dispose of a Control, the Collection is resized from the top so Enumerator.MovePrevious() won't skip any element in the collection.在这种情况下,当您处理控件时,集合会从顶部调整大小,因此Enumerator.MovePrevious()不会跳过集合中的任何元素。

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

You can also use a forward loop and dispose at Index 0. When the element at Index 0 is disposed of, the next in line will take its place at that index, so again you won't skip any.您还可以使用前向循环并在索引 0 处处理。当索引 0 处的元素被处理时,下一行将在该索引处取而代之,因此您不会再跳过任何内容。 The elements in the collection are constantly moved towards the bottom in this case, though, so it's quite a slower process.但是,在这种情况下,集合中的元素会不断地向底部移动,因此这是一个相当慢的过程。
If the collection has a small amount of items, you won't notice, but keep it in mind.如果该系列有少量物品,您不会注意到,但请记住。

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

You can also filter the collection of Controls, to only consider a specific Type.您还可以过滤控件集合,以仅考虑特定类型。
For example, to dispose of all TextBox Controls child of the Form (or any other class derived from Control):例如,要处理 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