You have to do this yourself. It's a bit of a pain. Basic flow is this...
- Create a global boolean called contextMenuAllowed.
- Subscribe to
MouseDown
event for theListView
. Do aHitTest
on theListView
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. - Subscribe to
MouseUp
event for theListView
. If it is the right mouse button, set contextMenuAllowed to false. - Subscribe to
Opening
event for theContextMenu
/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;
}
}