UserControl 中丢失的 ContextMenuStrip 选定项

ContextMenuStrip selected item lost in UserControl

我有一个 VB.NET 用户控件,它嵌入到另一个用户控件中并嵌入到一个表单中。内部用户控件有一个由 DataGridView 行点击触发的上下文菜单条。这成功激活了事件处理程序(我看到了 "OK" 消息),但是发送者没有发送所选项目(我没有看到其他 MsgBox 消息)。这是代码:

Public CMSV As ContextMenuStrip

Private grdSourceViewerCurrentRow As Long

Public Sub grdSourceViewer_RowHeaderMouseClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles grdSourceViewer.RowHeaderMouseClick
    'code to review/edit source details
     Select Case e.Button
        Case Windows.Forms.MouseButtons.Right
            grdSourceViewerCurrentRow = e.RowIndex  'retain for downstream code
            CMSV = New ContextMenuStrip
            AddHandler CMSV.MouseClick, AddressOf SourceViewDocumentationEdit
            CMSV.Items.Add("Edit")
            CMSV.Items.Add("Transfer to Evidence")
            Dim Pt As Point = New Point()
            Pt.X = grdSourceViewer.PointToClient(Cursor.Position).X
            Pt.Y = grdSourceViewer.PointToClient(Cursor.Position).Y + 20

            CMSV.Show(sender, Pt)

        Case Windows.Forms.MouseButtons.Left
            Exit Sub
        Case Else
            Exit Sub
    End Select
End Sub

Public Sub SourceViewDocumentationEdit()
    MsgBox("OK") 'I can see it reaches here
    Dim cc As ToolStripItemCollection = CMSV.Items
    Dim SelectedItem As Integer = -1
    Dim SelectedValue As String = ""

    For i As Integer = 0 To cc.Count - 1
        If cc.Item(i).Selected Then
            SelectedItem = i
            SelectedValue = cc.Item(SelectedItem).Text
            Exit For
        End If
    Next

    Select Case SelectedValue
        Case "Edit"
            MsgBox("Edit code here")
        Case "Transfer to Evidence"
            MsgBox("Transfer code here")
    End Select
End Sub

这里有什么问题?为什么我丢失了有关被单击项目的信息?

您需要使用 ToolStripMenuItem 而不仅仅是字符串。然后你可以为它的点击事件添加处理程序。

Dim tsmi As New ToolStripMenuItem
tsmi.Text = "Edit"
AddHandler tsmi.Click, AddressOf ItemClicked
CMSV.Items.Add(tsmi)

然后事件子:

Private Sub ItemClicked(sender As Object, e As EventArgs)
 'item clicked
 'sender object would be the ToolStripMenuItem
End Sub

为什么每次都要重新创建菜单?

无论如何,存储 CMSV.Items.Add() 返回的 ToolStripMenuItem 并将其连接起来。

简化示例:

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    CMSV = New ContextMenuStrip
    Dim TSMI As ToolStripMenuItem
    TSMI = CMSV.Items.Add("Edit")
    AddHandler TSMI.Click, AddressOf TSMI_Click
    TSMI = CMSV.Items.Add("Transfer to Evidence")
    AddHandler TSMI.Click, AddressOf TSMI_Click
    ' ...
End Sub

Private Sub TSMI_Click(sender As Object, e As EventArgs)
    Dim TSMI As ToolStripMenuItem = DirectCast(sender, toolstripmenuitem)
    Select Case TSMI.Text
        Case "Edit"
            Debug.Print("...Edit Code...")
            ' use "grdSourceViewerCurrentRow " in here?
        Case "Transfer to Evidence"
            Debug.Print("...Transfer to Evidence Code...")
            ' use "grdSourceViewerCurrentRow " in here?
    End Select
End Sub