我不认为For Each t As ToolStripMenuItem 做了你可能认为它会做的事情。
它只是声明t 迭代器的类型为ToolStripMenuItem。它对项目集合本身没有任何作用。当您使用分隔符时,您会得到强制转换异常,因为分隔符无法转换为菜单项。
Items 是ToolStripItems 的集合。这是一个基类,用于上下文菜单可以包含的所有类型(菜单项、组合、文本框或分隔符)。由于这些都继承自ToolStripItem,因此集合可以容纳其中的任何一个(具体而言,ToolStripSeparator 项目也是ToolStripItem)
有几种方法可以迭代或仅使用菜单项:
过滤 Items 集合
For Each tsi As ToolStripMenuItem In u.Items.OfType(Of ToolStripMenuItem)()
' do something fun with tsi
Next
OfType() 扩展将项目集合过滤为仅菜单项。
这是迄今为止最简单的,因为您的迭代器 tsi 是正确的类型。如果您的方法被编写为期望菜单项,则尤其如此:
Sub pProcessMenuItem(item As ToolStripMenuItem)
tsi 迭代器与该方法预期的类型相同,因此不需要进一步的步骤。其他任何事情都需要在方法中进行强制转换或调用方法(或 Option Strict Off)。
测试类型:
' iterate all the items
For Each tsi As ToolStripItem In u.Items
' test the type of each
If TypeOf tsi Is ToolStripMenuItem Then
' do something fun with tsi
End If
Next
在Option Strict 下,将tsi 传递给如上所示声明的方法不会编译。您必须在调用您的方法之前进行转换:
pProcessMenuItem(CType(tsi, ToolStripMenuItem))
如果方法被声明为接受ToolStripItem 或Object,如果您需要访问任何与菜单相关的属性,则必须在方法中进行强制转换。
使用As Object进行迭代也是如此:
For Each it As Object In u.Items
If TypeOf it Is ToolStripMenuItem Then
pProcessMenuItem(it)
End If
Next
如果方法参数声明为As Object,则在Option Strict 下编译的唯一方法。如上所述,Object 可能必须转换为 ToolStripMenuItem。第一种方法不需要这样做。