littleleaf
littleleaf

Reputation: 13

vb.net get contextmenustrip applicable to multiple pictureboxes

In my form I have several pictureboxes and one contextmenustrip, the contextmenustrip is supposed to use at all these pictureboxes.

A tool in the contextmenustrip is to open and view the a pdf file.

The current code is:

    Private Sub ViewToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ViewToolStripMenuItem.Click
    Process.Start("C:\Program Files (x86)\Adobe\Reader 11.0\Reader\AcroRd32.exe", "C:\vb_test\" + picDrawing(1))
End Sub

I have no idea how the tool can determine which picturebox is focused and open different files.

I am using vb.net.

Upvotes: 0

Views: 701

Answers (3)

Karl Stephen
Karl Stephen

Reputation: 1140

This answer is likely the same as tezzo's.
Just used to this scenario a lot, and wanted to share some security checks among many others that may help.


Assuming

  • ONLY PictureBoxes can show your ContextMenu named MyContextMenu :
  • and you have a ToolStripMenuItem named ViewToolStripMenuItem

Declarations :

Option Strict On
Option Explicit On
Option Infer Off

Imports System.IO
' File.Exist()
Imports System.Diagnostics
' Process.Start()

Public Class Form1

    Private p_SelectedPictureB As PictureBox
    Private p_AcroRedPath As String = "C:\Program Files (x86)\Adobe\Reader 11.0\Reader\AcroRd32.exe"
    Private p_ImageFolderPath As String = "C:\vb_test\"
    Private p_TargetFileName As String = ""

    ' ...

End Class

Handle the Opening Event of your MyContextMenu [ContextMenu]

  • either by a Handles MyContextMenu.Opening hook
  • or AddHandler MyContextMenu.Opening, AddressOf MyContextMenu_Opening

    Private Sub MyContextMenu_Opening( _
        sender As Object, e As System.ComponentModel.CancelEventArgs) _
        Handles MyContextMenu.Opening ' Requires Private WithEvents MyContextMenu

        'Try
            p_SelectedPictureB = DirectCast(MyContextMenu.SourceControl, PictureBox)
            If p_SelectedPictureB.Image IsNot Nothing Then
                ViewToolStripMenuItem.Enabled = True
                Select Case True
                    Case p_SelectedPictureB Is PictureBox1:
                        p_TargetFileName = picDrawing(1)
                        ViewToolStripMenuItem.Text = "Open [" + p_TargetFileName + "]"
                    Case p_SelectedPictureB Is PictureBox2:
                        p_TargetFileName = picDrawing(2)
                        ViewToolStripMenuItem.Text = "Open [" + p_TargetFileName + "]"

                    ' ...

                    Case Else
                        ViewToolStripMenuItem.Enabled = False
                        ViewToolStripMenuItem.Text = "Open [<Wrong PBox>]"
                        p_TargetFileName = ""
                        'e.Cancel = True
                End Select
            Else
                ViewToolStripMenuItem.Enabled = False
                ViewToolStripMenuItem.Text = "Open [<No Image>]"
                p_TargetFileName = ""
                'e.Cancel = True
            End If

        'Catch CurrentException As Exception
        '    MessageBox.Show(CurrentException.Message)
        '    ViewToolStripMenuItem.Enabled = False
        '    p_TargetFileName = ""
        '    e.Cancel = True
        'End Try
        ' ^^ remove commenting if you're unsure.
    End Sub

Prefer the use of top declared variables.

If you write plain file/folder paths inside a method or function, you could loose track of it quickly, and some time later, you don't understand why your application suddenly started to crash (because the file went deleted/application uninstalled, or the folder renamed)

=> Put path to File/Folder in a global variable

However, the best move is to retrieve that path at Runtime, and ensure the existence of the File/Folder before going further...


    Private Sub ViewToolStripMenuItem_Click( _
        sender As Object, e As EventArgs) _
        Handles ViewToolStripMenuItem.Click

        Dim TargetFile As String = p_ImageFolderPath + p_TargetFileName

        If File.Exists(TargetFile) Then
            ' (p_AcroRedPath existence checked when application starts)
            Process.Start(p_AcroRedPath, TargetFile)
        Else
            MessageBox.Show("The File [" + TargetFile + "] doesn't exist.")
        End If
    End Sub

Upvotes: 0

tezzo
tezzo

Reputation: 11115

It seems that ContextMenu.SourceControl returns always Nothing in particular situations. I verified this problem on VS2010 when I put my ToolStripMenuItem inside a ToolStripDropDownMenu. So the answer posted by @Justin Ryan couldn't working.

A workaround could be manually set a variable when opening ContextMenu with its SourceControl.

Public Class Form1

    Dim ctrlSourceControl As Control

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        AddHandler Me.ContextMenuStrip1.Opening, AddressOf setSourceControl
    End Sub

    Private Sub setSourceControl(sender As Object, e As System.ComponentModel.CancelEventArgs)
        Me.ctrlSourceControl = CType(sender, ContextMenuStrip).SourceControl
    End Sub

    Private Sub Item1ToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles Item1ToolStripMenuItem.Click
        MsgBox(Me.ctrlSourceControl.Name)
    End Sub

End Class

Upvotes: 2

Justin Ryan
Justin Ryan

Reputation: 1404

From this question, Tim Lentine shows how to use the SourceControl property Of a ContextMenuStrip to determine the control which opened the context menu:

Private Sub mnuWebCopy_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles mnuWebCopy.Click

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

    MessageBox.Show(cms.SourceControl.Name)

End Sub

Upvotes: 0

Related Questions