right mouse click on treeview

can anyone show me how to display a context menu after a right mouse click on a specific node. 

This is what i have been able to acheive so far 

If e.Button = MouseButtons.Right Then
            TreeView1.SelectedNode = TreeView1.GetNodeAt(e.X, e.Y)
             If TreeView1.SelectedNode.Text = "Categories" Then
            Dim cmenu As New ContextMenu()
            ' MsgBox(TreeView1.SelectedNode.Text)
            cmenu.MenuItems.Add(amenu)
            Me.ContextMenu = cmenu
                    End If
        End If


Answer this question

right mouse click on treeview

  • Yoshi NorwaY

    well, explorer (at least in XP) does "partial" select, where it actually highlights the node like it's selected, but doesn't actually select it (as in redraw the list on the right side).

    i know it's against the standards to do it that way, but it just feels a lot cleaner to do it that way...i wish it was the default  :P  But you're right...thanx for pointing that out!  :) 

  • Capt

    Thank guys , another question though....I have 2 nodes under a root node...."I want the context menu pop up different menus dependin on the nodei clicked....I tried something like this but it does not work ie the menu pops up and where on the control..

    Private Sub TreeView1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles TreeView1.MouseDown

            If e.Button = MouseButtons.Right Then
                Dim Node As TreeNode = TreeView1.GetNodeAt(e.X, e.Y)
                ' If Not Node Is Nothing Then
                If TreeView1.SelectedNode.Text = "Categories" Then
                    ContextMenu1.Show(TreeView1, New Point(e.X, e.Y))
                End If
            End If


    Private Sub ContextMenu1_Popup(ByVal sender As Object, ByVal e As System.EventArgs) Handles ContextMenu1.Popup
            Dim oItem As MenuItem
            Dim oItem1 As MenuItem
          
            oItem = New MenuItem("Add New Category", AddressOf AddCategory)
            oItem1 = New MenuItem("Add New Media", AddressOf AddMedia)

            With ContextMenu1().MenuItems
                .Clear()
                .Add(oItem)
                .Add(oItem1)
            End With
        End Sub

    Yes and Human Complier I noticed that the eg u gave me was in the mouseUp event, I put mine in the mouse down as i want the pop up to show when i right click the mouse btn. Does it make a difference.

    Thanx

  • suraj victor

    Just sorted my problem out....


    If e.Button = MouseButtons.Right Then
                Dim pt As New Point(e.X, e.Y)
                Dim dnode As TreeNode
                dnode = TreeView1.GetNodeAt(pt)
                TreeView1.SelectedNode = dnode
                Select Case dnode.Text
                    Case "Categories"
                        ContextMenu1.Show(TreeView1, pt)
                    Case "All Media"
                        ContextMenu2.Show(TreeView1, pt)
                End Select
            End If


    Heres the code for any one who wants to do anything similar

  • Doru Sandor

    You need to check to see if dnode is nothing or not, before you run any of the other code.
  • a66fm

    On little bug though



    If e.Button = MouseButtons.Right Then

                Dim pt As New Point(e.X, e.Y)
                Dim dnode As TreeNode
                dnode = TreeView1.GetNodeAt(pt)
                TreeView1.SelectedNode = dnode
                Select Case dnode.Text
                    Case "Categories"
                        ContextMenu1.Show(TreeView1, pt)
                    Case "All Media"
                        ContextMenu2.Show(TreeView1, pt)
                End Select
            End If



    the Application crashes when i click on the tree view control. ie when i click on the control but not a node.  I get this error

     Object reference not set to an instance of an object

    on this line

    Select Case dnode.Text

  • FransRudolf

    Hi i have added more code to the right mouse click event, to respond. When a menu pops up it has 2 options to rename and delete a node.



    If e.Button = MouseButtons.Right Then
                Dim pt As New Point(e.X, e.Y)
                Dim selectedNode As TreeNode

                selectedNode = TreeView1.GetNodeAt(pt)
                'If a node is selected
                If Not selectedNode Is Nothing Then
                    ' TreeView1.SelectedNode = selectedNode
                    Select Case selectedNode.Text
                        Case "Categories"
                            ContextMenu1.Show(TreeView1, pt)
                        Case "All Media"
                            ContextMenu2.Show(TreeView1, pt)
                    End Select
                End If

                If Not selectedNode Is Nothing Then
                    TreeView1.SelectedNode = selectedNode
                    For Each oMedium In myManager.Media
                        Select Case selectedNode.Text
                            Case oMedium.Title
                                ContextMenu3.Show(TreeView1, pt)
                        End Select
                    Next
                End If
            End If




    Private Sub ContextMenu3_Popup(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ContextMenu3.Popup
            Dim renameItem As MenuItem
            Dim deleteItem As MenuItem
            renameItem = New MenuItem("Rename", AddressOf RenameMedia)
            deleteItem = New MenuItem("Delete", AddressOf DeleteMedia)
            With ContextMenu3().MenuItems
                .Clear()
                .Add(renameItem)
                .Add(deleteItem)
            End With
        End Sub






    Private Sub RenameMedia(ByVal sender As Object, ByVal e As System.EventArgs)
            Dim selectedNode As New TreeNode()

            
                If Not selectedNode Is Nothing Then
                TreeView1.SelectedNode = selectedNode
                MsgBox(selectedNode.Text)
            End If
          
        End Sub




    I am trying to get the node i selected in the rename routine so i can update the database. I dont get anythign in the message box though...I think i know why it does not work though, but i not sure....i just think its a wrong way to acheive wht i want but cant think of another way to do this...Can anyone help..



  • Ken Noland

    any ideas on the question above
  • AlpMis

    The .NET treeview does partial select also.  (I think it's called drop_hilite, but I could be wrong).  Anyway, I only brought it up because, for some reason, one of the most frequent complaints I hear about the treeview is that it doesn't select on right-click...  So, I thought I would preempt the accusation that it is a bug in this thread.  ;-)
  • Muhsin Zahid U?ur

    spoton:

    In reply to your earlier question of:

    "Thank guys , another question though....I have 2 nodes under a root node.... I want the context menu pop up different menus dependin on the nodei clicked....I tried something like this but it does not work ie the menu pops up and where on the control....."

    Probably the first thing that comes to mind to most is to do the old <= VB6 thing and have a bunch of "If" statements in a Click event.  Now that VB is a top notch OO language, there is no reason why you can't just create your own derived TreeNode classes and have them preform this themselves.

    About a year ago, I created a .NET application that made extensive use of a custom TreeView and many custom TreeNodes. I found it easiest to create my own BaseTreeNode that had a property called "ContextMenu" (as well as several other properties depending on what the treenode was for). The point is that in my derived TreeView's click event handlers, I was able to just get the "clicked" treenode and then ask for it's context menu directly.  Since some of the default behavior of the BaseTreeNode was to return a "NULL" context menu, I would first check that it was valid and then "Pop it open" if it was.

    The cool thing about this trick is the code to handle the MenuItem click events is self contained in the costom TreeNode classes, which is where is should be.  This is the perfect way to seperate your logic and put it where it should be. Your Forms and TreeView shouldn't have that kind of intimate knowledge of this kind of logic. They are there just to "contain" the visual representation and tell the lower level objects when to do something.

    You could off course make a generic BaseTreeNode and then make a seperate, non-visual class that does the heavy work and then have the TreeNode contain and delegate to this class.  6 of one, half dozen of the other.  They both put the logic where it should be, in the item that knows what it is supposed to do.

    I have quite a bit of code to support this concept that I might be able to pull out if anyone is interested.

    Cal

  • Peter paterson

    Keep in mind that setting the SelectedNode in a treeview off of a right-click does not match standard behavior (e.g. Windows Explorer).  So, you may or may not wish to set the selected node.  I generally keep a private class level variable floating around to keep track of the "Right-Clicked" node.
  • Radhakrishnan

    Well, in your renameMedia method, you have Dim selectedNode As New TreeNode(), so, any subsequent usage of it within the method will result in there being no text.  It might be easier like this:

    Assumptions:
    1-  A Single Context Menu has been defined called MyContextMenu that contains all possible MenuItems.

    2-  The Context Menu from above has been associated to the treeview through the ContextMenu property of the treeview.


    Private m_rClickedNode As TreeNode

    Private Sub MyContextMenu_PopUp(ByVal sender As Object, ByVal e As EventArgs) Handles MyContextMenu.PopUp

    m_rClickedNode = MyTreeView.GetNodeAt(MyTreeView.PointToClient(Cursor.Position))
    'Toggle visibility of menu items here.
    If m_rClickedNode Is Nothing Then
          AllMediaSpecificMenuItem.Visible = False
          CategorySpecificMenuItem.Visible = False
    ElseIf m_rClickedNode.Text = "Categories" Then
          AllMediaSpecificMenuItem.Visible = False
          CategorySpecificMenuItem.Visible = True
    ElseIf m_rClickedNode.Text = "All Media" Then
          AllMediaSpecificMenuItem.Visible = True
          CategorySpecificMenuItem.Visible = False
    End If
    End Sub

    Private Sub AllMediaSpecificMenuItem_Click . .. . 
        If Not m_rClickedNode Is Nothing Then
            Messagebox.Show(m_rClickedNode.Text)
        End If
    End Sub

  • JensN

    I just did this recently...try something like this...


    Private Sub MyTreeView_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyTreeView.MouseUp
    If e.Button = MouseButtons.Right Then
    Dim Node As TreeNode = MyTreeView.GetNodeAt(e.X, e.Y)

    If Not Node Is Nothing Then
    MyTreeView.SelectedNode = Node
    MyContextMenu.Show(MyTreeView, New Point(e.X, e.Y))
    End If
    End If
    End Sub

  • Barbarin

    <quote>
    Yes and Human Complier I noticed that the eg u gave me was in the mouseUp event, I put mine in the mouse down as i want the pop up to show when i right click the mouse btn. Does it make a difference.
    </quote>

    Yes, it does make a difference.  As Jacob was pointing out the "standard" ways of doing things, you should never have anything happen (that I can think of offhand anyway) in MouseDown, always use MouseUp.  It gives the user a chance to basically "cancel" that action if they realize half way through the click they didn't really want to.

    If you click on a button and hold down the mouse, you'll notice the click event doesn't get fired, until you actually release the mouse (MouseUp).  All Controls work in a similar fashion and I would suggest you do the same with yours!  ;) 

  • aylmerj

    be sure to use the code tags in the future when posting code

    <<b>code</b>>
    My.blah = "whoa"
    </<b>code</b>>

  • right mouse click on treeview