VB.NET Menu Strip子菜单点击无法返回名称/索引问题求助
问题
我有一个名为Contact的Menu Strip,包含Customer、Supplier、Contact三个子菜单,这些子菜单是根据用户权限通过代码动态创建的。当点击其中一个子菜单(例如Contact菜单下的Customer)时,希望获取该子项的名称或索引以打开对应窗体,但使用以下代码:
MsgBox(DirectCast(sender, ToolStripMenuItem).Text)
或
MsgBox(DirectCast(sender, ToolStripDropDownItem).Text)
总是返回"Contact",而非点击的子项。
动态添加子菜单的代码:
Private Sub LoadMenu(ByVal strMenuSet As String) 'This function is used to show the menu based on the clicked menu with the permission already set' Dim cText, cPerm As Object Dim cMenu, cMenu0, cMenu1, cMenu2, cMenu3, cMenu4, cMenu5, cMenu6, cMenu7, cMenu8, cMenu9 As Object Dim intLoad As Integer Dim intI As Integer cMenu = mnu cMenu0 = mnu0 cMenu1 = mnu1 cMenu2 = mnu2 cMenu3 = mnu3 cMenu4 = mnu4 cMenu5 = mnu5 cMenu6 = mnu6 cMenu7 = mnu7 cMenu8 = mnu8 cMenu9 = mnu9 'if there is a button is clicked, it will trigger the menu and show in the menu strip' Select Case strMenuSet Case "Editor" cMenu.ToString() With cMenu cText = {"&File", "Contact", "Items", "Machines", "Tools", "", "", "", "", "", "", ""} cPerm = {"Perm1", "Perm2", "Perm3", "Perm4", "Perm5"} For intI = 0 To 9 If cText(intI) = "" Then .Items(intI).Enabled = False .Items(intI).Visible = False Else If fPermission(par1, par2, par3) Then .Items(intI).Text = cText(intI) .Items(intI).Enabled = True .Items(intI).Visible = True Else .Items(intI).Enabled = False .Items(intI).Visible = False End If End If Next End With 'and if I click "Contact", it will generate submenu like the picture I attach before' With cMenu1 cText = {"*", "Customer", "Supplier", "Contact"} cPerm = {"Perm1", "Perm2", "Perm3", "Perm4"} For intI = 0 To 1 If intI = 0 Then intLoad = 0 .DropDownItems.Add(".") .DropDownItems(intLoad).Visible = False Else If fPermission(lngPubUserId, cPerm(intI), "prmOpen") Then intLoad += 1 .DropDownItems.Add(intLoad).Text = cText(intI) .DropDownItems(intLoad).Enabled = True .DropDownItems(intLoad).Visible = True Else .DropDownItems(intLoad).Enabled = False .DropDownItems(intLoad).Visible = False End If End If Next End With End Sub
当前事件处理代码:
Private Sub mnu1_Click(sender As Object, e As EventArgs) Handles mnu1.Click MsgBox(DirectCast(val.OwnerItem, ToolStripMenuItem).Text) End Sub
请问如何实现点击子菜单时获取对应子项的名称或索引?
解决方案
问题根源
你当前的事件处理绑定的是父菜单mnu1(即"Contact"菜单)的Click事件,无论点击它的哪个子项,触发的都是父菜单的事件,sender指向父菜单而非子项,因此返回的是"Contact"。
正确实现步骤
1. 修改动态添加子菜单的代码
在创建每个子菜单项时,单独绑定专属的点击事件:
With cMenu1 cText = {"*", "Customer", "Supplier", "Contact"} cPerm = {"Perm1", "Perm2", "Perm3", "Perm4"} For intI = 0 To 1 If intI = 0 Then intLoad = 0 .DropDownItems.Add(".") .DropDownItems(intLoad).Visible = False Else If fPermission(lngPubUserId, cPerm(intI), "prmOpen") Then intLoad += 1 ' 实例化子菜单项并设置属性 Dim subMenuItem As New ToolStripMenuItem(cText(intI)) subMenuItem.Enabled = True subMenuItem.Visible = True ' 绑定点击事件到通用处理方法 AddHandler subMenuItem.Click, AddressOf SubMenuItem_Click ' 将子项添加到父菜单的下拉列表中 .DropDownItems.Add(subMenuItem) Else .DropDownItems(intLoad).Enabled = False .DropDownItems(intLoad).Visible = False End If End If Next End With
2. 编写通用子菜单点击事件处理方法
创建专门处理子项点击的方法,直接获取点击的子项信息:
Private Sub SubMenuItem_Click(sender As Object, e As EventArgs) ' 获取点击的子菜单项 Dim clickedItem As ToolStripMenuItem = DirectCast(sender, ToolStripMenuItem) ' 获取子项名称 MsgBox("点击的子项名称:" & clickedItem.Text) ' 获取子项在父菜单中的索引 Dim parentMenu As ToolStripMenuItem = DirectCast(clickedItem.OwnerItem, ToolStripMenuItem) Dim itemIndex As Integer = parentMenu.DropDownItems.IndexOf(clickedItem) MsgBox("点击的子项索引:" & itemIndex) ' 根据子项名称打开对应窗体 Select Case clickedItem.Text Case "Customer" Dim customerForm As New CustomerForm() customerForm.Show() Case "Supplier" Dim supplierForm As New SupplierForm() supplierForm.Show() Case "Contact" Dim contactForm As New ContactForm() contactForm.Show() End Select End Sub
3. 清理冗余代码
删除原来绑定到mnu1.Click的mnu1_Click方法,避免父菜单事件被误触发。
内容的提问来源于stack exchange,提问作者Mr Bim
相关产品推荐
相关产品推荐

