21

I want to click on a button and have it show a ContextMenuStrip right below the button. It keeps showing up in the left hand side of the screen when i try PointToScreen and top and left coordinates.

Any suggestions?

Giulio Caccin
  • 2,962
  • 6
  • 36
  • 57
leora
  • 188,729
  • 360
  • 878
  • 1,366

10 Answers10

46

I know this is an old question but I think it may help other people. Following code will display the context menu just below the button being clicked and the button will look like a dropdown button.

private void Button1_Click(object sender, EventArgs e)
{
    Button btnSender = (Button)sender;
    Point ptLowerLeft = new Point(0, btnSender.Height);
    ptLowerLeft = btnSender.PointToScreen(ptLowerLeft);           
    ctMenuStrip.Show(ptLowerLeft);
}
Jim Dagg
  • 2,044
  • 22
  • 29
A J Qarshi
  • 2,772
  • 6
  • 37
  • 53
  • this is the behavior I'm looking for in your solution! I cant figure out how to do it within protected override OnMouseClick(DataGridViewCellMouseEventArgs e)...I'm trying to position a ContextMenuStrip right below my dataGridViewCell. – Max Eisenhardt Apr 24 '13 at 18:21
  • @D.Allen : It looks like you are talking about DataGridView class in .NET and you are overriding the OnCellMouseClick event in your class inherited from DataGridView. If so then could you please describe what exactly you want to do. I think you can get the Location, X/Y coordinates from the DataGridViewCellMouseEventArgs object – A J Qarshi May 03 '13 at 10:06
  • This solution does not cover an edge case where we place the button near the task bar and then click it to show the context menu strip. Sometimes the menu strip will hide the button due to overflow, while the `expected` behavior should be flipping the menu then above the button. But there is no easy way to achieve such a flip. – Lex Li Oct 27 '14 at 13:18
  • Hi, I'm trying to sort out an issue with this. It opens my context menu on the bottom right hand corner of the mouse location, whereas I would prefer it to open on the top right. I'm trying to add parameters like this: but it doesn't seem to work – xandermonkey Oct 28 '16 at 19:40
  • `object[] args = {Control.MousePosition};` `mi.Invoke(this.notifyIcon1, args);` – xandermonkey Oct 28 '16 at 19:41
31

I figured it out:

layoutMenus.Show(Cursor.Position.X, Cursor.Position.Y);
tanascius
  • 53,078
  • 22
  • 114
  • 136
leora
  • 188,729
  • 360
  • 878
  • 1,366
  • 6
    Strictly speaking, this is not the answer to the question. This will show the context menu at the location of the pointer, not at a point right below the button. – Pete Baughman Jul 18 '12 at 21:01
  • I arrived here looking for exactly this. Thank you!! – Leo Gurdian Apr 29 '16 at 09:05
  • 3
    The ContextMenu.Show() method has a number of overloads - in your case, a good solution would be this one: It positions the context menu _relative to your button_. `layoutMenus.Show(Button1, new Point(0, Button1.Height))` – AeonOfTime Jan 06 '17 at 11:12
  • @AeonOfTime why don't you make your comment as a response? In my opinion, a very good and laconic solution. – XelaNimed Mar 31 '21 at 11:09
6

ContexMenuName under button, aligned to the right side of button (expands to below button and to the left): ContexMenuName.Show(ButtonName, new Point(ButtonName.Width - ContexMenuName.Width, ButtonName.Height)); Hope this will help sb :)

saper_2
  • 71
  • 1
  • 4
3

As far as I know the code you require was here:

// On the right of the button

ContextMenuName.Show(ButtonName.Left + ButtonName.Width + this.Left, ButtonName.Top + this.Top);

At the bottom of the button

ContextMenuName.Show(ButtonName.Left + this.Left, ButtonName.Top + ButtonName.Height + this.Top);

At the bottom right of the button

ContextMenuName.Show(ButtonName.Left + ButtonName.Width + this.Left, ButtonName.Top + ButtonName.Height + this.Top);
Kishan_KP
  • 4,488
  • 6
  • 27
  • 46
  • What is `this` here? Do you mean the form itself? The calculation does not work and the menu appears in an unexpected location. – Lex Li Oct 27 '14 at 13:13
2

There seems to be a right answer already, but I thought this might be a bit prettier:

private void button_Click(object sender, EventArgs e)
{
    Button btn = (Button)sender;
    menuStrip.Show(btn, new Point(0, 0)); // offset from the edge of your button
}
1

Make sure that when you're positioning the context menu that you pass it the correct screen coordinates. You'll need to use something like Control.PointToScreen, using the x, y, coordinates based on the position of the control in its parent.

Michael Todd
  • 16,679
  • 4
  • 49
  • 69
1

I am having toolstripDropDown and after clicking on toolstripDropDown button i wanted to show the context menu. So from above comments i modified my code in toolStripDropDown_Openining event as follows. it works fine.

void toolStripDropDownButton_DropDownOpening(object sender, EventArgs e)
    {


            ToolStripDropDownButton btnSender = (ToolStripDropDownButton)sender;
            Point ptLowerRight = new Point(btnSender.Bounds.Right, btnSender.Bounds.Bottom);
            ptLowerRight = PointToScreen(ptLowerRight);
            contextMenuStrip.Show(ptLowerRight);
    }
Sagar
  • 399
  • 4
  • 11
1
 contextMenuStrip1.Show(button1.PointToScreen(new Point(0, button1.Height)));

To show MenuStrip right under the button

Coder Tr25
  • 19
  • 5
0

The following solution can be applied for most control

contextMenuStrip1.Show(sender,sender.Location)
Grigory Zhadko
  • 1,484
  • 1
  • 19
  • 33
-1

Easy way

contextMenuStrip1.Show(Button1, Button1.PointToClient(Cursor.Position));

qursaan
  • 1
  • 2