【问题标题】:How can I find the sender of ContextMenuStrip?如何找到 ContextMenuStrip 的发件人?
【发布时间】:2015-07-15 11:51:37
【问题描述】:

情况:

我在 VB.NET 表单中有一个上下文菜单,它在 ItemClicked 上触发一个事件处理程序。自动生成的子程序接收sendere 作为参数。由于我没有多次重新发明轮子,因此我将此上下文菜单链接到三个文本框。我们将它们命名为 Textbox1、Textbox2 和 Textbox3。

问题:如何确定菜单是在哪个文本框中打开的?

好的,我已经尝试了什么?

  • sender 包含菜单本身,
  • e.ClickedItem 只返回被选中的单个菜单项。
  • sender.Parent 永远什么都不是
  • sender.OwnerItem 也总是什么都没有`
  • Me.Textbox1.Focused 始终是 False,即使它是菜单的“父”控件。

【问题讨论】:

    标签: vb.net


    【解决方案1】:

    好的,我找到了一个很好的解决方案,这里是所有有相同问题的 VB.NET 编码器的代码。

    上下文菜单链接在 TextBox1 中,因此我们需要添加另一个事件处理程序,将发送控件保存到菜单中:

    Private Sub TextBox1_MouseUp(sender As Windows.Forms.Control, e As System.Windows.Forms.MouseEventArgs) Handles TextBox1.MouseUp
        If e.Button = Windows.Forms.MouseButtons.Right Then
            ContextMenu.Tag = sender
        End If
    End Sub
    

    这是单击菜单项时事件处理程序的代码:

    Private Sub ContextMenu_ItemClicked(sender As System.Object, e As System.Windows.Forms.ToolStripItemClickedEventArgs) Handles ContextMenu.ItemClicked
        ContextMenu.Close()
    
        If ContextMenu.Tag Is Nothing Then
            Debug.Print("debug info: forgot to set sender? well ... KABOOM!")
            Exit Sub
        End If
    
        Dim oParent As Windows.Forms.Control
        Try
            oParent = ContextMenu.Tag
        Catch ex As Exception
            Debug.Print("debug info: tag contains data other than sender control. well ... KABOOM!")
            Exit Sub
        End Try
    
        ' Do fancy stuff here.
    
        ' Release sender
        ContextMenu.Tag = Nothing
    End Sub
    

    【讨论】:

      【解决方案2】:

      ContextMenuStrip 有一个SourceControl 属性,其中包含对打开菜单的控件的引用。该事件从 ContextMenuStrip 中的 ToolStripMenuItems 之一触发,因此您必须先获取“父级”:

      ' cast sender to menuitem
      Dim mi = CType(sender, ToolStripMenuItem)
      ' cast mi.Owner to CMS
      Dim cms = CType(mi.Owner, ContextMenuStrip)
      
      ' the control which opened the menu:
      Console.WriteLine(cms.SourceControl.Name)
      

      在某些条件下the SourceControl can get lost 但您可以自己使用变量和父 ContextMenuStrip 打开事件进行跟踪:

      ' tracking var:
      Private MenuSourceControl As Control
      Private Sub cms_Opening(sender As Object, e As CancelEventArgs) Handles cms.Opening
          ' set reference in case/before it is lost
          MenuSourceControl = CType(sender, ContextMenuStrip).SourceControl
      End Sub
      
      Private Sub CutToolStripMenuItem_Click(sender...
          If MenuSourceControl IsNot Nothing Then
              ' do your stuff
      
              ' optionally clear the tracking var
              MenuSourceControl = Nothing
          End If
      End Sub
      

      在处理子项的时候应该也更容易得到SourceControl


      在同一个菜单与不同控件一起使用的情况下,您还可以在相关ControlMouseDown 事件中捕获相关控件:

      Private Sub lv2_MouseDown(sender As Object, 
               e As MouseEventArgs) Handles lv2.MouseDown,
                        myLV.MouseDown, lv1.MouseDown ...
      
          If e.Button = Windows.Forms.MouseButtons.Right Then
              MenuSourceControl = DirectCast(sender, Control)
          End If
      End Sub
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-28
        • 2014-01-31
        • 2010-09-21
        • 2010-10-29
        • 2013-11-24
        • 1970-01-01
        相关资源
        最近更新 更多