簡體   English   中英

如何使用遞歸提取 ContextMenuStrip 的所有 ToolStripMenuItems?

[英]How to extract all ToolStripMenuItems of a ContextMenuStrip using recursion?

我正在嘗試將 ContextMenuStrip 中的所有項目提取到List(Of ToolStripMenuItem)
我可以獲得 DataGridView 的 ContextMenuStrip 的引用,然后 - 使用遞歸函數 - 我想提取所有ToolStripMenuItemsNameText屬性,不包括ToolStripSeparators ,如果有的話。

我使用這個代碼:

allItem = New List(Of Control)
Dim lstDbg As List(Of Control) = FindControlRecursive(allItem, form, GetType(DataGridView))

Dim dictRes As New Dictionary(Of String, String)
For Each dbgCtrl As Control In lstDbg
    If dbgCtrl.Name <> "" Then
        For Each mnuStrip As ToolStripItem In dbgCtrl.ContextMenuStrip.Items
            If mnuStrip.GetType() = GetType(ToolStripMenuItem) Then
                Dim lstItem As New List(Of ToolStripMenuItem)
                Dim lstTS As List(Of ToolStripMenuItem) = FindControlRecursive_ContextMenu(lstItem, mnuStrip, GetType(ToolStripMenuItem))
                    For Each item As ToolStripMenuItem In lstTS
                        dictRes.Add(item.Name, item.Text)
                    Next
             End If
        Next
    End If
Next

遞歸函數是FindControlRecursive_ContextMenu()

 Public Function FindControlRecursive_ContextMenu(ByVal list As List(Of ToolStripMenuItem), ByVal parent As ToolStripMenuItem, ByVal ctrlType As System.Type) As List(Of ToolStripMenuItem)
    If parent Is Nothing Then Return list
    If parent.GetType Is ctrlType Then
        list.Add(parent)
    End If
    For Each child As ToolStripMenuItem In parent.DropDown.Items
        FindControlRecursive_ContextMenu(list, child, ctrlType)
    Next
    Return list
End Function

它有效,但如果在 DropDown 列表中有一個ToolStripSeparator ,我沒有DropDown.Items元素並且該函數會生成異常。

如何跳過 ToolStripSeparators 並使用下一個“子項”調用遞歸函數?

由於只需要ToolStripMenuItem類型的子項,您可以簡單地預先過濾 ContextMenuStrip.Items 集合,只收集該特定類型的 Item。 Collection.OfType([Type])方法通常用於此目的。 OfType()僅返回指定類型的項: ToolStripSeparator不屬於該類型,因此它不會包含在過濾的集合中(其他組件類型,例如 ToolStripTextBox、ToolStripComboBox 等)也不會包含在內。

遞歸函數可以是一個迭代器,它返回一個IEnumerable(Of ToolStripMenuItem) ,它產生在for each循環中找到的每個項目。

調用 main 方法,例如:
► 將Option StrictOption ExplicitOption InferOn

 Dim cmsItems As Dictionary(Of String, String) = GetAllContextMenuItems(contextMenuStrip1)
Imports System.Linq

Private Function GetAllContextMenuItems(contextMenu As ContextMenuStrip) As Dictionary(Of String, String)
    If contextMenu Is Nothing OrElse (Not contextMenu.HasChildren) Then Return Nothing
    Dim dict = New Dictionary(Of String, String)
    For Each item As ToolStripMenuItem In contextMenu.Items.OfType(Of ToolStripMenuItem)
        dict.Add(item.Name, item.Text)
        For Each subItem In GetSubMenuItems(item)
            dict.Add(subItem.Name, subItem.Text)
        Next
    Next
    Return dict
End Function

Private Iterator Function GetSubMenuItems(parent As ToolStripMenuItem) As IEnumerable(Of ToolStripMenuItem)
    For Each item As ToolStripMenuItem In parent.DropDownItems.OfType(Of ToolStripMenuItem)
        If item.HasDropDownItems Then
            For Each subItem As ToolStripMenuItem In GetSubMenuItems(item)
                Yield subItem
            Next
        Else
            Yield item
        End If
    Next
End Function

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM