contextmenustrip populate with the .opening event

Zexor

Well-known member
Joined
Nov 28, 2008
Messages
520
Programming Experience
3-5
i populate the items in the contextmenustrip during runtime with the .opening event. When i go do the right click to open the menu, first click nothing happen, 2nd click the menu open in the upper left corner, 3rd click it opens on my mouse pointer, everything works perfectly after the 3rd click. Is there a way to make it so that it works on the first click?
 
VB.NET:
Private Sub cmsFile_Opening(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles cmsFile.Opening
        With cmsFile.Items
            .Clear()
            .Add("Scan", Nothing, AddressOf cmsFile_Click)
            .Add("Update", Nothing, AddressOf cmsFile_Click)
            .Add("-")
            .Add("Exit", Nothing, AddressOf cmsFile_Click)
        End With
End Sub
 
It doesn't make any sense that you are populating a menu in code like that. There's nothing dynamic about that code so why can't you just add those items in the designer? The only reason to build a menu in code like that is that there is something that you don't know until run time, e.g. the items are coming from a database. In your case, you should simply add the items in the designer.
 
But thats not the problem i am trying to solve. I have others that need to do it dynamically. That was just an example. The problem is it takes 3 clicks initially to generate the menu and display it at the correct location.

VB.NET:
    Private Sub cmsFile_Opening(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles cmsFile.Opening
        With cmsFile.Items
            .Clear()
            If TreeView1.SelectedNode IsNot Nothing Then
                If TreeView1.SelectedNode.Level = 0 Then
                    .Add("&Delete " + TreeView1.SelectedNode.Text, Nothing, AddressOf cmsFile_Click)
                Else
                    .Add("&Mark " + TreeView1.SelectedNode.Text + " as last seen.", Nothing, AddressOf cmsFile_Click)
                End If
                .Add("-")
            End If
            .Add("&About", Nothing, AddressOf cmsFile_Click)
        End With
    End Sub
 
Last edited:
Ok i figure out how to eliminate the first click. I just call cmsFile_Opening during load time. Now its down to 2 clicks for it to display at the correct location.
 
I just tried your original code and, while it didn't take three goes to display the menu, it did take two. The first thing I did was open the documentation for the ContextMenuStrip.Opening event and read the page. It includes a an example and this is part of it:
VB.NET:
   ' This event handler is invoked when the ContextMenuStrip
   ' control's Opening event is raised. It demonstrates
   ' dynamic item addition and dynamic SourceControl 
   ' determination with reuse.
    Sub cms_Opening(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs)

        ' Acquire references to the owning control and item.
        Dim c As Control = fruitContextMenuStrip.SourceControl
        Dim tsi As ToolStripDropDownItem = fruitContextMenuStrip.OwnerItem 

        ' Clear the ContextMenuStrip control's 
        ' Items collection.
        fruitContextMenuStrip.Items.Clear()

        ' Check the source control first.
        If (c IsNot Nothing) Then
            ' Add custom item (Form)
            fruitContextMenuStrip.Items.Add(("Source: " + c.GetType().ToString()))
        ElseIf (tsi IsNot Nothing) Then
            ' Add custom item (ToolStripDropDownButton or ToolStripMenuItem)
            fruitContextMenuStrip.Items.Add(("Source: " + tsi.GetType().ToString()))
        End If

        ' Populate the ContextMenuStrip control with its default items.
        fruitContextMenuStrip.Items.Add("-")
        fruitContextMenuStrip.Items.Add("Apples")
        fruitContextMenuStrip.Items.Add("Oranges")
        fruitContextMenuStrip.Items.Add("Pears")

        [color=#FF0000]' Set Cancel to false. 
        ' It is optimized to true based on empty entry.
        e.Cancel = False[/color]
    End Sub
I added a line to your code setting e.Cancel to False and, sure enough, the menu displayed on the first click. It appears that the event is cancelled by default if the menu has no items initially so, if you're adding items, you need to uncancel it to ensure the menu is displayed.

Please let this be a lesson to ALWAYS read the documentation first. I've posted that advice so many times in my seven years as a member here and has it ignored more often than not and even been abused for it at times. Given that you could have answered your own question in less than a minute, this is a perfect example of why it's the best advice a .NET developer can get and you're wasting your own time if you ignore it.
 
i attached the menu to the notify icon and the listview. It is still taking 2 clicks to get the menu to display under the mouse arrow. The first click will display the menu at the upper left corner of the screen if i click on the notify icon. It will display at the menustrip if i right click the listview. Then the 2nd click will display under the mouse pointer.
 
I just created a new WinForms application project and added a ListView, NotifyIcon and ContextMenuStrip. In the designer, I assigned the ContextMenuStrip instance to the ContextMenuStrip property of both the ListView and the NotifyIcon. I then added this code:
VB.NET:
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    NotifyIcon1.Icon = Me.Icon
End Sub

Private Sub ContextMenuStrip1_Opening(sender As System.Object, e As System.ComponentModel.CancelEventArgs) Handles ContextMenuStrip1.Opening
    With ContextMenuStrip1.Items
        .Clear()
        .Add("First", Nothing, AddressOf SomeToolStripMenuItem_Click)
        .Add("Second", Nothing, AddressOf SomeToolStripMenuItem_Click)
        .Add("-")
        .Add("Third", Nothing, AddressOf SomeToolStripMenuItem_Click)
    End With

    e.Cancel = False
End Sub

Private Sub SomeToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs)
    MessageBox.Show(DirectCast(sender, ToolStripMenuItem).Text)
End Sub
When I ran the project, if I right-clicked on the ListView first then everything worked as expected. The menu appeared with it's top-left corner under the cursor and then when I right-clicked the NotifyIcon the menu appeared with its bottom-right corner under the cursor. If I right-clicked on the NotifyIcon first then it didn't work quite the same but almost. On the first right-click on the NotifyIcon the menu appeared with the cursor at the top-middle of the menu, but then appeared as before for each subsequent right-click.

This all happened using VS 2010 and .NET 4.0 on Windows 8 Pro. I can't speak for any differences that might occur on another OS.
 
I notice if i remove the cmsFile from the menustrip, everything works correctly. But when i put cmsFile under FileToolStripMenuItem's Dropdown, it will initially take one more click to get the menu under the mouse.
I also notice if i remove it from design and then add it back during form load, everything works correctly as well. Is there any reason for that?
 
This is the first we're hearing about FileToolStripMenuItem. Maybe you should give us the whole story. Give us a FULL and CLEAR description of the problem and then we may be able to help.
 
ok, i started with a new windows forms application.
Added a Listview, MenuStrip, ContextMenuStrip.
On the MenuStrip1, i typed "File" as the first menu.
Then on the FileToolStripMenuItem.DropDown i assigned ContextMenuStrip1.
Listview1.ContextMenuStrip i assigned ContextMenuStrip1 as well.
Then i put this on the code.
VB.NET:
    Private Sub ContextMenuStrip1_Click(sender As Object, e As System.EventArgs) Handles ContextMenuStrip1.Click


    End Sub


    Private Sub ContextMenuStrip1_Opening(sender As System.Object, e As System.ComponentModel.CancelEventArgs) Handles ContextMenuStrip1.Opening
        With ContextMenuStrip1.Items
            .Clear()
            .Add("Exit", Nothing, AddressOf ContextMenuStrip1_Click)
        End With
        e.Cancel = False
    End Sub

I created this program 3 times, first 2 times the menu will open under the menustrip when i right click the listview on the first click. But when i recreated this the 3 time, everything works fine on the first click. I have no idea why and what i did different.
During the 2nd time, i think it was working fine until i added the form load and its not fine anymore.
i cant seem to repeat it after that, weird. But on my other program, it is still doing it if i set it at design time.
 
Back
Top