2009-05-15 6 views
14

¿Es posible dejar una ContextMenuStrip abierta después de una selección/verificación de ciertos elementos?No cerrar ContextMenuStrip en la selección de ciertos elementos

Planeo usar un ContextMenuStrip simple para establecer un filtro (de esta manera podría usar el mismo filtro en un menú o como una opción de clic derecho).

El menú enumera una serie de elementos, y me gustaría que el usuario pueda hacer una selección de los elementos utilizando la funcionalidad básica Comprobar. Una vez que se realiza la selección, el usuario puede hacer clic en la opción Activar filtro o hacer clic fuera del menú para activar o cancelar el filtro.

En un evento de selección/clic, el menú normalmente se cierra. ¿Es posible mantener el menú abierto en un evento de clic?

Respuesta

3

Para evitar que el menú contextual se cierre cuando se hace clic en un elemento, haga lo siguiente.

El evento mousedown de ContextMenuItems establece el indicador en falso y luego lo establece de nuevo en verdadero en el evento de cierre 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 
+5

-1 Has seleccionado la respuesta que no está en el idioma en el que estás codificando, y una que sugiere usar una variable global ??? Hay muchas más respuestas relacionadas aquí. –

1

No creo que haya una propiedad para esto en el ContextMenuStrip.

La solución alternativa que utilizamos en nuestra aplicación es que en el evento cliqueado de ContextMenuStrip, hacemos algún procesamiento, luego si queremos que el menú contextual permanezca abierto simplemente llamamos ContextMenuStrip.Show nuevamente.

Esto funcionará bien si solo hay un nivel para ContextMenuStrip. Si hay submenús y submenús secundarios, entonces deberá volver a seleccionar los menús que estaban abiertos antes del clic y no estoy seguro de cómo hacerlo ...

+0

Gracias! Lo revisé y esto funciona perfecto para menús de un nivel. Dejaré la pregunta abierta por un tiempo más para ver si hay otra opción. – barry

3

el evento de cierre

conjunto 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. establezca algún tipo de indicador en el evento Click de los elementos en los que desea mantener abierto el menú. luego, en el evento de cierre, marque la bandera y establezca e.Cancelar de manera apropiada.

+0

Esto parece funcionar más elegante que la solución de espectáculo. Establecí e.Cancel en "Verdadero" en el evento "Cierre" del ContextMenu basado en un indicador según lo sugerido y establecí el indicador en los elementos individuales seleccionados. Sin embargo, dado que el evento Cancelar solo se establece durante el evento de cierre, se retrasa un paso más. ¿Hay alguna manera de establecer el indicador Cancelar para el evento de cierre en los eventos de clic de elemento? – barry

0

OnClosing, hacer:! E.Cancel = = e.CloseReason ToolStripDropDownCloseReason.CloseCalled; y luego, cuando decida cerrar, llame a Close().

20

En caso de que los futuros programadores se pregunten cómo hacerlo, esto es lo que descubrí. Esto no cerrará el menú contextual si se hace clic en cualquier elemento. Cree el evento de cierre de la tira de menú de contexto y configure una instrucción if para cancelar el evento de cierre si el motivo de cierre es itemclic.

private void contextMenuStrip_Closing(object sender, ToolStripDropDownClosingEventArgs e) 
{ 
    if (e.CloseReason == ToolStripDropDownCloseReason.ItemClicked) 
     e.Cancel = true; 
} 
+1

respuesta correcta real – Alex

+0

Si entiendo la pregunta correctamente, esto realmente no responde completamente, ya que solo quieren dejar el menú contextual abierto para algunos de los elementos. P.ej. los elementos del menú contextual son: Opción A, Opción B, Opción C y Aceptar; el menú contextual debe dejarse abierto si se hace clic en una de las opciones (la opción se marcará); sin embargo, si se hace clic en Aceptar, se debe cerrar el menú contextual. – jonvw

0

La mejor manera que he encontrado para hacer esto sin parpadeo es el uso de 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 
1

Este es mi método; es libre de parpadeos y, creo, un poco más flexible.

Si usted tiene un conjunto de ToolStripMenuItems desea utilizar como botones de conmutación (opción de encendido/apagado), intente esto:

(El ctxWildCards es sólo mi ContextMenuStrip, que se utiliza para seleccionar los filtros basados ​​en los tipos de archivos - para búsqueda o FileDialogs)

Esto está en Visual Basic (obviamente!;), por lo que puede agregar controladores mediante programación o usando cláusulas 'Manejar ...'.

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 
1

Lo que me pareció extraño es que los incendios ContextMenuStrip.Closing eventos antes caso ToolStripMenuItem.Click. La solución fue utilizar el evento ContextMenuStrip.ItemClicked donde tiene e.ClickedItem, y luego verificar si es uno de los elementos que, al hacer clic, no cierra el ContextMenuStrip, y establece el indicador apropiado. Luego, en ContextMenuStrip.Closing, puede establecer e.Cancel = true; si la bandera también está configurada. No olvide restablecer la bandera sin 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; 
     } 
    } 
} 
0

Encontré 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 

Usted podría utilizar ItemClicked para leer la etiqueta o alguna otra propiedad.

Solo quería un elemento simple que dejara en claro al usuario qué elemento iba a afectar el menú contextual.

Cuestiones relacionadas