I am tryng to extract all items from a ContextMenuStrip to a 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.
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()
:
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.
How can I skip the ToolStripSeparators and call the recursive function with the next "child"?
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. The Collection.OfType([Type]) method is commonly used for this.
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.).The recursive function can be an iterator which returns an
IEnumerable(Of ToolStripMenuItem)
that yields each item found in afor each
loop.Call the main method as, e.g.,:
► Set
Option Strict
,Option Explicit
andOption Infer
toOn