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?
You have to do this yourself. It's a bit of a pain. Basic flow is this...
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.MouseUp
event for the ListView
. If it is the right mouse button, set contextMenuAllowed to false.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;
}
}