Domanda

E 'possibile lasciare un ContextMenuStrip aperta dopo una selezione / controllo di alcune voci?

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

Il menu elenca una serie di elementi, e vorrei che l'utente sia in grado di effettuare una selezione degli elementi utilizzando le funzionalità di base Check. Una volta che la selezione è fatta l'utente può fare clic su un'opzione di filtro Attivare o può fare clic all'esterno del menu per attivare o annullare il filtro.

In una selezione / click caso il menu si chiude normalmente. E 'possibile mantenere il menu aperto su un evento click?

È stato utile?

Soluzione

Per evitare che il menu contestuale di chiudere quando un elemento viene cliccato, effettuare le seguenti operazioni.

Su evento MouseDown di ContextMenuItems flag impostato su false quindi impostare di nuovo al vero in caso di menu contestuale di chiusura.

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

Altri suggerimenti

Nel caso in cui i programmatori futuri si chiedono come fare questo, questo è quello che ho capito. Questo non si chiuderà il menu contestuale se qualsiasi elemento viene cliccato. Creare l'evento menu contestuale chiusura strip e impostare un if per annullare l'evento close se vicino la ragione è itemclicked.

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

L'evento di chiusura

set e.Cancel = true per uscire dal menu aperto

unico problema è l'evento non ti dice ciò che è stato fatto clic, in modo da avere per tenere traccia di questo voi stessi. impostare una sorta di bandiera Click degli elementi che si desidera conservare il menu aperto. quindi in caso di chiusura controllare il flag e impostare e.Cancel modo appropriato.

Non credo che ci sia una proprietà per questo nel 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 funziona bene se c'è solo un livello al ContextMenuStrip. Se ci sono sotto-menu e sotto-menu secondari, allora si dovrà selezionare nuovamente i menu che erano aperte prima del click e io non sono sicuro di come ciò può essere fatto ...

OnClosing, do: e.Cancel = e.CloseReason = ToolStripDropDownCloseReason.CloseCalled; e poi, quando si decide di chiudere, chiamare Close ().

Questo è il mio metodo; è priva di sfarfallio e - credo -. un po 'più flessibile

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

(La ctxWildCards è solo la mia ContextMenuStrip, utilizzato per selezionare i filtri in base a tipi di file - per la ricerca o FileDialogs)

Questo è in Visual Basic (ovviamente;), in modo da poter aggiungere i gestori di programmazione o l'utilizzo 'maniglie ...' clausole

.
  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

Quello che ho trovato strana è che ContextMenuStrip.Closing generato l'evento prima il ToolStripMenuItem.Click evento. La soluzione era quella di utilizzare ContextMenuStrip.ItemClicked evento in cui si dispone di e.ClickedItem, e quindi verificare se si tratta di uno degli elementi che, se cliccato, non chiuderà la ContextMenuStrip, e impostare il flag appropriato. Poi, nel e.Cancel = true; è possibile impostare <=> se anche è impostato il flag. Non dimenticate di resettare la bandiera 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;
        }
    }
}

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

Ho trovato questo 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 semplice elemento che ha reso chiaro per l'utente, che voce di menu contestuale stava per effettuare.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top