How to get the referece to ContextMenuStrip from its underlying sub menuitem which is a ToolStripMenuItem of a ToolStripDropDownMenu which is a Dropdown of a ToolstripMenuItem of this ContextMenuStrip?
the problem lies in the ToolStripDropDownMenu class,where can't find a property refer to upperlevel objects such as its assciated ToolStripMenuItem.Its Parent,Container properties and GetContainerControl() method all return null.
My purpose is to know the SourceControl of the ContextMenuStrip when any of its underlying menu items are clicked.
You need a backward loop to get the first OwnerItem
property of a given ToolStripItem
(or one of the derived classes) in a branch then you can get the main ToolStrip
(which can be a ToolStrip
, MenuStrip
, StatusStrip
, or ContextMenuStrip
control) through the ToolStripItem.Owner
property.
Consider the following extension methods:
public static class ToolStripExtensions
{
public static ToolStrip GetMainToolStrip(this ToolStripItem tsi)
{
if (tsi == null) return null;
if (tsi.OwnerItem == null) return tsi.Owner;
var oi = tsi.OwnerItem;
while (oi.OwnerItem != null) oi = oi.OwnerItem;
return oi.Owner;
}
public static ToolStrip GetMainToolStrip(this ToolStrip ts)
{
ToolStrip res = ts;
var m = ts as ToolStripDropDownMenu;
if (m?.OwnerItem != null)
res = GetMainToolStrip(m.OwnerItem);
return res;
}
}
Here's an example that shows how to get the ContextMenuStrip.SourceControl
in the ItemClicked
event:
private void cmnu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
if (e.ClickedItem.GetMainToolStrip() is ContextMenuStrip cmnu)
Console.WriteLine(cmnu.SourceControl.Name);
}