当要求时,Visual Basic Form 不会处理所有项目
Visual Basic Form doesn't dispose all items when asked to
希望有人能帮忙..
我正在用 VB.NET 表单编写一个 Windows 小应用程序,
我创建了一个子程序,它在调用时处理表单上的所有项目:
Sub disposer() 'disposes of all the items in the form
For Each i In Me.Controls
i.dispose
Next
End Sub
以上,如果我是正确的应该处理表单中的所有内容,但是,它似乎只删除了表单中的一些项目,例如,只有一半的文本框。
会发生什么:您正在迭代表单控件的 collection(或继承 Control
的另一个 class)。
每次您对其成员之一调用 Dispose()
时,您都会主动将其从 collection 中删除,因此您正在修改正在迭代的 collection。
当您处理第一个控件时,它会从 collection 中删除,列表中的下一个控件 将取而代之 .
您的循环调用 Enumerator.MoveNext()
,因此当您再次调用 Dispose()
时,您将处理索引 1 处的元素,该元素之前是索引 2 处的元素。
跳过索引 1 现在索引 0 的元素。
此过程继续进行,结果是您处理了 collection.
中的一半控件
您可以使用以下方法进行测试:
For Each ctrl As Control In Me.Controls
ctrl.Dispose()
Console.WriteLine(Me.Controls.Count)
Next
您会看到最终计数是初始计数的一半:一半的对照仍然非常活跃。
您可以使用向后 For
循环(从 [Collection].Count - 1
到 0
),从 collection.
的顶部开始
在这种情况下,当您处理控件时,Collection 将从顶部调整大小,因此 Enumerator.MovePrevious()
不会跳过 collection.
中的任何元素
For i As Integer = Me.Controls.Count - 1 To 0 Step -1
Me.Controls(i).Dispose()
Next
您还可以使用正向循环并在索引 0 处进行处理。当处理索引 0 处的元素时,行中的下一个元素将在该索引处取而代之,因此您也不会跳过任何元素。 collection 中的元素不断地 向底部移动 ,但在这种情况下,这是一个相当慢的过程。
如果 collection 有少量项目,您不会注意到,但请记住。
For i As Integer = 0 To Me.Controls.Count - 1
Me.Controls(0).Dispose()
Next
您还可以过滤 collection 控件,以仅考虑特定类型。
例如,要处理 Form 的所有 TextBox 控件 child(或从控件派生的任何其他 class):
Dim textBoxes = Me.Controls.OfType(Of TextBox).ToList()
For i As Integer = textBoxes.Count - 1 To 0 Step -1
textBoxes(i).Dispose()
Next
希望有人能帮忙..
我正在用 VB.NET 表单编写一个 Windows 小应用程序,
我创建了一个子程序,它在调用时处理表单上的所有项目:
Sub disposer() 'disposes of all the items in the form
For Each i In Me.Controls
i.dispose
Next
End Sub
以上,如果我是正确的应该处理表单中的所有内容,但是,它似乎只删除了表单中的一些项目,例如,只有一半的文本框。
会发生什么:您正在迭代表单控件的 collection(或继承 Control
的另一个 class)。
每次您对其成员之一调用 Dispose()
时,您都会主动将其从 collection 中删除,因此您正在修改正在迭代的 collection。
当您处理第一个控件时,它会从 collection 中删除,列表中的下一个控件 将取而代之 .
您的循环调用 Enumerator.MoveNext()
,因此当您再次调用 Dispose()
时,您将处理索引 1 处的元素,该元素之前是索引 2 处的元素。
跳过索引 1 现在索引 0 的元素。
此过程继续进行,结果是您处理了 collection.
您可以使用以下方法进行测试:
For Each ctrl As Control In Me.Controls
ctrl.Dispose()
Console.WriteLine(Me.Controls.Count)
Next
您会看到最终计数是初始计数的一半:一半的对照仍然非常活跃。
您可以使用向后 For
循环(从 [Collection].Count - 1
到 0
),从 collection.
的顶部开始
在这种情况下,当您处理控件时,Collection 将从顶部调整大小,因此 Enumerator.MovePrevious()
不会跳过 collection.
For i As Integer = Me.Controls.Count - 1 To 0 Step -1
Me.Controls(i).Dispose()
Next
您还可以使用正向循环并在索引 0 处进行处理。当处理索引 0 处的元素时,行中的下一个元素将在该索引处取而代之,因此您也不会跳过任何元素。 collection 中的元素不断地 向底部移动 ,但在这种情况下,这是一个相当慢的过程。
如果 collection 有少量项目,您不会注意到,但请记住。
For i As Integer = 0 To Me.Controls.Count - 1
Me.Controls(0).Dispose()
Next
您还可以过滤 collection 控件,以仅考虑特定类型。
例如,要处理 Form 的所有 TextBox 控件 child(或从控件派生的任何其他 class):
Dim textBoxes = Me.Controls.OfType(Of TextBox).ToList()
For i As Integer = textBoxes.Count - 1 To 0 Step -1
textBoxes(i).Dispose()
Next