【问题标题】:Catch exception in iteration of ContextMenuStrip items在 ContextMenuStrip 项的迭代中捕获异常
【发布时间】:2016-01-11 22:36:14
【问题描述】:

我正在尝试迭代这样的上下文菜单项:

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???)以及如何捕获或避免此错误。

【问题讨论】:

    标签: vb.net iterator contextmenustrip


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

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

      ItemsToolStripItems 的集合。这是一个基类,用于上下文菜单可以包含的所有类型(菜单项、组合、文本框或分隔符)。由于这些都继承自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))
      

      如果方法被声明为接受ToolStripItemObject,如果您需要访问任何与菜单相关的属性,则必须在方法中进行强制转换。


      使用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。第一种方法不需要这样做。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-08
        • 1970-01-01
        • 2021-01-29
        • 2014-02-20
        • 1970-01-01
        • 2018-11-22
        相关资源
        最近更新 更多