No cierre ContextMenuStrip en la selección de ciertos elementos
-
22-08-2019 - |
Pregunta
Es posible dejar un ContextMenuStrip abrir después de una selección/verificación de ciertos artículos?
Pienso usar un simple ContextMenuStrip establecer un filtro (de esta manera podría utilizar el mismo filtro, ya sea en un menú o como un derecho-haga clic en la opción).
El menú enumera una serie de artículos, y me gustaría que el usuario sea capaz de hacer una selección de los elementos a través de la Verificación de la funcionalidad básica.Una vez que la selección se realiza el usuario puede hacer clic en una de Activar la opción de filtro o puede hacer clic fuera del menú para activar o cancelar el filtro.
En una selección/evento de clic en el menú normalmente se cierra.Es posible mantener el menú abierto en un evento de clic?
Solución
Para evitar que el menú contextual se cierre cuando se hace clic en un elemento, haga lo siguiente.
En caso de mousedown ContextMenuItems indicador establecido en false luego nuevamente a verdadero en el acto de clausura del menú contextual.
Ejemplo:
Private blnClose As Boolean = True
Private Sub MoveUpToolStripMenuItem_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MoveUpToolStripMenuItem.MouseDown
blnClose = False
End Sub
Private Sub ContextMenuStrip1_Closing(ByVal sender As Object, ByVal e As System.Windows.Forms.ToolStripDropDownClosingEventArgs) Handles ContextMenuStrip1.Closing
e.Cancel = Not blnClose
blnClose = True
End Sub
Otros consejos
En el caso de los futuros programadores se preguntan cómo hacer esto, esto es lo que me di cuenta. Esto no se cerrará el menú contextual si se hace clic en cualquier artículo. Crear el evento menú contextual de la tira de cierre y una configuración if para cancelar el evento de cierre si se itemclicked cerca razón.
private void contextMenuStrip_Closing(object sender, ToolStripDropDownClosingEventArgs e)
{
if (e.CloseReason == ToolStripDropDownCloseReason.ItemClicked)
e.Cancel = true;
}
el evento de cierre
set e.Cancel = true para salir del menú abierto
único problema es el evento no le dice lo que se ha hecho clic, lo que tiene que hacer un seguimiento de esto por sí mismo. establecer algún tipo de indicador en el evento Click de los elementos que desea mantener el menú abierto. a continuación, en caso de cierre comprobar la bandera y establecer e.Cancel adecuadamente.
No creo que hay una propiedad para esto en el ContextMenuStrip.
La solución que utilizamos en nuestra aplicación es que se ha hecho clic en el evento de la ContextMenuStrip, hacemos algún tipo de procesamiento, a continuación, si queremos que el menú contextual para permanecer abierto simplemente llamamos ContextMenuStrip.Show de nuevo.
Esto funciona bien si sólo hay un nivel al ContextMenuStrip. Si hay sub-menús y sub-sub-menús, entonces tendría que volver a seleccionar los menús que estaban abiertos antes del clic y no estoy seguro de cómo se puede hacer ...
OnClosing, Do: e.Cancel = = e.CloseReason ToolStripDropDownCloseReason.CloseCalled; y luego, cuando usted decide cerrar, llame a Close ().
Este es mi método;es libre de parpadeo y - creo - un poco más flexible.
Si usted tiene un conjunto de ToolStripMenuItems te gustaría utilizar como botones (opción de encendido/apagado), intente esto:
(El ctxWildCards
es solo mi ContextMenuStrip
, se utiliza para seleccionar los filtros basados en tipos de archivo para la búsqueda o FileDialogs)
Esto es en Visual Basic (obviamente!;), así que usted puede agregar Controladores de programación o el uso de controladores de...' cláusulas.
Private Sub OnOffToolStripMenuItem_MouseDown(sender As System.Object, e As System.Windows.Forms.MouseEventArgs)
Dim t = TryCast(sender, ToolStripMenuItem)
If Not t Is Nothing Then
'Since you may have more On/off-Items, check to see if the Owner is the ContextMenuStrip
If t.Owner Is ctxWildCards Then
' The ContextMenuStrip will stay open on Right-click, i.e. the user can check and close by clicking 'normally'
ctxWildCards.AutoClose = (e.Button = Windows.Forms.MouseButtons.Left)
End If
'Just me using a custom image for checked items.
t.Checked = Not t.Checked
t.Image = If(t.Checked, rdoImage, Nothing)
End If
End Sub
' On leaving ToolStripMenuItems of the ContextMenuStrip, allow it to AutoClose
Private Sub OnOffToolStripMenuItem_MouseLeave(sender As System.Object, e As System.EventArgs)
ctxWildCards.AutoClose = True
End Sub
Lo que me pareció extraño es que ContextMenuStrip.Closing
desencadena el evento antes el ToolStripMenuItem.Click
evento. La solución fue usar ContextMenuStrip.ItemClicked
evento en el que tiene e.ClickedItem
, y después comprobar si se trata de uno de los elementos que, al hacer clic, no cerrará la ContextMenuStrip
, y establecer el indicador apropiado. Luego, en e.Cancel = true;
puede establecer <=> si se establece también la bandera. No se olvide de restablecer el indicador embargo.
bool isRunAtStartupClicked;
private void ContextMenuStrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
if (e.ClickedItem == trayIcon.ContextMenuStrip.Items["miRunAtStartup"])
{
isRunAtStartupClicked = true;
}
}
private void ContextMenuStrip_Closing(object sender, ToolStripDropDownClosingEventArgs e)
{
if (e.CloseReason == ToolStripDropDownCloseReason.ItemClicked)
{
if (isRunAtStartupClicked)
{
isRunAtStartupClicked = false;
e.Cancel = true;
}
}
}
La mejor manera que he encontrado para hacer esto sin parpadeo es utilizar los eventos MouseDown y MouseLeave para cada botón en el menú desplegable.
Ejemplo:
Private Sub ToolStripMenuItem2_Mousedown(sender As Object, e As EventArgs) Handles ToolStripMenuItem2.MouseDown
ΥπηρεσίεςToolStripMenuItem.DropDown.AutoClose = False
End Sub
Private Sub ToolStripMenuItem2_MouseLeave(sender As Object, e As EventArgs) Handles ToolStripMenuItem2.MouseLeave
ΥπηρεσίεςToolStripMenuItem.DropDown.AutoClose = True
End Sub
He encontrado esto útil para mis propósitos.
Private Sub CM_Closing(sender As Object, e As ToolStripDropDownClosingEventArgs) Handles CM.Closing
If e.CloseReason = ToolStripDropDownCloseReason.ItemClicked Then
Dim ItemClicked As String = CM.GetItemAt(New Point(Cursor.Position.X - CM.Left, Cursor.Position.Y - CM.Top)).Name
If ItemClicked = "CMHeader" Then
e.Cancel = True
End If
End If
End Sub
Se puede usar ItemClicked
para leer la etiqueta o alguna otra propiedad.
Sólo quería un elemento simple que hizo claro para el usuario qué elemento del menú contextual se va a efectuar.