ContextMenu Opening Event and Mouse Location

O

O.B.

I have a ListView (entityListView) with a ContextMenu (contextMenu).
Overriding the Opening event of the ContextMenu, I'm trying to ensure
that the ContextMenu does not appear if it not right-clicked over an
existing item in the list view. In the code below, it appears that
the Y location is still wrong, off by about 30 pixels or so. Is there
a better way to do this?


private void OpenContextMenu(object sender,
System.ComponentModel.CancelEventArgs e)
{
ContextMenuStrip contextMenu = (ContextMenuStrip)sender;

ListViewItem selectedItem = entityListView.GetItemAt(0,
temp.Location.Y -
temp.SourceControl.Parent.Location.Y -
temp.SourceControl.Location.Y);

if (selectedItem == null)
{
e.Cancel = true;
}
else
{
e.Cancel = false;
}
}
 
V

vvnraman

I have a ListView (entityListView) with a ContextMenu (contextMenu).
Overriding the Opening event of the ContextMenu, I'm trying to ensure
that the ContextMenu does not appear if it not right-clicked over an
existing item in the list view. In the code below, it appears that
the Y location is still wrong, off by about 30 pixels or so. Is there
a better way to do this?

private void OpenContextMenu(object sender,
System.ComponentModel.CancelEventArgs e)
{
ContextMenuStrip contextMenu = (ContextMenuStrip)sender;

ListViewItem selectedItem = entityListView.GetItemAt(0,
temp.Location.Y -
temp.SourceControl.Parent.Location.Y -
temp.SourceControl.Location.Y);

if (selectedItem == null)
{
e.Cancel = true;
}
else
{
e.Cancel = false;
}

}

Hi O.B.
You haven't written how you're getting the position of the Mouse.
If you're using Control.MousePostion property it gives you the the
Screen coordinates by default.
You'll have to use Control.PointToClient() method to convert it to the
actual client coordinates.
That should give you its actual postion.

I wrote a small program to test this. I changed it a little bit by
which i mean when the user presses on an empty area, the context menu
is just Copy, Paste, Cut and Delete and when he clicks on a
ListViewItem, the item is also added to the context menu such as Copy
file1.txt, etc...

Add a ListView and a ContextMenuStrip to your form.
Add Copy, Paste, Cut, Delete as the four menu items.
Set the FullRowSelected of the ListView to true. (Necessary)
Set the GridLines to true.
Set the View to Details.

Here's the code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace ContextMenuListViewItem
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
InitializeUserComponent();
}
private void InitializeUserComponent()
{
ListViewItem listViewItem1 = new
System.Windows.Forms.ListViewItem(new string[] {
"file1.txt",
"Documents",
"29 Kb",
"Text File"}, -1);
ListViewItem listViewItem2 = new
System.Windows.Forms.ListViewItem(new string[] {
"mypic.jpeg",
"My Pictures",
"387 Kb",
"JPEG File"}, -1);
ListViewItem listViewItem3 = new
System.Windows.Forms.ListViewItem(new string[] {
"Terminator III.avi",
"My Movies",
"700 Mb",
"AVI File"}, -1);
ListViewItem listViewItem4 = new
System.Windows.Forms.ListViewItem(new string[] {
"Help.chm",
"My eBooks",
"12 Mb",
"CHM File"}, -1);

ColumnHeader columnHeader1 = new
System.Windows.Forms.ColumnHeader();
columnHeader1.Text = "File Name";
columnHeader1.Width = 111;
ColumnHeader columnHeader2 = new
System.Windows.Forms.ColumnHeader();
columnHeader2.Text = "Folder";
columnHeader2.Width = 126;
ColumnHeader columnHeader3 = new
System.Windows.Forms.ColumnHeader();
columnHeader3.Text = "Size";
ColumnHeader columnHeader4 = new
System.Windows.Forms.ColumnHeader();
columnHeader4.Text = "Type";
columnHeader4.Width = 108;

this.listView1.Columns.AddRange(new
System.Windows.Forms.ColumnHeader[] {
columnHeader1,
columnHeader2,
columnHeader3,
columnHeader4});

this.listView1.ContextMenuStrip = this.contextMenuStrip1;

this.listView1.Items.AddRange(new
System.Windows.Forms.ListViewItem[] {
listViewItem1,
listViewItem2,
listViewItem3,
listViewItem4});

}
private ListViewItem lvItem = null;

private void contextMenuStrip1_Opening(object sender,
CancelEventArgs e)
{
// If its a right click
if(!MousePosition.IsEmpty)
{
Point p = PointToClient(new Point(MousePosition.X,
MousePosition.Y));

// Using HitTest
/*//
ListViewHitTestInfo lvhtInfo =
this.listView1.HitTest(p);
if (lvhtInfo != null)
{
lvItem = lvhtInfo.Item;
StringBuilder sb = new StringBuilder();
sb.AppendFormat("{0}\r\n", p.ToString());
sb.AppendFormat("{0}\r\n", lvhtInfo.ToString());
if (lvhtInfo.Item != null)
{
sb.AppendFormat("{0}\r\n",
lvhtInfo.Item.ToString());
}
if (lvhtInfo.SubItem != null)
{
sb.AppendFormat("{0}\r\n",
lvhtInfo.SubItem.ToString());
}
textBox1.Text = sb.ToString();
}
//*/
// Using GetItemAt
//*//
ListViewItem currLvItem =
this.listView1.GetItemAt(p.X, p.Y);
if (currLvItem != null)
{
lvItem = currLvItem;
StringBuilder sb = new StringBuilder();
sb.AppendFormat("{0}\r\n", p.ToString());
sb.AppendFormat("{0}\r\n", currLvItem.ToString());
sb.AppendFormat("{0}\r\n", currLvItem.Text);
if (currLvItem.SubItems != null)
{
foreach (ListViewItem.ListViewSubItem
lvSubItem in currLvItem.SubItems)
{
sb.AppendFormat("{0}\r\n",
lvSubItem.Text);
}
}
textBox1.Text = sb.ToString();
}
//*/
}
contextMenuStrip1.Items.Clear();
ToolStripMenuItem tsmItem = null;
if (lvItem != null)
{
tsmItem = new ToolStripMenuItem();
tsmItem.Text = "Copy " + lvItem.Text;
contextMenuStrip1.Items.Add(tsmItem);
tsmItem = new ToolStripMenuItem();
tsmItem.Text = "Paste";
contextMenuStrip1.Items.Add(tsmItem);
tsmItem = new ToolStripMenuItem();
tsmItem.Text = "Cut " + lvItem.Text;
contextMenuStrip1.Items.Add(tsmItem);
tsmItem = new ToolStripMenuItem();
tsmItem.Text = "Delete " + lvItem.Text;
contextMenuStrip1.Items.Add(tsmItem);
}
else
{
tsmItem = new ToolStripMenuItem();
tsmItem.Text = "Copy";
contextMenuStrip1.Items.Add(tsmItem);
tsmItem = new ToolStripMenuItem();
tsmItem.Text = "Paste";
contextMenuStrip1.Items.Add(tsmItem);
tsmItem = new ToolStripMenuItem();
tsmItem.Text = "Cut";
contextMenuStrip1.Items.Add(tsmItem);
tsmItem = new ToolStripMenuItem();
tsmItem.Text = "Delete";
contextMenuStrip1.Items.Add(tsmItem);
}
}
}

}

You'll notice that when you use GetItemAt(), the ListViewSubItem are
not taken into account.

Hope this helps
Prateek Raman
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top