Question

I have a list view of items and I'd like it so that when the user right-clicks on one of the items it would bring up a contextmenustrip with a few options or tasks the user could perform, BUT I would like it to only bring the contextmenustrip when an item is r-clicked, as opposed to white space. Is there a setting for this?

Was it helpful?

Solution

You have to do this yourself. It's a bit of a pain. Basic flow is this...

  1. Create a global boolean called contextMenuAllowed.
  2. Subscribe to MouseDown event for the ListView. Do a HitTest on the ListView using the coordinates of the mouse (e.X and e.Y). If they hit on an item AND it was a right click, set contextMenuAllowed to true.
  3. Subscribe to MouseUp event for the ListView. If it is the right mouse button, set contextMenuAllowed to false.
  4. Subscribe to Opening event for the ContextMenu/ContextMenuStrip. If contextMenuAllowed is false, set e.Cancel to true and return. This is stop the context menu from actually opening.

It's a bit of a pain but easily done and the user will never know the difference.

Here is an example where I just made a new custom control that will do exactly what you are looking for:

using System;
using System.Windows.Forms;

public class CustomListView : ListView
{
    private bool contextMenuAllowed = false;

    public override ContextMenuStrip ContextMenuStrip
    {
        get
        {
            return base.ContextMenuStrip;
        }
        set
        {
            base.ContextMenuStrip = value;
            base.ContextMenuStrip.Opening += ContextMenuStrip_Opening;
        }
    }   

    public CustomListView()
    {
    }

    protected override void OnMouseDown(MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Right)
        {
            ListViewHitTestInfo lvhti = HitTest(e.X, e.Y);
            if (lvhti.Item != null)
            {
                contextMenuAllowed = true;
            }
        }

        base.OnMouseDown(e);
    }

    protected override void OnMouseUp(MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Right)
        {
            contextMenuAllowed = false;
        }

        base.OnMouseUp(e);
    }

    private void ContextMenuStrip_Opening(object sender, System.ComponentModel.CancelEventArgs e)
    {
        if (!contextMenuAllowed)
            e.Cancel = true;
    }
}

OTHER TIPS

There is a very simple way to do this:

  1. Assign the context menu to the ContextMenuStrip property of the ListView object (this can be done in the GUI settings)

  2. Handle the Opening event of the context menu object and do a check inside the event handler, whether any item of the ListView object is selected. Cancel the event if this is not the case:

    If myListView.SelectedItems.Count = 0 Then e.Cancel = True

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top