Не закрывайте ContextMenuStrip при выборе определенных элементов.

StackOverflow https://stackoverflow.com/questions/866689

Вопрос

Можно ли оставить ContextMenuStrip открытым после выбора/проверки определенных элементов?

Я планирую использовать простой ContextMenuStrip для установки фильтра (таким образом я мог бы использовать тот же фильтр либо в меню, либо в качестве опции, вызываемой щелчком правой кнопкой мыши).

В меню перечислено несколько элементов, и я хотел бы, чтобы пользователь мог выбирать элементы, используя базовую функцию проверки.После завершения выбора пользователь может выбрать параметр «Активировать фильтр» или щелкнуть за пределами меню, чтобы активировать или отменить фильтр.

В случае выбора/щелчка меню обычно закрывается.Можно ли оставить меню открытым при нажатии?

Это было полезно?

Решение

Чтобы предотвратить закрытие контекстного меню при щелчке элемента, выполните следующие действия.

В событии 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

Другие советы

Если будущие программисты задаются вопросом, как это сделать, вот что я выяснил.Это не приведет к закрытию контекстного меню при щелчке по любому элементу.Создайте событие закрытия полосы контекстного меню и настройте оператор if для отмены события закрытия, если причина закрытия выбрана.

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

заключительное мероприятие

установите e.Cancel = true, чтобы оставить меню открытым

Единственная проблема заключается в том, что событие не сообщает вам, по какому элементу был сделан щелчок, поэтому вам придется отслеживать это самостоятельно.установите какой-то флаг в событии Click элементов, меню которых вы хотите оставить открытым.затем в событии закрытия проверьте флаг и установите e.Cancel соответствующим образом.

Я не думаю, что в ContextMenuStrip есть свойство для этого.

Обходной путь, который мы используем в нашем приложении, заключается в том, что при нажатии на событие ContextMenuStrip мы выполняем некоторую обработку, а затем, если мы хотим, чтобы контекстное меню оставалось открытым, мы просто вызываем ContextMenuStrip.Show еще раз.

Это будет хорошо работать, если у ContextMenuStrip есть только один уровень.Если есть подменю и подподменю, то вам придется заново выбирать меню, которые были открыты до щелчка, и я не уверен, как это можно сделать...

При закрытии выполните:e.Cancel = e.CloseReason != ToolStripDropDownCloseReason.CloseCalled;а затем, когда вы решите закрыться, вызовите Close().

Это мой метод;он не мерцает и, как мне кажется, немного более гибкий.

Если у вас есть набор ToolStripMenuItems, который вы хотите использовать в качестве кнопок переключения (включить/выключить опцию), попробуйте следующее:

( ctxWildCards это только мой ContextMenuStrip, используется для выбора фильтров по типам файлов — для поиска или FileDialogs)

Это на Visual Basic (очевидно!;), поэтому вы можете добавлять обработчики программно или с помощью предложений «Handles...».

  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

Что мне показалось странным, так это то, что ContextMenuStrip.Closing пожары событий до тот ToolStripMenuItem.Click событие.Решением было использовать ContextMenuStrip.ItemClicked мероприятие, на котором у вас есть e.ClickedItem, а затем проверьте, не является ли это одним из элементов, при нажатии на который не закрывается ContextMenuStrip, и установите соответствующий флаг.Затем в ContextMenuStrip.Closing ты можешь установить e.Cancel = true; если флаг также установлен.Однако не забудьте сбросить флаг.

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;
        }
    }
}

Лучший способ сделать это без мерцания — использовать события MouseDown и MouseLeave для каждой кнопки в раскрывающемся меню.

Пример:

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

Я нашел это полезным для своих целей.

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 чтобы прочитать тег или какое-либо другое свойство.

Мне просто нужен был простой элемент, который давал бы пользователю понять, на какой элемент будет влиять контекстное меню.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top