我正在尝试迭代这样的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中有工具条分隔符,我收到了错误
“System.InvalidCastException:System.Windows.Forms.ToolStripSeparator类型的对象无法转换为System.Windows.Forms.ToolStripMenuItem类型”
一旦碰到分隔符。
我想知道为什么这个分隔符包含在项目中(我请求“For Each t As ToolStripMenuItem”,为什么它返回非ToolStripMenuItems ???)以及如何捕获此错误或避免它。
答案 0 :(得分:0)
我不认为For Each t As ToolStripMenuItem
会做你认为它做的事情。
它只是声明t
迭代器将是ToolStripMenuItem
类型。它对项目集合本身没有任何作用。当你来到分隔符时,你会得到强制转换异常,因为分隔符无法转换为菜单项。
Items
是ToolStripItem
的集合。这是一个基类,用于上下文菜单可以容纳的所有类型(菜单项,组合,文本框或分隔符)。由于这些都继承自ToolStripItem
,因此集合可以包含其中任何一个(具体而言,ToolStripSeparator
项也是ToolStripItem
)
有几种方法可以迭代或使用菜单条目:
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
如果方法参数声明为Option Strict
,则在As Object
下编译的唯一方法。如上所述,Object
可能必须转换为ToolStripMenuItem
。第一种方法可以防止任何需要。
答案 1 :(得分:0)
我找到了一个解决方案,但不是问题:
For Each it As Object In u.Items
If TypeOf it Is ToolStripMenuItem Then
pProcessMenuItem(it)
End If
Next