Vb.net ContextMenuStrip选定项在UserControl中丢失

Vb.net ContextMenuStrip选定项在UserControl中丢失,vb.net,datagridview,user-controls,contextmenu,Vb.net,Datagridview,User Controls,Contextmenu,我有一个VB.NET用户控件,它嵌入到另一个用户控件中,并嵌入到窗体中。内部用户控件具有由DataGridView行单击触发的contextmenustrip。这将成功激活事件处理程序“我看到了确定消息”,但发件人未发送所选项目“我没有看到其他MsgBox消息”。代码如下: Public CMSV As ContextMenuStrip Private grdSourceViewerCurrentRow As Long Public Sub grdSourceViewer_RowHeader

我有一个VB.NET用户控件,它嵌入到另一个用户控件中,并嵌入到窗体中。内部用户控件具有由DataGridView行单击触发的contextmenustrip。这将成功激活事件处理程序“我看到了确定消息”,但发件人未发送所选项目“我没有看到其他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

这对我不起作用;我试过了。CMSV.Items.Add可以接受文本字符串或ToolStripMenuItem。在任何一种情况下,它都会创建该项。所以造成这个问题的原因比较复杂。你们两个都是正确的,而且都很有帮助。我需要设置一次CM,并为这两个CM项设置一个事件处理程序。这很有效。我的策略是在没有嵌套的用户控件中工作,但这种复杂性暴露了我有缺陷的逻辑。