Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

NotifyIcon right click multiplies dynamic contextmenu items on click

Status
Not open for further replies.

Maven4Champ

Technical User
Jun 16, 2004
154
Hello everyone,

Here is the code I have which is used to dnyamically build a contextmenu and related items. My problem is that on the first right-click, nothing happens. On the second right-click, the menu finally appears but with the dynamic items repeated twice. The next right-click refreshes the menu and triples the items. It has to be something in my While or For Each where I am not clearing out the array properly or not terminating the loop control properly. Any assistance is GREALTLY appreciated!

Code:
    Private Sub NotifyIcon1_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles NotifyIcon1.MouseClick
        If Not e.Button = Windows.Forms.MouseButtons.Right Then Exit Sub
        With My.Computer.Screen.WorkingArea
            Call NotifyIcon1_Visible()
        End With
    End Sub

    Private Sub NotifyIcon1_Visible() '(ByVal sender As System.Object, ByVal e As System.EventArgs) ' Handles NotifyIcon1.ButtonClick
        Dim cms As ContextMenuStrip = Me.DynamicMenuStrip
        Dim sMenu() As String
        Dim Conn As SqlConnection = New SqlConnection(AppEnvLauncher.My.MySettings.Default.AppSiteConn)
        Dim sQry As String
        sQry = ""
        sQry = "SELECT DISTINCT Env_Name, DisplayOrder FROM dbo.Instances WHERE (Display < '1') and env_name <> 'DSCPRD' ORDER BY DisplayOrder ASC;"
        Dim dbCommand As New SqlCommand(sQry, Conn)
        Conn.Open()
        Dim sMenuRD As SqlDataReader = dbCommand.ExecuteReader()
        Dim readerData As New System.Text.StringBuilder

        ReDim Preserve sMenu(0)
        Dim i As Integer

        If sMenuRD.HasRows Then
            i = 0
            While sMenuRD.Read()
                ReDim Preserve sMenu(i)
                sMenu(i) = sMenuRD("Env_Name")
                i = i + 1
            End While
        End If

        For Each sMn As String In sMenu
            cms.Items.Add(sMn, Nothing, New System.EventHandler(AddressOf SelectedChildMenu_OnClick))
        Next

        sMenuRD.Close()

        If (Not sMenuRD Is Nothing) Then
            sMenuRD.Close()
        End If
        Conn.Close()
    End Sub
 
Well everyone,

I figured part of this out by adding a clear and refresh to my code, specifically for the menu display.

I would say however that I still have an issue - I was planning to pass a URL to each of the buttons programatically. So OnClick of each list item, open a browser - this isn't working as expected as the code actually loops through each record so clicking on one item actually loops for all 10 records in my list.

With that said, is there a programmatic way to assign a dynamic On Click value to a dynamically generated list of context menu items?
 
Yes. You use AddHandler.

-I hate Microsoft!
-Forever and always forward.
-My kingdom for a edit button!
 
I've not added a ContextMenuStrip like you did above so I didn't notice, but this:
Code:
cms.Items.Add(sMn, Nothing, New System.EventHandler(AddressOf SelectedChildMenu_OnClick))
Already does that.

Did you mean you wanted to dynamically generate the code of an event? If so there is no reason to. You might post the code for your click event. Why are you looping through all your records? Do you look for the record assigned to the menu item and the get the URL? If all you are doing is returning the URL then really you should have already done that when you made the menu item. You could assign it to its tag property or something. You could use the ToolTipText so that way they would also know what URL it was going to before they clicked.

Another thing is unless your database is constantly being updated then I wouldn't call it every time you make the drop down. Instead call it only once when you first create the NotifyIcon.

-I hate Microsoft!
-Forever and always forward.
-My kingdom for a edit button!
 
Sorwen,

Well-noted. I made some changes last night and I am actually utilizing the ClickedItem.Text value do grab what was clicked and pass it to my Sub routine which catches the URL - all works as needed and doing this actually reduced my code a bit.

As for generating the menu each time, I went through that logic since we would take an instance down at times and another function I have written will drop that db off the list if we do not get a proper response from the server itself via the function.

I do like the ToolTipText idea and will look into seeing how I can use my SqlDataReader to add that as a Tool Tip to each of the instances.

My remaining challenge at this point is to get the function working as needed and then concatenate the output result of the function in with the env_Name to signify UP or DOWN. I have additional logic written to allow the user to decide in their app settings whether or not they want to see ALL instances or only UP instances (hidding/removing the DOWN instances). That is for another time I suppose...
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top