如何解决ContextMenuStrip 需要两次右键才能显示
我喜欢以编程方式创建我的上下文菜单。我通常不会将项目添加到上下文菜单条,直到它打开,因为显示的项目取决于设计的其他可变方面。
我发现上下文菜单条似乎需要两次右键单击才能显示。我尝试在不同的事件(打开、打开等)中添加菜单项,并手动将 contextmenustrip 的可见性设置为 true 无济于事。
我终生无法弄清楚为什么需要两次右键单击。如果你创建一个空白的 winforms 项目,然后用这个替换所有的代码,它会证明这个问题。
Public Class Form1
Private Sub Form1_Load(sender As Object,e As EventArgs) Handles Me.Load
Dim currContextMenuStrip As New ContextMenuStrip
Me.ContextMenuStrip = currContextMenuStrip
AddHandler currContextMenuStrip.opening,AddressOf ContextMenuStrip1_opening
End Sub
Private Sub ContextMenuStrip1_opening(sender As Object,e As CancelEventArgs)
Dim currContextMenuStrip As ContextMenuStrip = sender
Dim menuTxt As String = "&Find"
'only add the menu if it doesn't already exist
If (From f In currContextMenuStrip.Items Where f.text = menuTxt).Count = 0 Then
Dim newMenuItem As New ToolStripMenuItem
newMenuItem.Text = menuTxt
currContextMenuStrip.Items.Add(newMenuItem)
End If
End Sub
End Class
编辑:刚刚发现它似乎与第一次右键单击时上下文菜单条没有任何项目的事实有关。如果我添加了一个虚拟项目,然后在添加其他项目后隐藏它,它在第一次右键单击时起作用。好纠结!
这有效:
Private Sub Form1_Load(sender As Object,AddressOf ContextMenuStrip1_opening
'add a dummy item
Dim newMenuItem As New ToolStripMenuItem
newMenuItem.Text = "dummy"
currContextMenuStrip.Items.Add(newMenuItem)
End Sub
Private Sub ContextMenuStrip1_opening(sender As Object,e As CancelEventArgs)
Dim currContextMenuStrip As ContextMenuStrip = sender
Dim menuTxt As String = "&Find"
'only add the menu if it doesn't already exist
If (From f In currContextMenuStrip.Items Where f.text = menuTxt).Count = 0 Then
Dim newMenuItem As New ToolStripMenuItem
newMenuItem.Text = menuTxt
currContextMenuStrip.Items.Add(newMenuItem)
End If
'hide the dummy item
Dim items As List(Of ToolStripMenuItem) = (From f As ToolStripMenuItem In currContextMenuStrip.Items Where f.Text = "dummy").ToList
items.First.visible = False
End Sub
End Class
解决方法
如果您确实需要以这种方式做事,一种选择是创建您自己的自定义 ContextMenuStrip
,以说明没有项目时的行为以及对虚拟项目的要求。我使用了这个代码:
Imports System.ComponentModel
Public Class Form1
Private WithEvents menu As New ContextMenuStrip
Private Sub Form1_Load(sender As Object,e As EventArgs) Handles MyBase.Load
ContextMenuStrip = menu
End Sub
Private Sub menu_Opening(sender As Object,e As CancelEventArgs) Handles menu.Opening
If menu.Items.Count = 0 Then
menu.Items.AddRange({New ToolStripMenuItem("First"),New ToolStripMenuItem("Second"),New ToolStripMenuItem("Third")})
End If
End Sub
Private Sub menu_ItemClicked(sender As Object,e As ToolStripItemClickedEventArgs) Handles menu.ItemClicked
MessageBox.Show(e.ClickedItem.Text)
End Sub
End Class
并看到了您描述的相同行为。然后我定义了这个类:
Public Class ContextMenuStripEx
Inherits ContextMenuStrip
Private dummyItem As ToolStripItem
Public ReadOnly Property IsInitialised As Boolean
Get
Return dummyItem Is Nothing
End Get
End Property
Public Sub New()
dummyItem = Items.Add(CStr(Nothing))
End Sub
''' <inheritdoc />
Protected Overrides Sub OnItemAdded(e As ToolStripItemEventArgs)
If Not IsInitialised Then
Items.Remove(dummyItem)
dummyItem = Nothing
End If
MyBase.OnItemAdded(e)
End Sub
End Class
并将我的表单代码更改为:
Imports System.ComponentModel
Public Class Form1
Private WithEvents menu As New ContextMenuStripEx
Private Sub Form1_Load(sender As Object,e As CancelEventArgs) Handles menu.Opening
If Not menu.IsInitialised Then
menu.Items.AddRange({New ToolStripMenuItem("First"),e As ToolStripItemClickedEventArgs) Handles menu.ItemClicked
MessageBox.Show(e.ClickedItem.Text)
End Sub
End Class
它按预期工作。请注意,最后一个代码段使用了自定义类型及其自定义属性。
,感谢大家的帮助和建议!我最终决定在 Designer 中构建菜单超集,然后在运行时显示/隐藏。这可能比每次右键单击都要快,然后每次都重建菜单。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。