-1

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.

Oak_3260548
  • 1,882
  • 3
  • 23
  • 41
  • Use .Parent does not make sense, delete it. – Hans Passant Nov 04 '20 at 10:12
  • Just handle the `MouseClick` event of the control, detect the right button and then call `Show` on the menu. – jmcilhinney Nov 04 '20 at 10:30
  • @HansPassant You are right with `Parent`, I just accidentally left it there, it was one of some options I tested. But it didn't resolve the issues, since when the window was moved away from top-left corner, the `ContextMenuStrip` would still appear in place, where it would be with window top-left-cornered. – Oak_3260548 Nov 04 '20 at 10:38
  • @jmcilhinney Thank you for your suggestion and while I resolved the issue in the meanwhile as per answer bellow, I wonder if you meant to call `Show()` with no parameters? I tested it and that showed the `ContextMenuStrip` in the very top-left corner. Though, I too expected that the default value would be the actual mouse-(right)-click point. – Oak_3260548 Nov 04 '20 at 10:41
  • What I meant was to call `Show` with the appropriate arguments, which you could have determined if you had bothered to read the documentation for the method and see what overloads were available. It should go without saying that you read the documentation. Why would the default be the point you clicked? There's no connection between the two. That happens inside the menu when you create a connection by setting the `ContextMenuStrip` property. Without that connection, you have to tell it where to show. That's easy to do and explained in the documentation. – jmcilhinney Nov 04 '20 at 10:51
  • Why it would take a [1,1] location on the screen? That's a nonsense, while a click point would make sense, I'd say. But it's not a big deal and yes, I might have missed something. As for docs, I actually did try some other overloads, maybe incorrectly, but I think it didn't work, because the coordinates I could provide were in a different context. – Oak_3260548 Nov 04 '20 at 13:42

1 Answers1

0

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.

Oak_3260548
  • 1,882
  • 3
  • 23
  • 41