You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 09:14:57