Search code examples
vb.netcontrolscontextmenutoolstripmenu

How to find a toolstripitem based on its name being a variable and then change the checked value of it


I have a ContextMenuStrip called: DGVContextStrip its displayed when the user right clicks on my datagridview.

That MenuStrip contains an item called AddUpgradeTagToolStripMenuItem which contains sub items(dropdownitems), these sub items are all named with a number in their name. eg: Add1ToolStripMenuItem, Add2ToolStripMenuItem, Add3ToolStripMenuItem.... and so on until Add25ToolStripMenuItem.

When a user right clicks, on the Datagridview, I want to check if a cell contains the number "1" then if it does make Add1ToolStripItem.checked = true

I figured I would loop through the numbers 1 to 25, and in each loop check if the cell contains 1 and if true, change the checked value of the menu item. something like...

For i = 1 to 25
  If DataGridView1.SelectedRows(0).Cells("Text_Field").Value.ToString.Contains(i) then
  CType("Add" & i & "ToolStripMenuItem", ToolStripMenuItem).Checked = True

Next

but this doesn't work, iv seen examples online that use the control.find method but i couldn't get that to work for my use. for example

Dim ControlName As String = "Add" & i & "ToolStripMenuItem"
CType(Me.Controls.Find(ControlName, True), ToolStripMenuItem).Checked = True

any ideas how I get this to work? I realise I could have used 25 if then else statements but I kind of wanted to keep the code far neater.


Solution

  • The ToolStripItem is not a control to search for one in a Control.ControlCollection. You need to search a ToolStripItemCollection where it belongs.

    Just like the Control.ControlCollection.Find method, the ToolStripItemCollection.Find method can perform a deep search for an item.

    Examples for your case:

    Dim itemName As String = $"Add{i}ToolStripMenuItem"
    Dim tsmi = yourContextMenuStrip.Items.
        Find(itemName, True).
        OfType(Of ToolStripMenuItem).
        FirstOrDefault()
    
    If tsmi IsNot Nothing Then
        tsmi.Checked = True
    End If
    

    Alternatively, if you already know that the target item is one of the AddUpgradeTagToolStripMenuItem drop down items, then you can do:

    Dim itemName As String = $"Add{i}ToolStripMenuItem"
    Dim tsmi = DirectCast(AddUpgradeTagToolStripMenuItem, ToolStripMenuItem).
        DropDownItems.OfType(Of ToolStripMenuItem).
        FirstOrDefault(Function(x) x.Name.Equals(itemName, StringComparison.OrdinalIgnoreCase))
    
    If tsmi IsNot Nothing Then
        tsmi.Checked = True
    End If
    

    In case you need to check only one item from the collection:

    Dim itemName As String = $"Add{i}ToolStripMenuItem"
    
    For Each tsmi In DirectCast(AddUpgradeTagToolStripMenuItem, ToolStripMenuItem).
        DropDownItems.OfType(Of ToolStripMenuItem)
    
        If tsmi.Name.Equals(itemName, StringComparison.OrdinalIgnoreCase) Then
            tsmi.Checked = True
        Else
            tsmi.Checked = False
        End If
    Next