C# 不要在选择某些项目时关闭 ContextMenuStrip
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/866689/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Do not close ContextMenuStrip on selection of certain items
提问by barry
Is it possible to leave a ContextMenuStrip open after a selection/check of certain items?
在选择/检查某些项目后,是否可以让 ContextMenuStrip 保持打开状态?
I plan on using a simple ContextMenuStrip to set a filter (this way i could use the same filter either in a menu or as a right-click option).
我计划使用一个简单的 ContextMenuStrip 来设置过滤器(这样我可以在菜单中或作为右键单击选项使用相同的过滤器)。
The menu lists a number of items, and i would like the user to be able to make a selection of the items using the basic Check functionality. Once the selection is done the user can click an Activate filter option or can click outside the menu to either activate or cancel the filter.
菜单列出了许多项目,我希望用户能够使用基本的检查功能来选择项目。选择完成后,用户可以单击“激活过滤器”选项或单击菜单外以激活或取消过滤器。
On a selection/click event the menu normally closes. Is it possible to keep the menu open on a click event?
在选择/单击事件中,菜单通常会关闭。是否可以在单击事件时保持菜单打开?
采纳答案by user89894
To prevent the contextmenu from closing when an item is clicked, do the following.
要防止在单击项目时关闭上下文菜单,请执行以下操作。
On mousedown event of ContextMenuItems set flag to false then set it back to true at the closing event of the contextmenu.
在 ContextMenuItems 的 mousedown 事件中,将标志设置为 false,然后在上下文菜单的关闭事件中将其设置回 true。
Example:
例子:
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
回答by Meta-Knight
I don't think there is a property for this in the ContextMenuStrip.
我认为 ContextMenuStrip 中没有此属性。
The workaround we use in our application is that on the clicked event of the ContextMenuStrip, we do some processing, then if we want the context menu to stay open we simply call ContextMenuStrip.Show again.
我们在应用程序中使用的解决方法是,对 ContextMenuStrip 的 clicked 事件进行一些处理,然后如果我们希望上下文菜单保持打开状态,我们只需再次调用 ContextMenuStrip.Show。
This will work well if there is only one level to the ContextMenuStrip. If there are sub-menus and sub-sub-menus, then you would have to re-select the menus that were open before the click and I'm not sure how that can be done...
如果 ContextMenuStrip 只有一层,这将很有效。如果有子菜单和子子菜单,那么您必须重新选择单击之前打开的菜单,我不确定如何做到这一点......
回答by user89894
the Closing event
闭幕式
set e.Cancel = true to leave the menu open
设置 e.Cancel = true 使菜单保持打开状态
only problem is the event doesn't tell you what was clicked, so you have to keep track of this yourself. set some kind of flag in the Click event of the items you want to keep the menu open. then in the Closing event check the flag and set e.Cancel appropriately.
唯一的问题是事件不会告诉你点击了什么,所以你必须自己跟踪。在要保持菜单打开的项目的 Click 事件中设置某种标志。然后在 Closing 事件中检查标志并适当设置 e.Cancel。
回答by user89894
OnClosing, do: e.Cancel = e.CloseReason != ToolStripDropDownCloseReason.CloseCalled; and then when you decide to close, call Close().
OnClosing,执行: e.Cancel = e.CloseReason != ToolStripDropDownCloseReason.CloseCalled; 然后当您决定关闭时,调用 Close()。
回答by Delirious
In case future programers are wondering how to do this, this is what I figured out. This will not close the context menu if any item is clicked. Create the context menu strip closing event and setup an if statement to cancel the close event if close reason is itemclicked.
如果未来的程序员想知道如何做到这一点,这就是我想出来的。如果单击任何项目,这不会关闭上下文菜单。创建上下文菜单条关闭事件并设置 if 语句以在关闭原因是 itemclicked 时取消关闭事件。
private void contextMenuStrip_Closing(object sender, ToolStripDropDownClosingEventArgs e)
{
if (e.CloseReason == ToolStripDropDownCloseReason.ItemClicked)
e.Cancel = true;
}
回答by geomad
The best way I found to do this without flickering is to use the MouseDown and MouseLeave events for every button in the DropDown menu.
我发现在不闪烁的情况下执行此操作的最佳方法是对 DropDown 菜单中的每个按钮使用 MouseDown 和 MouseLeave 事件。
Example:
例子:
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
回答by Jens
This is my method; it's flicker-free and - I think - a bit more flexible.
这是我的方法;它没有闪烁,而且 - 我认为 - 更灵活一些。
If you have a set of ToolStripMenuItems you'd like to use as toggle buttons (option on/off), try this:
如果您有一组 ToolStripMenuItems 想要用作切换按钮(选项开/关),请尝试以下操作:
(The ctxWildCards
is just my ContextMenuStrip
, used to select filters based on file types - for search or FileDialogs)
(这ctxWildCards
只是我的ContextMenuStrip
,用于根据文件类型选择过滤器 - 用于搜索或 FileDialogs)
This is in Visual Basic (obviously! ;), so you can add Handlers programmatically or using 'Handles...' clauses.
这是在 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
回答by Arctic_Avenger
What i found strange is that ContextMenuStrip.Closing
event fires beforethe ToolStripMenuItem.Click
event. The solution was to use ContextMenuStrip.ItemClicked
event where you have e.ClickedItem
, and then check if it's one of the items that, when clicked, won't close the ContextMenuStrip
, and set the appropriate flag. Then in ContextMenuStrip.Closing
you can set e.Cancel = true;
if the flag is also set. Don't forget to reset the flag though.
我发现奇怪的是,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;
}
}
}
回答by Regular Joe
I found this useful for my purposes.
我发现这对我的目的很有用。
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
You could use ItemClicked
to read the tag or some other property.
您可以ItemClicked
用来读取标签或其他一些属性。
I just wanted a simple item that made clear to the user which item the context menu was going to effect.
我只是想要一个简单的项目,让用户清楚上下文菜单将影响哪个项目。