ejemplo context c# .net winforms contextmenu

c# - ejemplo - Cómo mostrar un menú contextual al hacer clic con el botón derecho en un elemento del menú



context menu datagridview c# (3)

Probablemente tendrás que p / invocar el método.

[DllImport("user32.dll")] static extern bool TrackPopupMenuEx(IntPtr hmenu, uint fuFlags, int x, int y, IntPtr hwnd, IntPtr lptpm); const int TPM_RECURSE = 0x0001;

Estoy trasladando una aplicación MFC a .NET WinForms. En la aplicación MFC, puede hacer clic con el botón derecho en un menú o en un elemento del menú contextual y mostramos otro menú contextual con elementos de diagnóstico y configuración. Estoy tratando de portar esta funcionalidad a .NET, pero estoy teniendo problemas.

He podido capturar el clic derecho, desactivar el clic del menú subyacente y abrir un menú contextual en la ubicación correcta, pero el menú original desaparece tan pronto como pierde el foco.

En MFC, mostramos el nuevo menú contextual llamando a TrackPopupMenuEx con el indicador TPM_RECURSE .

ContextMenu y las nuevas clases ContextMenuStrip en .NET solo tienen un método Show . ¿Alguien sabe cómo hacer esto en .NET?

EDITAR

He intentado usar TrackPopupMenuEx a través de ap / invoke , pero eso te limita a usar un ContextMenu en lugar de un ContextMenuStrip que parece fuera de lugar en nuestra aplicación. Tampoco funciona correctamente. No funciona con los nuevos MenuStrip y ContextMenuStrip .

También intenté subclasificar ToolStripMenuItem para ver si puedo agregarle un menú contextual. Eso está funcionando para MenuStrip , pero ContextMenuStrip todavía permite que los eventos de clic derecho pasen como clics.



Editar, debido a un comentario:

En:

protected override void OnClick(EventArgs e) { if (SecondaryContextMenu == null || MouseButtons != MouseButtons.Right) { base.OnClick(e); } }

esta parte

MouseButtons != MouseButtons.Right

debería y compila, ya que es una llamada a Control.MouseButtons. Como el Formulario hereda la clase Control, es suficiente llamar directamente a la propiedad MouseButtons.

Espero que esto ayude:

public partial class Form1 : Form { class CustomToolStripMenuItem : ToolStripMenuItem { private ContextMenuStrip secondaryContextMenu; public ContextMenuStrip SecondaryContextMenu { get { return secondaryContextMenu; } set { secondaryContextMenu = value; } } public CustomToolStripMenuItem(string text) : base(text) { } protected override void Dispose(bool disposing) { if (disposing) { if (secondaryContextMenu != null) { secondaryContextMenu.Dispose(); secondaryContextMenu = null; } } base.Dispose(disposing); } protected override void OnClick(EventArgs e) { if (SecondaryContextMenu == null || MouseButtons != MouseButtons.Right) { base.OnClick(e); } } } class CustomContextMenuStrip : ContextMenuStrip { private bool secondaryContextMenuActive = false; private ContextMenuStrip lastShownSecondaryContextMenu = null; protected override void Dispose(bool disposing) { if (disposing) { if (lastShownSecondaryContextMenu != null) { lastShownSecondaryContextMenu.Close(); lastShownSecondaryContextMenu = null; } } base.Dispose(disposing); } protected override void OnControlAdded(ControlEventArgs e) { e.Control.MouseClick += new MouseEventHandler(Control_MouseClick); base.OnControlAdded(e); } protected override void OnControlRemoved(ControlEventArgs e) { e.Control.MouseClick -= new MouseEventHandler(Control_MouseClick); base.OnControlRemoved(e); } private void Control_MouseClick(object sender, MouseEventArgs e) { ShowSecondaryContextMenu(e); } protected override void OnMouseClick(MouseEventArgs e) { ShowSecondaryContextMenu(e); base.OnMouseClick(e); } private bool ShowSecondaryContextMenu(MouseEventArgs e) { CustomToolStripMenuItem ctsm = this.GetItemAt(e.Location) as CustomToolStripMenuItem; if (ctsm == null || ctsm.SecondaryContextMenu == null || e.Button != MouseButtons.Right) { return false; } lastShownSecondaryContextMenu = ctsm.SecondaryContextMenu; secondaryContextMenuActive = true; ctsm.SecondaryContextMenu.Closed += new ToolStripDropDownClosedEventHandler(SecondaryContextMenu_Closed); ctsm.SecondaryContextMenu.Show(Cursor.Position); return true; } void SecondaryContextMenu_Closed(object sender, ToolStripDropDownClosedEventArgs e) { ((ContextMenuStrip)sender).Closed -= new ToolStripDropDownClosedEventHandler(SecondaryContextMenu_Closed); lastShownSecondaryContextMenu = null; secondaryContextMenuActive = false; Focus(); } protected override void OnClosing(ToolStripDropDownClosingEventArgs e) { if (secondaryContextMenuActive) { e.Cancel = true; } base.OnClosing(e); } } public Form1() { InitializeComponent(); CustomToolStripMenuItem itemPrimary1 = new CustomToolStripMenuItem("item primary 1"); itemPrimary1.SecondaryContextMenu = new ContextMenuStrip(); itemPrimary1.SecondaryContextMenu.Items.AddRange(new ToolStripMenuItem[] { new ToolStripMenuItem("item primary 1.1"), new ToolStripMenuItem("item primary 1.2"), }); CustomToolStripMenuItem itemPrimary2 = new CustomToolStripMenuItem("item primary 2"); itemPrimary2.DropDownItems.Add("item primary 2, sub 1"); itemPrimary2.DropDownItems.Add("item primary 2, sub 2"); itemPrimary2.SecondaryContextMenu = new ContextMenuStrip(); itemPrimary2.SecondaryContextMenu.Items.AddRange(new ToolStripMenuItem[] { new ToolStripMenuItem("item primary 2.1"), new ToolStripMenuItem("item primary 2.2"), }); CustomContextMenuStrip primaryContextMenu = new CustomContextMenuStrip(); primaryContextMenu.Items.AddRange(new ToolStripItem[]{ itemPrimary1, itemPrimary2 }); this.ContextMenuStrip = primaryContextMenu; } }