Psst! Did you know DevelopmentNow is a mobile web site design agency?

Contact us for help mobilizing your site, or to sign up for our beta Mobile Web SDK!
all groups > c# > december 2009 >

c# : Location of Context Menu in Listview


O.B.
3/29/2008 1:11:15 PM
Assume a context menu is associated with a listview. Upon opening the
context menu, is there a way to determine which row in the listview
O.B.
3/29/2008 5:20:53 PM
[quoted text, click to view]

O.B.
3/29/2008 5:24:02 PM
[quoted text, click to view]

I can override the MouseDown within the ListView and check to see if it
is a right-click, but then what? Is there a quick way to determine
which item was right-clicked?
Joe Cool
3/29/2008 8:50:45 PM
On Sat, 29 Mar 2008 13:11:15 -0700 (PDT), "O.B."
[quoted text, click to view]

By default, the item that was selected. If none is selected, and you
right click in an area where there are no items, it appears with the
Lasse_Vågsæther_Karlsen
3/29/2008 9:16:30 PM
[quoted text, click to view]

I think you can override the MouseDown event to handle that before the
menu pops up.

--
Lasse Vågsæther Karlsen
mailto:lasse@vkarlsen.no
http://presentationmode.blogspot.com/
vvnraman
3/30/2008 1:07:54 AM
[quoted text, click to view]

Yes...
There are two ways in which you can achieve this.
First you'll have to handle the MouseDown event of the ListView
control.
Suppose you have these three options in the context menu
Copy
Paste
Delete

The event handlers for these will not be called when the user right
clicks on the ListView and the context menu appears but the MouseDown
event will fire on a right click.

Now you can use the method GetChildAt(int x, int y)
or
HitTest(int x, int y)
to find out the exact listViewItem.
HitTest is a better method to use as it will give you the subitem if
any, when the sub item was clicked.

The only drawback of these is that if the user right clicks on a
ListViewItem but not on the text which is displayed there then it
doesn't works.

I wrote a small program and its working fine.
I'll copy paste the code here.
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);
JB
12/10/2009 1:34:10 PM
For anyone googling this link there is a simpler way which is to build the complete context menu with all options using the Designer in VS and the control the visibility of the item before it is displayed, as follows:


private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
{
Point mousePoint = this.PointToClient(Control.MousePosition);

ListViewItem lvi = GetItemAt(mousePoint.X, mousePoint.Y);
if (lvi != null)
{
this.toolStripMenuItemOpen.Visible = (lvi.Tag is TypeXXXXXXX);
this.toolStripMenuItemProperties.Visible = true;
}
else
{
this.toolStripMenuItemOpen.Visible = false;
this.toolStripMenuItemProperties.Visible = false;

}

}

From http://www.developmentnow.com/g/36_2008_3_0_0_1056560/Location-of-Context-Menu-in-Listview.htm

Posted via DevelopmentNow.com Groups
AddThis Social Bookmark Button