[英]How to extract all ToolStripMenuItems of a ContextMenuStrip using recursion?
I am tryng to extract all items from a ContextMenuStrip to a List(Of ToolStripMenuItem)
.我正在尝试将 ContextMenuStrip 中的所有项目提取到
List(Of ToolStripMenuItem)
。
I can get the reference of the ContextMenuStrip of a DataGridView, then - with a recursive function - I want to extract the Name
and Text
properties of all the ToolStripMenuItems
, excluding the ToolStripSeparators
, if any.我可以获得 DataGridView 的 ContextMenuStrip 的引用,然后 - 使用递归函数 - 我想提取所有
ToolStripMenuItems
的Name
和Text
属性,不包括ToolStripSeparators
,如果有的话。
I use this code:我使用这个代码:
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
The function of recursion is FindControlRecursive_ContextMenu()
:递归函数是
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
It works, but if in the DropDown list there is a ToolStripSeparator
, I don't have the DropDown.Items
element and the function generates an exception.它有效,但如果在 DropDown 列表中有一个
ToolStripSeparator
,我没有DropDown.Items
元素并且该函数会生成异常。
How can I skip the ToolStripSeparators and call the recursive function with the next "child"?如何跳过 ToolStripSeparators 并使用下一个“子项”调用递归函数?
Since only sub-items of type ToolStripMenuItem are needed, you can simply filter the ContextMenuStrip.Items collection beforehand, collecting only Item of that specific type.由于只需要ToolStripMenuItem类型的子项,您可以简单地预先过滤 ContextMenuStrip.Items 集合,只收集该特定类型的 Item。 The Collection.OfType([Type]) method is commonly used for this.
Collection.OfType([Type])方法通常用于此目的。
OfType()
only returns Items of the type specified: ToolStripSeparator is not of that Type, so it won't be included in the filtered collection (nor will other components types such as ToolStripTextBox, ToolStripComboBox etc.). OfType()
仅返回指定类型的项: ToolStripSeparator不属于该类型,因此它不会包含在过滤的集合中(其他组件类型,例如 ToolStripTextBox、ToolStripComboBox 等)也不会包含在内。
The recursive function can be an iterator which returns an IEnumerable(Of ToolStripMenuItem)
that yields each item found in a for each
loop.递归函数可以是一个迭代器,它返回一个
IEnumerable(Of ToolStripMenuItem)
,它产生在for each
循环中找到的每个项目。
Call the main method as, eg,:调用 main 方法,例如:
► Set Option Strict
, Option Explicit
and Option Infer
to On
► 将
Option Strict
、 Option Explicit
和Option Infer
为On
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.