Не закрывайте ContextMenuStrip при выборе определенных элементов
Можно ли оставить ContextMenuStrip открытым после выбора/проверки определенных элементов?
Я планирую использовать простой ContextMenuStrip для установки фильтра (таким образом, я мог бы использовать тот же фильтр либо в меню, либо в качестве параметра правой кнопки мыши).
В меню перечислены несколько элементов, и я хотел бы, чтобы пользователь мог сделать выбор элементов с помощью базовой функции проверки. После выбора пользователь может нажать кнопку "Активировать фильтр" или нажать "За пределами меню", чтобы активировать или отменить фильтр.
В событии выбора/щелчка меню обычно закрывается.
Возможно ли открыть меню в событии клика?
Ответы
Ответ 1
Чтобы предотвратить закрытие контекстного меню при нажатии элемента, выполните следующие действия.
В событии mousedown для параметра ContextMenuItems установите флаг в false, а затем верните его в true в заключительном событии контекстного меню.
Пример:
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
Ответ 2
Если будущие программисты задаются вопросом, как это сделать, это то, что я выяснил. Это не приведет к закрытию контекстного меню при щелчке по любому элементу. Создайте событие закрытия полосы контекстного меню и настройте оператор if, чтобы отменить событие закрытия, если закрытие причины элемента.
private void contextMenuStrip_Closing(object sender, ToolStripDropDownClosingEventArgs e)
{
if (e.CloseReason == ToolStripDropDownCloseReason.ItemClicked)
e.Cancel = true;
}
Ответ 3
Событие закрытия
установите e.Cancel = true, чтобы открыть меню
проблема только в том, что событие не сообщает вам, что было нажато, поэтому вам нужно следить за этим самостоятельно. установите какой-то флаг в событии Click элементов, которые вы хотите сохранить в открытом меню. затем в событии закрытия отметьте флаг и установите e.Cancel соответствующим образом.
Ответ 4
Я не думаю, что в ContextMenuStrip есть свойство для этого.
Обходной путь, который мы используем в нашем приложении, заключается в том, что при кликнутом событии ContextMenuStrip мы выполняем некоторую обработку, а затем, если мы хотим, чтобы контекстное меню оставалось открытым, мы просто вызываем ContextMenuStrip.Show снова.
Это будет хорошо работать, если для ContextMenuStrip будет только один уровень. Если есть подменю и под-подменю, вам нужно будет повторно выбрать меню, которые были открыты до щелчка, и я не уверен, как это можно сделать...
Ответ 5
Это мой метод; он мерцает и, я думаю, немного более гибкий.
Если у вас есть набор инструментов ToolStripMenuItems, которые вы хотите использовать в качестве кнопок переключения (опция включения/выключения), попробуйте следующее:
(ctxWildCards
- это только мой ContextMenuStrip
, используемый для выбора фильтров на основе типов файлов - для поиска или FileDialogs)
Это в Visual Basic (очевидно!;), поэтому вы можете добавлять обработчики программным способом или использовать предложения "Ручки...".
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
Ответ 6
То, что я нашел странным, заключается в том, что событие ContextMenuStrip.Closing
срабатывает до события ToolStripMenuItem.Click
. Решение состояло в том, чтобы использовать событие ContextMenuStrip.ItemClicked
, где у вас есть e.ClickedItem
, а затем проверить, не является ли он одним из элементов, который при нажатии не будет закрывать ContextMenuStrip
, и установить соответствующий флаг. Затем в ContextMenuStrip.Closing
вы можете установить e.Cancel = true;
, если флаг также установлен. Однако не забудьте reset флаг.
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;
}
}
}
Ответ 7
OnClosing, do: e.Cancel = e.CloseReason!= ToolStripDropDownCloseReason.CloseCalled;
а затем, когда вы решите закрыть, вызовите Close().
Ответ 8
Лучший способ найти это без мерцания - использовать события MouseDown и MouseLeave для каждой кнопки в меню DropDown.
Пример:
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
Ответ 9
Я нашел это полезным для своих целей.
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
Вы можете использовать ItemClicked
для чтения тега или другого свойства.
Мне просто нужен простой элемент, который дал понять пользователю, какой элемент контекстного меню будет действовать.