Question

Est-il possible de laisser un ContextMenuStrip ouvert après une sélection / vérification de certains éléments?

Je prévois d'utiliser simple ContextMenuStrip pour définir un filtre (cette façon, je pouvais utiliser le même filtre soit dans un menu ou une option clic droit).

Le menu énumère un certain nombre d'éléments, et je voudrais que l'utilisateur peut faire une sélection des éléments à l'aide de la fonctionnalité de vérification de base. Une fois la sélection effectuée, l'utilisateur peut cliquer sur une option de filtre Activer ou peut cliquer en dehors du menu pour activer ou annuler le filtre.

Sur un événement de sélection / cliquez sur le menu se ferme normalement. Est-il possible de garder le menu ouvert sur un événement click?

Était-ce utile?

La solution

Pour éviter la contextmenu de se fermer lorsqu'un élément est cliqué, procédez comme suit.

Lors de l'événement mousedown de ContextMenuItems mis drapeau faux alors il remis à vrai lors de l'événement de clôture du contextmenu.

Exemple:

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

Autres conseils

Dans le cas où les futurs programers se demandent comment faire, ce que je compris. Ce ne sera pas fermer le menu contextuel si un élément est cliqué. Créer l'événement de clôture de la bande de menu contextuel et une configuration instruction if pour annuler l'événement close si la raison est proche itemclicked.

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

l'événement de clôture

set e.Cancel = true pour quitter le menu ouvert

seul problème est l'événement ne vous dit pas ce qui a été cliqué, vous devez garder une trace de vous-même. mettre une sorte de drapeau dans l'événement Click des éléments que vous souhaitez conserver le menu ouvert. puis en cas de clôture vérifier le drapeau et définir e.Cancel de façon appropriée.

Je ne pense pas qu'il y ait une propriété pour cela dans le ContextMenuStrip.

La solution que nous utilisons dans notre application est que l'événement clicked du ContextMenuStrip, nous faisons un peu de traitement, alors si nous voulons que le menu contextuel pour rester ouvert que nous appelons simplement ContextMenuStrip.Show à nouveau.

Cela fonctionne bien s'il n'y a qu'un seul niveau à la ContextMenuStrip. S'il y a des sous-menus et sous-sous-menus, alors vous devez sélectionner à nouveau les menus qui étaient ouverts avant le clic et je ne sais pas comment cela peut être fait ...

OnClosing, do: e.Cancel = e.CloseReason = ToolStripDropDownCloseReason.CloseCalled; et puis quand vous décidez de fermer, appeler Close ().

Ceci est ma méthode; il est sans scintillement et - je pense -. un peu plus flexible

Si vous avez un ensemble de ToolStripMenuItems vous souhaitez utiliser sous forme de boutons à bascule (en option on / off), essayez ceci:

(Le ctxWildCards est juste mon ContextMenuStrip, utilisé pour sélectionner des filtres en fonction des types de fichiers - pour la recherche ou FileDialogs)

Ceci est en Visual Basic (évidemment;), de sorte que vous pouvez ajouter à l'aide d'un programme ou Handlers 'poignées ...' clauses

.
  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

Ce que je trouve étrange est que l'événement se déclenche ContextMenuStrip.Closing avant l'événement ToolStripMenuItem.Click. La solution était d'utiliser l'événement où vous ContextMenuStrip.ItemClicked avez e.ClickedItem, puis vérifier si elle est l'un des éléments qui, lorsque vous cliquez dessus, ne fermerons pas la ContextMenuStrip et définir le drapeau approprié. Puis, en vous pouvez définir e.Cancel = true; si le drapeau <=> est également fixé. Ne pas oublier de remettre le drapeau bien.

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 meilleure manière que je trouvais à le faire sans scintillement est d'utiliser les événements MouseDown et MouseLeave pour chaque bouton dans le menu déroulant.

Exemple:

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

J'ai trouvé cela utile pour mes besoins.

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

Vous pouvez utiliser pour lire le ItemClicked tag ou une autre propriété.

Je voulais juste un élément simple qui fait clairement à l'utilisateur quel élément le menu contextuel allait effectuer.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top