2009-05-15 3 views
14

È possibile lasciare aperto ContextMenuStrip dopo una selezione/controllo di determinati elementi?Non chiudere ContextMenuStrip sulla selezione di alcuni elementi

Ho intenzione di utilizzare un semplice ContextMenuStrip per impostare un filtro (in questo modo potrei usare lo stesso filtro in un menu o come opzione del tasto destro del mouse).

Il menu elenca un numero di elementi e vorrei che l'utente fosse in grado di effettuare una selezione degli articoli utilizzando la funzionalità di controllo di base. Una volta effettuata la selezione, l'utente può fare clic su un'opzione di attivazione del filtro o può fare clic all'esterno del menu per attivare o annullare il filtro.

In un evento di selezione/clic il menu normalmente si chiude. È possibile mantenere il menu aperto su un evento click?

risposta

3

Per evitare che il menu di contesto si chiuda quando viene fatto clic su un elemento, effettuare le seguenti operazioni.

In caso di evento contestato di ContextMenuItems, impostare flag su false quindi impostarlo su true all'evento di chiusura del menu di scelta rapida.

Esempio:

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 Hai selezionato la risposta che non è nella lingua in cui stai codificando e quella che suggerisce di utilizzare una variabile globale ??? Qui ci sono risposte più correlate. –

1

Non penso che ci sia una proprietà per questo in ContextMenuStrip.

La soluzione che usiamo nella nostra applicazione è che sull'evento cliccato del ContextMenuStrip, facciamo un po 'di elaborazione, quindi se vogliamo che il menu contestuale per rimanere aperto chiamiamo semplicemente di nuovo ContextMenuStrip.Show.

Questo funzionerà bene se c'è un solo livello in ContextMenuStrip. Se ci sono sottomenu e sotto-menu secondari, dovrai selezionare nuovamente i menu che erano aperti prima del clic e non so come farlo ...

+0

Grazie! Ho controllato e questo funziona perfettamente per i menu di un livello. Lascerò la domanda aperta ancora per un po 'per vedere se c'è un'altra opzione. – barry

3

l'evento di chiusura

set e.Cancel = true per uscire dal menu aperto

unico problema è l'evento non ti dice quello che è stato fatto clic, in modo da avere per tenere traccia di questo voi stessi. imposta un qualche tipo di flag nell'evento Click degli oggetti che vuoi mantenere aperto. quindi nell'evento di chiusura controlla la bandiera e imposta e.Cancel in modo appropriato.

+0

Questo sembra funzionare più elegante della soluzione show. Ho impostato e.Cancel su true nell'evento Closing del ContextMenu basato su un flag come suggerito e impostato il flag sui singoli elementi cliccati. Tuttavia, poiché l'evento Cancel viene impostato solo durante l'evento di chiusura, rimane indietro di un passo. C'è un modo per impostare il flag Annulla per l'evento di chiusura negli eventi di click degli articoli? – barry

0

OnClosing, fare: e.Cancel = e.CloseReason = ToolStripDropDownCloseReason.CloseCalled; e poi quando decidi di chiudere, chiama Close().

20

Nel caso in cui i futuri programmatori si stiano chiedendo come fare, questo è quello che ho capito. Questo non chiuderà il menu di scelta rapida se si fa clic su un elemento. Crea l'evento di chiusura della striscia del menu contestuale e imposta un'istruzione if per annullare l'evento close se il motivo di chiusura è itemclicked.

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

risposta corretta reale – Alex

+0

Se ho capito bene la domanda, questa non risponde in modo completo, in quanto vogliono solo lasciare il menu di scelta rapida aperto per alcuni degli elementi. Per esempio. le voci del menu di scelta rapida sono: Opzione A, Opzione B, Opzione C e Accetta; il menu di scelta rapida dovrebbe essere lasciato aperto se si fa clic su una delle opzioni (l'opzione verrà quindi verificata), tuttavia, se si fa clic su Accetta, il menu di scelta rapida dovrebbe essere chiuso. – jonvw

0

Il modo migliore che ho trovato per fare questo senza sfarfallio è quello di utilizzare gli eventi MouseDown e MouseLeave per ogni tasto nel menu a discesa.

Esempio:

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

Questo è il mio metodo; è senza sfarfallio e - penso - un po 'più flessibile.

Se si dispone di un set di ToolStripMenuItems si desidera utilizzare i pulsanti a levetta (opzione on/off) come, provate questo:

(Il ctxWildCards è solo il mio ContextMenuStrip, utilizzato per selezionare i filtri in base a tipi di file - per ricerca o FileDialogs)

Questo è in Visual Basic (ovviamente!;), quindi è possibile aggiungere Gestori a livello di codice o utilizzando le clausole 'Gestisci ...'.

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

Quello che ho trovato strano è che gli incendi ContextMenuStrip.Closing evento prima dell'evento ToolStripMenuItem.Click. La soluzione era utilizzare l'evento ContextMenuStrip.ItemClicked in cui si dispone di e.ClickedItem, quindi verificare se si tratta di uno degli elementi che, quando si fa clic, non chiude lo ContextMenuStrip e imposta il flag appropriato. Quindi in ContextMenuStrip.Closing è possibile impostare e.Cancel = true; se è impostato anche il flag. Non dimenticare di resettare il flag però.

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

Ho trovato utile per i miei scopi.

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 

Si potrebbe utilizzare ItemClicked per leggere il tag o qualche altra proprietà.

Volevo solo un elemento semplice che rendesse chiaro all'utente quale voce avrebbe avuto effetto il menu di scelta rapida.