שתף באמצעות


context menu on selected listiew items in vb.net

Question

Monday, May 20, 2013 5:29 PM

I am using a listview control and trying to achieve a context menu on the item being selected. But the menu is appearing in the blank area of the form....

here is my code...

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.Controls.Add(lv)
        lv.View = View.Details
        lv.Dock = DockStyle.Fill
        il.ColorDepth = ColorDepth.Depth42Bit
        lv.SmallImageList = il
        lv.Columns.Add("Button Text", 300, HorizontalAlignment.Left)
        lv.Columns.Add("PID", 50, HorizontalAlignment.Left)
        lv.Columns.Add("Process Path", 600, HorizontalAlignment.Left)
        Dim things As List(Of TrayButton) = TrayHelper.Tray.GetTrayButtons()
        For Each b As TrayButton In things
            If b.Icon IsNot Nothing Then
                il.Images.Add(b.TrayIndex.ToString, b.Icon)
            Else
                ' When we can't find an icon, the listview will display this form's one.
                ' You could try to grab the icon from the process path I suppose. 
                il.Images.Add(b.TrayIndex.ToString, Me.Icon)
            End If
            Dim lvi As New ListViewItem(b.Text)
            lvi.SubItems.Add(b.ProcessIdentifier.ToString)
            lvi.SubItems.Add(b.ProcessPath)
            lvi.ImageKey = b.TrayIndex.ToString
            lv.Items.Add(lvi)
        Next

        Dim mnuContextMenu As New ContextMenu()
        lv.ContextMenu = mnuContextMenu
        Dim mnuItemHide As New MenuItem()
        Dim mnuItemExit As New MenuItem()
        mnuItemHide.Text = "&Hide"
        mnuItemExit.Text = "&Exit"
        mnuContextMenu.MenuItems.Add(mnuItemHide)
        mnuContextMenu.MenuItems.Add(mnuItemExit)
    End Sub

All replies (13)

Monday, May 20, 2013 6:16 PM ✅Answered

Hi,

 You could change your code a little and add the lv_MouseDown event. When you right click on the listview this will select the item under the mouse and show the contextmenu if there is an item under the mouse. If not then the contextmenu does not show.

Public Class Form1
    Dim mnuContextMenu As New ContextMenu() 'Moved this to be declared as global

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.Controls.Add(lv)
        lv.View = View.Details
        lv.Dock = DockStyle.Fill
        lv.FullRowSelect = True 'Added this but, you don`t need it if you don`t want it
        il.ColorDepth = ColorDepth.Depth42Bit
        lv.SmallImageList = il
        lv.Columns.Add("Button Text", 300, HorizontalAlignment.Left)
        lv.Columns.Add("PID", 50, HorizontalAlignment.Left)
        lv.Columns.Add("Process Path", 600, HorizontalAlignment.Left)
        Dim things As List(Of TrayButton) = TrayHelper.Tray.GetTrayButtons()
        For Each b As TrayButton In things
            If b.Icon IsNot Nothing Then
                il.Images.Add(b.TrayIndex.ToString, b.Icon)
            Else
                ' When we can't find an icon, the listview will display this form's one.
                ' You could try to grab the icon from the process path I suppose. 
                il.Images.Add(b.TrayIndex.ToString, Me.Icon)
            End If
            Dim lvi As New ListViewItem(b.Text)
            lvi.SubItems.Add(b.ProcessIdentifier.ToString)
            lvi.SubItems.Add(b.ProcessPath)
            lvi.ImageKey = b.TrayIndex.ToString
            lv.Items.Add(lvi)
        Next

        'lv.ContextMenu = mnuContextMenu 'Don`t need to add if done this way
        Dim mnuItemHide As New MenuItem()
        Dim mnuItemExit As New MenuItem()
        mnuItemHide.Text = "&Hide"
        mnuItemExit.Text = "&Exit"
        mnuContextMenu.MenuItems.Add(mnuItemHide)
        mnuContextMenu.MenuItems.Add(mnuItemExit)
    End Sub

    Private Sub lv_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles lv.MouseDown
        If e.Button = Windows.Forms.MouseButtons.Right Then
            If lv.GetItemAt(e.X, e.Y) IsNot Nothing Then
                lv.GetItemAt(e.X, e.Y).Selected = True
                mnuContextMenu.Show(lv, New Point(e.X, e.Y))
            End If
        End If
    End Sub
End Class

Monday, May 20, 2013 7:58 PM ✅Answered

@paul ishak...

hey thanks for the advice ;) .... i used your example and the friend method for list view actually accessed the context menu..... but the problem i that i am getting it on the blank area as well...

further help will be appreciated ...

Try this modified version of the other example.

Option Strict On
Public Class Form1
    Friend WithEvents ListView1 As New ListView With {.Parent = Me, .Dock = DockStyle.Fill}
    Friend WithEvents ContextMenu1 As New ContextMenu, HelloMenuItem, WorldMenuItem As MenuItem
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        HelloMenuItem = ContextMenu1.MenuItems.Add("Hello")
        WorldMenuItem = ContextMenu1.MenuItems.Add("World")
        ListView1.Items.AddRange({New ListViewItem("Hello"), New ListViewItem("World")})
    End Sub
    Private Sub Listview1_MouseDown(sender As Object, e As MouseEventArgs) Handles ListView1.MouseDown
        WorldMenuItem.Enabled = False
        HelloMenuItem.Enabled = False
        ListView1.ContextMenu = Nothing
        If ListView1.GetItemAt(e.X, e.Y) Is Nothing Then Exit Sub
        ListView1.ContextMenu = ContextMenu1
        ListView1.SelectedItems.Clear()
        ListView1.GetItemAt(e.X, e.Y).Selected = True
        Select Case ListView1.SelectedItems(0).Text
            Case "Hello" : HelloMenuItem.Enabled = True
            Case "World" : WorldMenuItem.Enabled = True
        End Select
    End Sub
    Private Sub HelloMenuItem_Click(sender As Object, e As EventArgs) Handles HelloMenuItem.Click
        MsgBox("Hello")
    End Sub
    Private Sub WorldMenuItem_Clice(sender As Object, e As EventArgs) Handles WorldMenuItem.Click
        MsgBox("World")
    End Sub
End Class

“If you want something you've never had, you need to do something you've never done.”

Don't forget to mark helpful posts and answers ! Answer an interesting question? Write a new article about it! My Articles

*This post does not reflect the opinion of Microsoft, or its employees.


Monday, May 20, 2013 8:11 PM ✅Answered

actually thanks to both of you...

i combined the suggestions given by both of you......

here is the complete ans....

Option Strict On
Option Explicit On
Option Infer Off

Imports TrayHelper

Public Class Form1
    Dim x1, y1 As Single
    Friend WithEvents lv As New ListView With {.Parent = Me, .Dock = DockStyle.Fill}


    Private il As New ImageList
    Dim nxt As Integer
    Friend WithEvents mnuContextMenu As New ContextMenu() 'Moved this to be declared as global

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.Controls.Add(lv)
        lv.View = View.Details


        il.ColorDepth = ColorDepth.Depth42Bit
        lv.SmallImageList = il
        lv.Columns.Add("Button Text", 300, HorizontalAlignment.Left)
        lv.Columns.Add("PID", 50, HorizontalAlignment.Left)
        lv.Columns.Add("Process Path", 600, HorizontalAlignment.Left)
        Dim things As List(Of TrayButton) = TrayHelper.Tray.GetTrayButtons()
        For Each b As TrayButton In things
            If b.Icon IsNot Nothing Then
                il.Images.Add(b.TrayIndex.ToString, b.Icon)
            Else
                ' When we can't find an icon, the listview will display this form's one.
                ' You could try to grab the icon from the process path I suppose. 
                il.Images.Add(b.TrayIndex.ToString, Me.Icon)
            End If
            Dim lvi As New ListViewItem(b.Text)
            lvi.SubItems.Add(b.ProcessIdentifier.ToString)
            lvi.SubItems.Add(b.ProcessPath)
            lvi.ImageKey = b.TrayIndex.ToString
            lv.Items.Add(lvi)
        Next
        lv.MultiSelect = False
        'lv.ContextMenu = mnuContextMenu 'Don`t need to add if done this way

        lv.FullRowSelect = True 'Added this but, you don`t need it if you don`t want it

        Dim mnuItemHide As New MenuItem()
        Dim mnuItemExit As New MenuItem()
        mnuItemHide.Text = "&Hide"
        mnuItemExit.Text = "&Exit"
        mnuContextMenu.MenuItems.Add(mnuItemHide)
        mnuContextMenu.MenuItems.Add(mnuItemExit)
        mnuItemExit.Visible = True
        mnuItemHide.Visible = True
        
    End Sub

   Private Sub lv_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles lv.MouseDown
        If e.Button = Windows.Forms.MouseButtons.Right Then
            If lv.GetItemAt(e.X, e.Y) IsNot Nothing Then
                lv.GetItemAt(e.X, e.Y).Selected = True
                mnuContextMenu.Show(lv, New Point(e.X, e.Y))
            End If
        End If
    End Sub
End Class

worked like a charm...

thanks once again


Monday, May 20, 2013 6:06 PM

Please try this example to see if it helps you

Option Strict On
Public Class Form1
    Friend WithEvents ListView1 As New ListView With {.Parent = Me, .Dock = DockStyle.Fill}
    Friend WithEvents ContextMenuStrip1 As New ContextMenuStrip, HelloToolStripItem, WorldToolStripItem As ToolStripItem
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        HelloToolStripItem = ContextMenuStrip1.Items.Add("Hello")
        WorldToolStripItem = ContextMenuStrip1.Items.Add("World")
        ListView1.ContextMenuStrip = ContextMenuStrip1
        ListView1.Items.AddRange({New ListViewItem("Hello"), New ListViewItem("World")})
    End Sub
    Private Sub Listview1_MouseDown(sender As Object, e As MouseEventArgs) Handles ListView1.MouseDown
        WorldToolStripItem.Enabled = False : HelloToolStripItem.Enabled = False
        If ListView1.GetItemAt(e.X, e.Y) Is Nothing Then Exit Sub
        ListView1.SelectedItems.Clear()
        ListView1.GetItemAt(e.X, e.Y).Selected = True
        Select Case ListView1.SelectedItems(0).Text
            Case "Hello" : HelloToolStripItem.Enabled = True
            Case "World" : WorldToolStripItem.Enabled = True
        End Select
    End Sub
    Private Sub HelloToolStripItem_Click(sender As Object, e As EventArgs) Handles HelloToolStripItem.Click
        MsgBox("Hello")
    End Sub
    Private Sub WorldToolStripItem_Clice(sender As Object, e As EventArgs) Handles WorldToolStripItem.Click
        MsgBox("World")
    End Sub
End Class

“If you want something you've never had, you need to do something you've never done.”

Don't forget to mark helpful posts and answers ! Answer an interesting question? Write a new article about it! My Articles

*This post does not reflect the opinion of Microsoft, or its employees.


Monday, May 20, 2013 6:29 PM

Thanks...that made the whole row selection instead of only 1st column row selection... but the context menu is not appearing...... i think this code is not raising the event.

Private Sub lv_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles lv.MouseDown
        If e.Button = Windows.Forms.MouseButtons.Right Then
            If lv.GetItemAt(e.X, e.Y) IsNot Nothing Then
                lv.GetItemAt(e.X, e.Y).Selected = True
                mnuContextMenu.Show(lv, New Point(e.X, e.Y))
            End If
        End If
    End Sub

Monday, May 20, 2013 6:49 PM

Try putting a break point on the (If e.Button = ....) line or put a messagebox in there and see if the lv_MouseDown event is being called.

EDIT :  You may also need to add this to the lv properties

lv.MultiSelect = False

Monday, May 20, 2013 7:09 PM

Have you looked at the example I provided? I'm not giving you code strait up, but you should be able to extrapolate a few things from it.

“If you want something you've never had, you need to do something you've never done.”

Don't forget to mark helpful posts and answers ! Answer an interesting question? Write a new article about it! My Articles

*This post does not reflect the opinion of Microsoft, or its employees.


Monday, May 20, 2013 7:21 PM

sorry...but message box is also not firing... if I am adding

lv.Enabled = False

in Form1_Load function, then context menu is appearing...but the row is not selected...but i am getting what i required...but i don't think its useful


Monday, May 20, 2013 7:29 PM

thanks for the response...but this is a contextMenuStrip... and i working with simple context menu..but its worth switching of context menu with case statement but its not working for me, 


Monday, May 20, 2013 7:54 PM

@paul ishak...

hey thanks for the advice ;) .... i used your example and the friend method for list view actually accessed the context menu..... but the problem i that i am getting it on the blank area as well...

further help will be appreciated ...


Monday, May 20, 2013 7:56 PM

thanks for the response...but this is a contextMenuStrip... and i working with simple context menu..but its worth switching of context menu with case statement but its not working for me, 

Granted, but in principal, the example is still the same: here is it updated to a contextmenu, sorry for misreading :)

Option Strict On
Public Class Form1
    Friend WithEvents ListView1 As New ListView With {.Parent = Me, .Dock = DockStyle.Fill}
    Friend WithEvents ContextMenu1 As New ContextMenu, HelloToolStripItem, WorldToolStripItem As MenuItem
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        HelloToolStripItem = ContextMenu1.MenuItems.Add("Hello")
        WorldToolStripItem = ContextMenu1.MenuItems.Add("World")
        ListView1.ContextMenu = ContextMenu1
        ListView1.Items.AddRange({New ListViewItem("Hello"), New ListViewItem("World")})
    End Sub
    Private Sub Listview1_MouseDown(sender As Object, e As MouseEventArgs) Handles ListView1.MouseDown
        Dim Point As Point = ListView1.PointToClient(MousePosition)
        WorldToolStripItem.Enabled = False
        HelloToolStripItem.Enabled = False
        If ListView1.GetItemAt(Point.X, Point.Y) Is Nothing Then Exit Sub
        ListView1.SelectedItems.Clear()
        ListView1.GetItemAt(Point.X, Point.Y).Selected = True
        Select Case ListView1.SelectedItems(0).Text
            Case "Hello" : HelloToolStripItem.Enabled = True
            Case "World" : WorldToolStripItem.Enabled = True
        End Select
    End Sub
    Private Sub HelloToolStripItem_Click(sender As Object, e As EventArgs) Handles HelloToolStripItem.Click
        MsgBox("Hello")
    End Sub
    Private Sub WorldToolStripItem_Clice(sender As Object, e As EventArgs) Handles WorldToolStripItem.Click
        MsgBox("World")
    End Sub
End Class

“If you want something you've never had, you need to do something you've never done.”

Don't forget to mark helpful posts and answers ! Answer an interesting question? Write a new article about it! My Articles

*This post does not reflect the opinion of Microsoft, or its employees.


Monday, May 20, 2013 8:15 PM

actually thanks to both of you...

thanks once again

You're quite welcome :)

“If you want something you've never had, you need to do something you've never done.”

Don't forget to mark helpful posts and answers ! Answer an interesting question? Write a new article about it! My Articles

*This post does not reflect the opinion of Microsoft, or its employees.


Monday, May 20, 2013 8:27 PM

 I have to say sorry because i did not realize you where adding the listview with code. I thought you had one added to the form.  Had i realized that i would have put an AddHandler in. Thats why the MouseDown event was not triggered. Anyways i am glad you got it going.  :)