Laden...

Item identifizieren, für das ein Contextmenu geöffnet wurde

Erstellt von ErfinderDesRades vor 14 Jahren Letzter Beitrag vor 14 Jahren 4.271 Views
ErfinderDesRades Themenstarter:in
5.299 Beiträge seit 2008
vor 14 Jahren
Item identifizieren, für das ein Contextmenu geöffnet wurde

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.