RememberOfLife RememberOfLife - 2 months ago 15
C# Question

Opening a contextmenu on a listview only if NO item has been clicked

So thanks to many answers on stackoverflow we all know how to open a contextmenu when an item in a listview has been rightclicked. i.e.:

private void listviewItems_MouseClick(object sender, MouseEventArgs e) {
ListView tmp_SenderListView = sender as ListView;
if (e.Button == MouseButtons.Right) {
ListViewItem tmp_SelectedItem = tmp_SenderListView.GetItemAt(e.X, e.Y);
if (tmp_SelectedItem != null) {
tmp_SelectedItem.Selected = true;
contextMenuStripItem.Show(tmp_SenderListView, e.Location);
}
}
}


My goal is to open another (a different) contextmenu when the user clicks inside the listview but does not click on an item but rather the empty space. (preferably does not trigger when clicking on the column header)

My first thoughts were to just test if the above mentioned tmp_SelectedItem was null and thus no item. when I did however insert the else case and switched it around:

private void listviewItems_MouseClick(object sender, MouseEventArgs e) {
ListView tmp_SenderListView = sender as ListView;
if (e.Button == MouseButtons.Right) {
ListViewItem tmp_SelectedItem = tmp_SenderListView.GetItemAt(e.X, e.Y);
if (tmp_SelectedItem == null) {
contextMenuStripNoItem.Show(tmp_SenderListView, e.Location);
}
else {
tmp_SelectedItem.Selected = true;
contextMenuStripItem.Show(tmp_SenderListView, e.Location);
}
}
}


It didn't work, just hasn't opened anything then.
I tried again, this time opening the contextMenuStripNoItem before I tested if an item has been clicked, if that was the case, the contextMenuStripNoItem would be closed and the contextMenuStripItem would open. This did not work either.

I tried with making the contextMenuStripNoItem the main contextMenuStrip of the listView however then it only opened the contextMenuStripNoItem no matter where or at what I clicked inside the listView. For addition I tried closing that assigned contextMenuStrip when an item has been clicked and instead opening the other one. Did not work aswell.

I really don't get why it didn't work with the first two approaches, so after some research to confirm there was no tutorial for this or an already existing question on a forum (atleast as far as I searched and understood), I decided to turn to stackoverflow.

Thanks in advance :)

Answer

Try this (I changed logic a little bit, if you are clicking on an item, it will be selected, so you don't need to check X and Y positions. If checked; show menustrip1 , if not; so right click not performed on items, show menustrip2). You can use Mouse_Up event which triggers all over listbox mouse events. Mouse_Click only works when item got hit.

 private void listView1_MouseUp(object sender, MouseEventArgs e)
        {
            ListView tmp_SenderListView = sender as ListView;
            if (e.Button == MouseButtons.Right)
            {

                if (tmp_SenderListView.SelectedItems.Count > 0)
                {
                    contextMenuStrip1.Show(tmp_SenderListView, e.Location);
                }
                else
                {
                    contextMenuStrip2.Show(tmp_SenderListView, e.Location);
                }
            }
        }

Hope helps,