Search code examples
vb.netcontextmenustrip

Change contextMenuStrip based on state of a different object


I am looking for a good way to implement a TreeView in VB.net whose contextMenuStrip is variant based on the state of a different object in the form.

Specifically, in the 'TreeView' below, when the object state=1 display contextMenuStrip1 on items, and when state=2 display contextMenuStrip2 on items.

So far, I've been implementing context menus like the code below, and adding the contextMenuStrip when I create the node.

Dim Context1 As ContextMenuStrip = New ContextMenuStrip
AddHandler Context1.Items.Add("Delete Item").Click, AddressOf DeleteSub


------------------
| + TreeNode1
| + TreeNode2
| + TreeNode3
|   |- Item1
|   |- Item2
|   |- Item3
------------------

Solution

  • I have no idea what this object is which determines the menu to use, so I used a CheckBox. If the object in question is something like that, you could reassign the ContextMenuStrip when the state changes - in this case, using the CheckChange event:

    Private Sub chkShow2_CheckedChanged(sender...
        If chkShow2.Checked Then
            tv1.ContextMenuStrip = cms2
        Else
            tv1.ContextMenuStrip = cms1
        End If
    End Sub
    

    If the state isnt known until the moment the menu is needed, re/assign the menu in the MouseDown event for the TreeView:

    If e.Button = Windows.Forms.MouseButtons.Right Then
        If chkShow2.Checked Then
            tv1.ContextMenuStrip = cms2
        Else
            tv1.ContextMenuStrip = cms1
        End If
    End If
    

    You can also show the menu manually, rather than assign it to the control:

    Private Sub tv1_MouseDown(sender ...
        If e.Button = Windows.Forms.MouseButtons.Right Then
            If chkShow2.Checked Then
                cms2.Show(tv1, e.Location)
            Else
                cms1.Show(tv1, e.Location)
            End If
        End If
    End Sub
    

    Would it also be possible to append a number to the contextMenuStrip item?

    Yes. You can add/change or delete menu items before it shows. For instance, if you had nodes {A, B, C}, and wanted to implement a Move To... item, when it opens over and item in node B, disable that destination.