2

i am attaching a single context menu to multiple text box. so, i need to get the control name/reference that used to show the context menu.

below is the sample image of my context menu:

enter image description here

Below is the code for green marked "paste" item click event:

    Dim objTSMI As ToolStripMenuItem
    Dim objCMS As ContextMenuStrip
    Dim objTxtBox As System.Windows.Forms.TextBox
    objTSMI = CType(sender, ToolStripMenuItem)
    objCMS = CType(objTSMI.Owner, ContextMenuStrip)
    objTxtBox = CType(objCMS.SourceControl, System.Windows.Forms.TextBox)
    If Clipboard.ContainsText(TextDataFormat.Text) = True Then
        objTxtBox.SelectedText = Clipboard.GetText(TextDataFormat.Text)
    End If

it works very fine.

but below is my code for red marked "Page count" item click event:

    Dim objTSMI As ToolStripMenuItem
    Dim objCMS As ContextMenuStrip
    Dim objTxtBox As System.Windows.Forms.TextBox
    objTSMI = CType(sender, ToolStripMenuItem)
    objCMS = CType(objTSMI.Owner, ContextMenuStrip)
    objTxtBox = CType(objCMS.SourceControl, System.Windows.Forms.TextBox)
    MessageBox.Show(objTxtBox.Name)

but above throws following error :

Unable to cast object of type 'System.Windows.Forms.ToolStripDropDownMenu' to type 'System.Windows.Forms.ContextMenuStrip'.

here is the screenshot of the error:

enter image description here

so, i can't figure it out what is the issue.

any help would be highly appreciated

Zakir_SZH
  • 466
  • 7
  • 21
  • Couldn't you just tack on another `.Owner`, since you know it's a nested menu? – DonBoitnott Jun 08 '16 at 10:58
  • See this thread: http://stackoverflow.com/questions/12094528/contextmenustrip-owner-property-null-when-retrieving-from-nested-toolstripmenuit. I will give the vb.net answer below with a small twist. – Robin Mackenzie Jun 08 '16 at 11:34

2 Answers2

2

If you check this C# thread the accepted answer notes it is a bug. The workaround presented there uses a private variable to store the SourceControl on the Opening event of the ContextMenuStrip. I've converted to VB.NET and used the Tag of the ContextMenuStrip instead of using the variable. You then refer to the Tag property instead of the faulty SourceControl property:

Imports System.ComponentModel

Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Me.TextBox1.ContextMenuStrip = Me.ContextMenuStrip1
        Me.TextBox2.ContextMenuStrip = Me.ContextMenuStrip1
    End Sub

    Private Sub ContextMenuStrip1_Opening(sender As Object, e As CancelEventArgs) Handles ContextMenuStrip1.Opening
        Me.ContextMenuStrip1.Tag = CType(Me.ContextMenuStrip1.SourceControl, Control)
    End Sub

    Private Sub TestToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles TestToolStripMenuItem.Click
        ' first level of context menu strip
        Dim Strip As ContextMenuStrip = CType(sender, ToolStripMenuItem).Owner
        Dim Box As TextBox = Strip.Tag

        MessageBox.Show(Box.Name)
    End Sub

    Private Sub ChildToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ChildToolStripMenuItem.Click
        ' second level of context menu strip
        Dim Strip As ContextMenuStrip = CType(sender, ToolStripMenuItem).OwnerItem.Owner
        Dim Box As TextBox = Strip.Tag

        MessageBox.Show(Box.Name)
    End Sub

End Class
Community
  • 1
  • 1
Robin Mackenzie
  • 18,801
  • 7
  • 38
  • 56
  • Not a bug, just a misunderstanding. The SourceControl property returns the control that caused the context menu to open. If it's null, there was no control involved in causing the context menu to open. This will work around the problem, but the better idea would be to write the code so that this information is not required. I've used lots of context menus and never needed this. – Cody Gray - on strike Jun 08 '16 at 13:51
  • @CodyGray http://stackoverflow.com/questions/37703891/how-to-get-parent-control-from-context-menu-item-vb-net this is my question, I would like you to take a look at my scenario and suggest whats the other and reliable ways to solve this problem? without using the Robin's method. – Muhammad Saqib Jun 08 '16 at 14:04
  • Your question contains no additional background information that might help me to suggest an alternative solution. There's no mention of *why* you are trying to obtain this information, or what you're going to do with it. You just show your proposed solution (using the `SourceControl` property) and show why it won't work. Which is a fine way to ask a question, but only gets you a limited range of answers. It is, in general, a violation of the SRP for a context menu to need to know details about another control in your application. @muh – Cody Gray - on strike Jun 08 '16 at 14:06
  • @CodyGray - yes, interested to see a solution that doesn't involve the workaround. The issue is very easy to replicate though - if you cast the `ToolstripMenuItem.OwnerItem.Owner` to the `ContextMenuStrip` and examine `SourceControl` it is `Nothing` - even though the `Textbox` caused the context menu to open. I guess you are saying that using this cast is the wrong approach? – Robin Mackenzie Jun 08 '16 at 14:08
  • @Robin, whether it is a bug or not, i am more concerned about working solution than arguing with it. and robin solution works just fine so, i will accept his as answer. Just as i have Option Strict On, i needed to ctype both line like CType(Strip.Tag, TextBox). thanks again... – Zakir_SZH Jun 08 '16 at 17:11
  • @Robin, i would suggest if you kindly edit your answer to add ctype to your code, so i can accept your answer. i don't want to edit it, because i like the credit for this answer should only goes to you :) – Zakir_SZH Jun 08 '16 at 17:12
0
Dim ControlsName as string 
Private Sub ContextMenuStrip1_Opening(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles ContextMenuStrip1.Opening
        ControlsName= ContextMenuStrip1.SourceControl.Name.ToString
End Sub
  • 1
    Please consider adding a brief explanation of [how and why this solves the problem](https://meta.stackoverflow.com/q/392712/13138364). This will help readers to better understand your solution. – tdy Nov 16 '21 at 04:25