C# = MenuItem.Click handler - Get the object the context menu belongs to?
Solution 1
Use the ContextMenu.SourceControl property, it gives you a reference to the Button instance back.
Solution 2
If you are using ContextMenuStrip and ToolStripItem, rather than ContextMenu and MenuItem, you'll need:
private void myToolStripMenuItem_Click(object sender, EventArgs e)
{
Button parent = (Button)((ContextMenuStrip)((ToolStripItem)sender).Owner).SourceControl;
...
With a regular ContextMenu and MenuItem (from trycatch's comment on Hans Passant's post):
Button parent = (Button)((ContextMenu)((MenuItem)sender).Parent).SourceControl;
Solution 3
In the above code excerpt, when you call the show method of buttonContextMenu
, you pass the button object to buttonContextMenu
when you right-click on the button.
To access the button in the OnFooClicked method simply cast the 'sender' back to a button.
public void OnFooClicked(object sender, EventArgs e)
{
((MenuItem)sender).Parent //This is the button
}
*I don't know if MenuItem is the correct cast but it should be along those lines.
trycatch
Updated on June 04, 2022Comments
-
trycatch almost 2 years
This might be incredibly simple and I'm not seeing it because it's the end of a long day, and if it is I apologize in advance.
I've got a set of Buttons that when right-clicked pop up a ContextMenu. The menu has two MenuItems, both of which have a Click handler function assigned. I'm triggering the ContextMenu to pop up on the right click of a button like so:
Overly simplified example:
public void InitiailizeButtonContextMenu() { buttonContextMenu = new ContextMenu(); MenuItem foo = new MenuItem("foo"); foo.Click += OnFooClicked; MenuItemCollection collection = new MenuItemCollection(buttonContextMenu); collection.Add(foo); } public void OnButtonMouseClick(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) // left click stuff handling if (e.Button == MouseButtons.Right) buttonContextMenu.Show((Button)sender, new Point(e.X, e.Y)); } public void OnFooClicked(object sender, EventArgs e) { // Need to get the Button the ContextMenu .Show'd on in // OnButtonMouseClick... thoughts? } ContextMenu buttonContextMenu;
I need to be able to get the Button that triggered the ContextMenu to pop up IN the Click handler for the MenuItem, or get it to it somehow. MenuItem.Click takes EventArgs, so nothing useful there. I can cast object sender back to MenuItem but I can't find anything that tells me what made it pop up. Is this possible?
-
trycatch about 13 yearsI'm away from my code now, but I'm 90% sure I tried this, and it threw an exception because sender was a MenuItem because it's a MenuItem.Click handler.
-
Kyle Uithoven about 13 yearsOops, sorry. Yea, that won't work. You should be able to reference the Parent, and that will be your button. Sorry.
-
trycatch about 13 yearsWorth noting (in case someone with this same problem comes across this question) that you have to do: Button parent = (Button)((ContextMenu)((MenuItem)sender).Parent).SourceControl; to get all the way back to the button from the MenuItem, but this works! Thanks.
-
SepehrM over 10 yearsIn case someone like me needs this for wpf, should use PlacementTarget property: Button btn = (Button)((ContextMenu)((MenuItem)sender).Parent).PlacementTarget;