Meist beziehen sich die Aktionen eines ContextMenuItems auf ein bestimmtes ControlItem eines Multi-Item-Controls (Treeview, Listview, DatagridView, Listbox - weitere?).
Im Click-Event dieses MenuItems kann das gemeinte ControlItem aber nicht ohne weiteres identifiziert werden, denn dazu bräuchte man die Mausposition zum Zeitpunkt, als das ContextMenu geöffnet wurde.
Hier also ein ContextMenuStrip-Erbe, der sich diese erf. Zusatz-Information merkt:
using System;
using System.Drawing;
using System.ComponentModel;
namespace System.Windows.Forms {
[System.ComponentModel.DesignerCategory("Code")]
public class ContextMenuEx : ContextMenuStrip {
/// <summary>
/// mousePosition over the control, on which the ContextMenuEx at last was opened
/// </summary>
[ToolboxItem(false)]
public Point OpenClickLocation { get; private set; }
protected override void OnOpened(EventArgs e) {
OpenClickLocation = SourceControl.PointToClient(Control.MousePosition);
base.OnOpened(e);
}
}
}
Man kann damit ebenso im Designer arbeiten, wie mit dem herkömmlichen ContextMenuStrip
Anwendungsbeispiel:
using System;
using System.Windows.Forms;
namespace ContextMenuEx {
public partial class frmContextMenuEx : Form {
//Form mit:
// DataGridView dataGridView1 (4 Columns)
// ContextMenuEx contextMenuX1 (3 ToolStripMenuItem)
// contextMenuX1 ist im Designer als ContextMenuStrip des DataGridViews eingestellt
public frmContextMenuEx() {
InitializeComponent();
this.Location = Screen.PrimaryScreen.WorkingArea.Location;
//DGV befüllen
dataGridView1.RowCount = 15;
for(var y = dataGridView1.Rows.Count; y-- > 0; ) {
for(var x = dataGridView1.ColumnCount; x-- > 0; ) {
dataGridView1[x, y].Value =string.Concat(x, " ", y);
}
}
//alle MenuItem-Clickse auf denselben EventHandler leiten
this.x1ToolStripMenuItem.Click += ContextMenuItem_Click;
this.x2ToolStripMenuItem.Click += ContextMenuItem_Click;
this.x3ToolStripMenuItem.Click += ContextMenuItem_Click;
}
private void ContextMenuItem_Click(object sender, EventArgs e) {
//die DGV-Zelle melden, die den Rechtsklick empfangen hat
var pt = contextMenuX1.OpenClickLocation;
var ht = dataGridView1.HitTest(pt.X, pt.Y);
MessageBox.Show(dataGridView1[ht.ColumnIndex, ht.RowIndex].Value.ToString());
}
}
}
edit: code-Verbesserung: ContextMenuEx.OpenClickLocation gibt die Position jetzt bezogen auf das Source-Control zurück.
Der frühe Apfel fängt den Wurm.