Не закрывайте ContextMenuStrip при выборе определенных элементов - PullRequest
14 голосов
/ 15 мая 2009

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

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

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

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

Ответы [ 9 ]

24 голосов
/ 19 мая 2012

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

private void contextMenuStrip_Closing(object sender, ToolStripDropDownClosingEventArgs e)
{
    if (e.CloseReason == ToolStripDropDownCloseReason.ItemClicked)
        e.Cancel = true;
}
4 голосов
/ 24 мая 2009

Закрывающее событие

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

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

3 голосов
/ 09 июля 2009

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

При событии 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
1 голос
/ 29 июля 2016

Что мне показалось странным, так это то, что событие 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;
        }
    }
}
1 голос
/ 08 февраля 2016

Это мой метод; он без мерцания и - я думаю - немного более гибкий.

Если у вас есть набор 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
1 голос
/ 17 сентября 2009

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

1 голос
/ 15 мая 2009

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

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

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

0 голосов
/ 29 января 2017

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

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 для чтения тега или другого свойства.

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

0 голосов
/ 30 сентября 2015

Лучший способ сделать это без мерцания - использовать события 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
...