Vb.net 在ContextMenuStrip项的迭代中捕获异常

Vb.net 在ContextMenuStrip项的迭代中捕获异常,vb.net,iterator,contextmenustrip,Vb.net,Iterator,Contextmenustrip,我试图迭代contextmenustrip项,如下所示: Public Sub TranslateContextMenuStrip(ByRef u As ContextMenuStrip) For Each t As ToolStripMenuItem In u.Items 'here the error occurs pProcessMenuItem(t) 'not here Next End Sub 但是我在contextmenustrip中有tools

我试图迭代contextmenustrip项,如下所示:

Public Sub TranslateContextMenuStrip(ByRef u As ContextMenuStrip)

    For Each t As ToolStripMenuItem In u.Items 'here the error occurs
        pProcessMenuItem(t) 'not here
    Next

End Sub
但是我在contextmenustrip中有toolstrip分隔符,我得到了错误

“System.InvalidCastException:无法将System.Windows.Forms.ToolStripSeparator类型的对象转换为System.Windows.Forms.ToolStripMenuItem类型”

一旦它绊倒在分离器上


我想知道为什么这个分隔符包含在条目中(我请求“For Each t As ToolStripMenuItem”,那么为什么它返回非ToolStripMenuItems???),以及如何捕获或避免这个错误。

我不认为
For Each t As ToolStripMenuItem
做了您可能认为它做的事情

它只是声明
t
迭代器的类型为
ToolStripMenuItem
。它对项目集合本身没有任何影响。当您使用分隔符时,会出现强制转换异常,因为分隔符无法转换为菜单项

Items
ToolStripItem
s的集合。这是一个基类,用于上下文菜单可以包含的所有类型(菜单项、组合、文本框或分隔符)。因为这些都是从
ToolStripItem
继承的,所以集合可以保存其中任何一个(具体来说,
ToolStripSeparator
项也是
ToolStripItem

有几种方法可以迭代或仅使用菜单项:

筛选项目集合 OfType()的
扩展将items集合过滤为菜单项

这是迄今为止最简单的,因为迭代器
tsi
是正确的类型。如果将方法编写为期望菜单项,则尤其如此:

Sub pProcessMenuItem(item As ToolStripMenuItem)
tsi
迭代器与该方法所期望的类型相同,因此不需要进一步的步骤。其他任何操作都需要在方法中强制转换或调用方法(或关闭选项)

测试类型: 在
选项Strict
下,将
tsi
传递给如上所示声明的方法不会编译。您必须在调用方法之前强制转换:

pProcessMenuItem(CType(tsi, ToolStripMenuItem))
如果该方法声明为接受
ToolStripItem
对象
,则如果需要访问任何与菜单相关的属性,则必须在该方法中进行转换


使用
作为对象进行迭代也是如此:

For Each it As Object In u.Items
    If TypeOf it Is ToolStripMenuItem Then
        pProcessMenuItem(it)
    End If
Next

如果方法参数声明为对象
,则这将在
选项Strict
下编译。如上所述,
对象
可能必须强制转换为
ToolStripMenuItem
。第一种方法可以避免这种情况。

我找到了解决方案,但不是问题:

    For Each it As Object In u.Items
        If TypeOf it Is ToolStripMenuItem Then
            pProcessMenuItem(it)
        End If
    Next
For Each it As Object In u.Items
    If TypeOf it Is ToolStripMenuItem Then
        pProcessMenuItem(it)
    End If
Next
    For Each it As Object In u.Items
        If TypeOf it Is ToolStripMenuItem Then
            pProcessMenuItem(it)
        End If
    Next