vb.netwinformstoolstripmenu

Selecting 1 Tool Strip Menu Item at any one time


I have a Tool strip menu with 4 options. The options are degrees of screen rotation. (0, 90, 180, 270) I am trying to select only 1 of these and keep it selected. When I choose one then another, both are ticked (selected). I have searched and found some solutions but only this works for me. I have used the click event for each option to clear the ones not chosen like below.

Private Sub DegreesToolStripMenuItem6_Click(sender As Object, e As EventArgs) Handles DegreesToolStripMenuItem6.Click

    DegreesToolStripMenuItem6.Checked = True
    DegreesToolStripMenuItem7.Checked = False
    DegreesToolStripMenuItem8.Checked = False
    DegreesToolStripMenuItem9.Checked = False

End Sub

This sub is in my code 4 times to make it work but i'm sure there must be a cleaner, easier way to do this.

I have found online some other solutions but I can't seem to make it work, this one kind of makes sense like it should work but I can't figure it out

Private Sub DegreesToolStripMenuItem6_CheckedChanged(sender As Object, e As EventArgs) Handles DegreesToolStripMenuItem6.CheckedChanged, _
    DegreesToolStripMenuItem7.CheckedChanged, _
    DegreesToolStripMenuItem8.CheckedChanged, _
    DegreesToolStripMenuItem9.CheckedChanged

    Dim currentItem As ToolStripMenuItem = TryCast(sender, ToolStripMenuItem)

    If currentItem IsNot Nothing AndAlso currentItem.Checked Then
        Dim menu As ContextMenuStrip = TryCast(currentItem.Owner, ContextMenuStrip)

        If menu IsNot Nothing Then
            'The current item has just been checked so uncheck all other items on the same context menu strip.
            For Each item As ToolStripMenuItem In menu.Items
                If item IsNot currentItem Then
                    item.Checked = False
                End If
            Next item
        End If
    End If

End Sub

the toolstrip menu reads like this

-PreferedRotationToolStripMenuItem-DegreesToolStripMenuItem6
                                   DegreesToolStripMenuItem7
                                   DegreesToolStripMenuItem8
                                   DegreesToolStripMenuItem9

Thanks for your time and looking forward to any help you guys can give.


Solution

  • Set CheckOnClick to True for each menu item, which I'm guessing you already have. This code worked for me:

    Private Sub ToolStripMenuItems_CheckedChanged(sender As Object, e As EventArgs) Handles DegreesToolStripMenuItem9.CheckedChanged,
                                                                                            DegreesToolStripMenuItem8.CheckedChanged,
                                                                                            DegreesToolStripMenuItem7.CheckedChanged,
                                                                                            DegreesToolStripMenuItem6.CheckedChanged
        Dim currentMenuItem = DirectCast(sender, ToolStripMenuItem)
    
        If currentMenuItem.Checked Then
            Dim menu = DirectCast(currentMenuItem.Owner, ContextMenuStrip)
    
            For Each menuItem In menu.items.Cast(Of ToolStripMenuItem)
                menuItem.Checked = menuItem Is currentMenuItem
            Next
        End If
    End Sub
    

    Here's a slight variation that avoids checking the already checked current item:

    Private Sub ToolStripMenuItems_CheckedChanged(sender As Object, e As EventArgs) Handles DegreesToolStripMenuItem9.CheckedChanged,
                                                                                            DegreesToolStripMenuItem8.CheckedChanged,
                                                                                            DegreesToolStripMenuItem7.CheckedChanged,
                                                                                            DegreesToolStripMenuItem6.CheckedChanged
        Dim currentMenuItem = DirectCast(sender, ToolStripMenuItem)
    
        If currentMenuItem.Checked Then
            Dim menu = DirectCast(currentMenuItem.Owner, ContextMenuStrip)
    
            For Each menuItem In menu.Items.Cast(Of ToolStripMenuItem).Except({currentMenuItem})
                menuItem.Checked = False
            Next
        End If
    End Sub
    

    The code above works if you have added the items to a ContextMenuStrip. If you have added them directly to an item on a MenuStrip then change this:

    Dim menu = DirectCast(currentMenuItem.Owner, ContextMenuStrip)
    

    to this:

    Dim menu = DirectCast(currentMenuItem.Owner, ToolStripDropDownMenu)