0

I have a form with numerous charts and have added a ContextMenuStrip when a chart is right clicked so the user can copy the chart image to the clipboard

 Public Sub Chart_Click(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Chart1.MouseClick, _
          Chart2.MouseClick, Chart3.MouseClick, Chart4.MouseClick 

    If e.Button = MouseButtons.Right Then
        Dim cmus As ContextMenuStrip = New ContextMenuStrip

        Dim cms1 As ToolStripMenuItem = New ToolStripMenuItem("Copy as Image")
        cms1.Tag = 0
        cmus.Items.Add(cms1)

        For Each c As ToolStripMenuItem In cmus.Items
            AddHandler c.Click, AddressOf Chart_cMenu_Click
        Next

        cmus.Show(New Point(Control.MousePosition.X, Control.MousePosition.Y))
    End If

End Sub

Then I would like to identify which chart was clicked on so that I can copy that chart to the clipboard. This seems like a simple problem to me but I cannot figure out why no matter what I do trying to identify the Owner,Parent,SourceControl of the right click menu always returns me a Nothing value.

Public Sub Chart_cMenu_Click(ByVal sender As Object, ByVal e As EventArgs)

    Dim menuItem As ToolStripMenuItem = CType(sender, ToolStripMenuItem)
    Dim cms As ContextMenuStrip = CType(menuItem.Owner, ContextMenuStrip)

    Dim _owner As Control = CType(cms.SourceControl, Chart)

    Select Case menuItem.Text
        Case "Copy as Image"

            Dim ms As New System.IO.MemoryStream(100)

            _owner.SaveImage(ms, ChartImageFormat.Bmp)

            Dim bm As Bitmap = New Bitmap(ms)
            Clipboard.SetImage(bm)

    End Select
End Sub

Any ideas how to identify the source chart?

TylerDurden
  • 1,632
  • 1
  • 20
  • 30
  • possible duplicate of [ContextMenuStrip.Owner Property null When Retrieving From Nested ToolStripMenuItem](http://stackoverflow.com/questions/12094528/contextmenustrip-owner-property-null-when-retrieving-from-nested-toolstripmenuit) – LarsTech Feb 13 '14 at 17:43
  • still getting `menuSource = (CType(sender,ContextMenuStrip)).SourceControl` is `Nothing` using that solution – TylerDurden Feb 13 '14 at 18:04

2 Answers2

0

Have a messy solution. Going to leave this open in case a more elegant solution can be formed.

Add a name to your new ContextMenuStrip that reflects the Sender. This can then be used in the MouseClick method to find the origin

Public Sub Chart_Click(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Chart1.MouseClick, _
      Chart2.MouseClick, Chart3.MouseClick, Chart4.MouseClick 

       If e.Button = MouseButtons.Right Then
            Dim cmus As ContextMenuStrip = New ContextMenuStrip

            'Add the name to menu
            cmus.Name = sender.Name & "_CMS"

            Dim cms1 As ToolStripMenuItem = New ToolStripMenuItem("Copy as Image")
            cms1.Tag = 0
            cmus.Items.Add(cms1)

            For Each c As ToolStripMenuItem In cmus.Items
                AddHandler c.Click, AddressOf Chart_cMenu_Click
            Next

            cmus.Show(New Point(Control.MousePosition.X, Control.MousePosition.Y))
       End If

End Sub

Now find the control that corresponds to the new name

Public Sub Chart_cMenu_Click(ByVal sender As Object, ByVal e As EventArgs)

    Dim cms As ToolStripMenuItem = CType(sender, ToolStripMenuItem)
    Dim _owner As ContextMenuStrip = CType(cms.Owner, ContextMenuStrip)

    'This is where you use the name attached to the ContextMenuStrip
    Dim _chartname As String = Replace(_owner.Name, "_CMS", "")

    Dim parentObject As Chart = Nothing
    Try
        parentObject = CType(Me.Controls.Find(_chartname, True)(0), Chart)
    Catch ex As Exception

    End Try

    If Not parentObject Is Nothing Then
        Select Case cms.Text
            Case "Copy as Image"

                Dim ms As New System.IO.MemoryStream(100)

                parentObject.SaveImage(ms, ChartImageFormat.Bmp)

                Dim bm As Bitmap = New Bitmap(ms)
                Clipboard.SetImage(bm)

        End Select
    End If

End Sub

Still think there should be an easier solution than this using the likes of Parent,Owner and SourceControl

TylerDurden
  • 1,632
  • 1
  • 20
  • 30
0

My VB is rusty, but the below code works fine for me.

Dim menu As New ContextMenuStrip()
menu.ItemClicked += New ToolStripItemClickedEventHandler(menu_ItemClicked)
menu.Items.Add("Save As Image")
chart1.ContextMenuStrip = menu
chart2.ContextMenuStrip = menu;

Private Sub menu_ItemClicked(sender As Object, e As ToolStripItemClickedEventArgs)
    If e.ClickedItem.ToString() = "Save As Image" Then
        Dim menu As ContextMenuStrip = TryCast(sender, ContextMenuStrip)
        If menu IsNot Nothing AndAlso menu.SourceControl IsNot Nothing Then
            Dim chart As Chart = TryCast(menu.SourceControl, Chart)
            Dim dlg As New SaveFileDialog()
            If chart IsNot Nothing AndAlso dlg.ShowDialog() = DialogResult.OK Then
                chart.SaveImage(dlg.FileName, ChartImageFormat.Jpeg)
            End If
        End If
    End If
End Sub
Junaith
  • 3,298
  • 24
  • 34