Tengo un ContextMenuStrip
que está asignado a varios cuadros de lista diferentes. Estoy tratando de averiguar cuándo ContextMenuStrip
se hace clic en en qué ListBox
se usó. Probé el siguiente código para comenzar, pero no funciona. El sender
tiene el valor correcto, pero cuando intento para asignarlo a la menuSubmitted
que 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
if
declaraciones 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
sender
pará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
MenuItem
expone unGetContextMenu
método que le dirá quéContextMenu
contiene 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
ContextMenuStrip
lugar 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
sender
parámetro, por lo que tendrá que determinar a quiénContextMenuStrip
pertenece este elemento de menú individual. Haces eso con laOwner
propiedad . Finalmente, usará laSourceControl
propiedad 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
ContextMenu
yContextMenuStrip
. (Ah, y veo que ya lo has descubierto. Bueno, ¡mucho mejor si aprendes las cosas por tu cuenta!)SourceControl
lamentablemente es nulo en el momento en que se activa unClick
evento de unToolStripItem
subelemento deContextMenuStrip
. Parece que el evento deContextMenuStrip
'Closed
se dispara antes que eseClick
evento, que es probablemente lo que causa el problema; Supongo que la propiedad se borra después de que el menú 'se cierra'.OwnerItem
propiedades hasta que encuentre unaToolStripItem
que tenga unaContextMenuStrip
en suOwner
propiedad. Pero como acabo de comentar, no funciona; elSourceControl
en 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 queItemClicked
no se activa al hacer clic en los elementos del submenú ; necesitan su propioClick
evento 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