Ne fermez pas ContextMenuStrip sur la sélection de certains éléments
-
22-08-2019 - |
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?
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.