大家好,圣诞快乐。
我最近继承了一个必须添加功能的VB项目。所以我有以下代码:
Private Sub AddItems()
Dim itemMenu = DirectCast(ContextMenuStrip.Items.Find("name", False)(0), ToolStripMenuItem)
For Each dbObject In dbObjects
Dim item As New ToolStripMenuItem(dbObject.Name)
item.Tag = dbObject
AddHandler item.Click, AddressOf Item_Click
itemMenu.DropDownItems.Add(item)
Next
End Sub
Private Sub RemoveItems()
Dim itemMenu = DirectCast(ContextMenuStrip.Items.Find("name", False)(0), ToolStripMenuItem)
For Each item As ToolStripItem In itemMenu.DropDownItems
RemoveHandler item.Click, AddressOf Item_Click
Next
itemMenu.DropDownItems.Clear()
End Sub
Private Sub ContextMenuStrip_Opening(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles ContextMenuStrip.Opening
AddItems()
End Sub
Private Sub ContextMenuStrip_Closing(sender As Object, e As ToolStripDropDownClosingEventArgs) Handles ContextMenuStrip.Closing
RemoveItems()
End Sub
Private Sub Item_Click(sender As Object, e As EventArgs)
' Do the work
End Sub
逻辑是每次使用有效的数据库对象填充上下文菜单中的子菜单。
问题是此代码不起作用。它将项目完美地添加到上下文菜单中,但AddHandler item.Click, AddressOf Item_Click
不执行任何操作。
奇怪的是,如果我在AddItems()
中拨打Form_Load
,那么它就会完美无缺。
任何帮助都将不胜感激。
2016.12.22 WozzeC回答后的解决方案
Private Sub AddItems()
RemoveItems()
Dim itemMenu = DirectCast(ContextMenuStrip.Items.Find("name", False)(0), ToolStripMenuItem)
For Each dbObject In dbObjects
Dim item As New ToolStripMenuItem(dbObject.Name)
item.Tag = dbObject
AddHandler item.Click, AddressOf Item_Click
itemMenu.DropDownItems.Add(item)
Next
End Sub
Private Sub RemoveItems()
Dim itemMenu = DirectCast(ContextMenuStrip.Items.Find("name", False)(0), ToolStripMenuItem)
For Each item As ToolStripItem In itemMenu.DropDownItems
RemoveHandler item.Click, AddressOf Item_Click
Next
itemMenu.DropDownItems.Clear()
End Sub
Private Sub ContextMenuStrip_Opening(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles ContextMenuStrip.Opening
AddItems()
End Sub
Private Sub Item_Click(sender As Object, e As EventArgs)
' Do the work
End Sub
答案 0 :(得分:1)
我已经玩了一段时间了,我已经成功地重现了你的问题。令人头疼的原因是RemoveItems在Click事件之前触发。因此,当您执行RemoveHandler时,单击事件将消失。
我建议你做的是不在ContextMenuItems上添加点击处理程序。而是在Parent节点上为DropDownItemClicked添加EventHandler。结果将与Item.Click一样工作,但没有动态处理Handler的麻烦。
我还尝试在ContextMenu上为RemoveItems切换Closing到Closed事件。但恐怕无济于事。
解决此问题的另一种方法是将RemoveItems移动到AddItems的第一行。然后删除关闭事件及其对RemoveItems的调用。这意味着无论何时您想要创建新的ContextMenu,前一个都会正确处理。这也将解决您将来添加两次或更多次ContextMenu项目的错误。如果您非常快速地多次右键单击,目前会发生这种情况。