Tengo un ContextMenuStripque está asignado a varios cuadros de lista diferentes. Estoy tratando de averiguar cuándo ContextMenuStripse hace clic en en qué ListBoxse usó. Probé el siguiente código para comenzar, pero no funciona. El sendertiene el valor correcto, pero cuando intento para asignarlo a la menuSubmittedque es nulo.
private void MenuViewDetails_Click(object sender, EventArgs e)
{
ContextMenu menuSubmitted = sender as ContextMenu;
if (menuSubmitted != null)
{
Control sourceControl = menuSubmitted.SourceControl;
}
}
Cualquier ayuda sería genial. Gracias.
Usando la ayuda a continuación, lo descubrí:
private void MenuViewDetails_Click(object sender, EventArgs e)
{
ToolStripMenuItem menuItem = sender as ToolStripMenuItem;
if (menuItem != null)
{
ContextMenuStrip calendarMenu = menuItem.Owner as ContextMenuStrip;
if (calendarMenu != null)
{
Control controlSelected = calendarMenu.SourceControl;
}
}
}
c#
.net
winforms
contextmenustrip
Taryn
fuente
fuente

ifdeclaraciones y usarlasif (menuItem == null) return;si eres como yo y no quieres que tu código que lo maneja esté anidado en 2 niveles adicionales innecesarios.Respuestas:
Para un
ContextMenu:El problema es que el
senderparámetro apunta al elemento del menú contextual en el que se hizo clic, no al menú contextual en sí.Sin embargo, es una solución simple, porque cada uno
MenuItemexpone unGetContextMenumétodo que le dirá quéContextMenucontiene ese elemento del menú.Cambie su código a lo siguiente:
private void MenuViewDetails_Click(object sender, EventArgs e) { // Try to cast the sender to a MenuItem MenuItem menuItem = sender as MenuItem; if (menuItem != null) { // Retrieve the ContextMenu that contains this MenuItem ContextMenu menu = menuItem.GetContextMenu(); // Get the control that is displaying this context menu Control sourceControl = menu.SourceControl; } }Para un
ContextMenuStrip:Cambia ligeramente las cosas si usa a en
ContextMenuStriplugar de aContextMenu. Los dos controles no están relacionados entre sí, y una instancia de uno no se puede convertir en una instancia del otro.Como antes, el elemento en el que se hizo clic todavía se devuelve en el
senderparámetro, por lo que tendrá que determinar a quiénContextMenuStrippertenece este elemento de menú individual. Haces eso con laOwnerpropiedad . Finalmente, usará laSourceControlpropiedad para determinar qué control muestra el menú contextual.Modifica tu código así:
private void MenuViewDetails_Click(object sender, EventArgs e) { // Try to cast the sender to a ToolStripItem ToolStripItem menuItem = sender as ToolStripItem; if (menuItem != null) { // Retrieve the ContextMenuStrip that owns this ToolStripItem ContextMenuStrip owner = menuItem.Owner as ContextMenuStrip; if (owner != null) { // Get the control that is displaying this context menu Control sourceControl = owner.SourceControl; } } }fuente
ContextMenuyContextMenuStrip. (Ah, y veo que ya lo has descubierto. Bueno, ¡mucho mejor si aprendes las cosas por tu cuenta!)SourceControllamentablemente es nulo en el momento en que se activa unClickevento de unToolStripItemsubelemento deContextMenuStrip. Parece que el evento deContextMenuStrip'Closedse dispara antes que eseClickevento, que es probablemente lo que causa el problema; Supongo que la propiedad se borra después de que el menú 'se cierra'.OwnerItempropiedades hasta que encuentre unaToolStripItemque tenga unaContextMenuStripen suOwnerpropiedad. Pero como acabo de comentar, no funciona; elSourceControlen el menú de contexto será nulo. Sin embargo, dijiste que no puedes reproducirlo ... ¿tal vez el problema solo ocurre con menús de más de un nivel? El mío tenía dos subniveles de profundidad.Publicación anterior, pero en caso de que alguien como yo la encuentre:
Para un ContextMenuStrip, lo anterior no funcionó para mí, pero me llevó a encontrar lo que sí.
void DeleteMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e) { ContextMenuStrip menu = sender as ContextMenuStrip; Control sourceControl = menu.SourceControl; MessageBox.Show(sourceControl.Name); }Esto me dio el nombre del control esperado. Puede poner en validación, etc. con declaraciones if, solo estoy publicando para ir al grano.
fuente
ContextMenu. El problema es queItemClickedno se activa al hacer clic en los elementos del submenú ; necesitan su propioClickevento que tendría el elemento en sí como remitente, no el menú.Tuve una gran dificultad para hacer que funcionara este código. Esta es la solución más simple que pude encontrar:
Para un ContextMenuStrip:
Control _sourceControl = null; private void contextMenuStrip_Opened(object sender, EventArgs e) { _sourceControl = contextMenuStrip.SourceControl; } private void contextMenuItem_Click(object sender, EventArgs e) { var menuItem = (ToolStripMenuItem)sender; _sourceControl.Text = menuItem.Text; MessageBox.Show(menuItem.Name); MessageBox.Show(sourceControl.Name); }fuente
La solución más sencilla sería:
Control parentControl = ((sender as MenuItem).GetContextMenu()).SourceControl;fuente