Search code examples
vb.netpointcontextmenustrip

ContextMenuStrip Location Point


How to open the ContextMenuStrip programmatically at the cursor on right mouse button down/clicked over PictureBox?


I need to open ContextMenuStrip only in some areas of an Image (Schedule) in a PictureBox, so I disconnected the PictureBox.ContextMenuStrip property from the ContextMenuStrip1 and I'm firing it manually. That means I need to provide a point, which appears to be surprisingly challanging.

My question is similar to "How to get location of ContextMenuStrip", but I need to account for both vertical and horizontal scrolling, which it doesn't (unless I messed something).

So when I'm trying something like this (in PictureBoxPlan.MouseDown):

Dim rpt As Point = Me.PointToClient(PictureBoxPlan.Parent.PointToScreen(e.Location))

...it has a fundamental flaw, because the e.Location is in context of Image, regardless how it is scrolled within the PictureBox. I tried to Form.MouseDown event, but it's not fired, when [right] clicked on a PictureBox.

Just for confirmation, I still need the point in PictureBox context to analyze whether the ContextMenuStrip should be shown or not and to lookup associated ID.

I am now trying to use some constants (may not work if windows "font size" is set to other than 100%) together with scroll bars values, which is not optimal at all.


Solution

  • OK, I found what is breaking the logic in the ContextMenuStrip.Show(Point) documentation:

    Show(Point)   
    Positions the `ToolStripDropDown` relative to the specified screen location.
    

    So the ContextMenuStrip, to my surprise, takes the screen coordinates, not the Form ones. I then just removed PointToClient and everything works as a charm, regardless of window position on the screen or scrollbars position of the Image container:

    Dim rpt As Point = PictureBoxPlan.PointToScreen(New Point(e.Location.X, e.Location.Y))
    

    No need to take into account PanelPlan.VerticalScroll.Value or PanelPlan.HorizontalScroll.Value.