ContextMenuStrip.Owner Property null When Retrieving From Nested ToolStripMenuItem
I have a ContextMenuStrip
setup with two ToolStripItem
s. The second ToolStripItem
has two additional nested ToolStripItem
s. I define this as:
ContextMenuStrip cms = new ContextMenuStrip();
ToolStripMenuItem contextJumpTo = new ToolStripMenuItem();
ToolStripMenuItem contextJumpToHeatmap = new ToolStripMenuItem();
ToolStripMenuItem contextJumpToHeatmapStart = new ToolStripMenuItem();
ToolStripMenuItem contextJumpToHeatmapLast = new ToolStripMenuItem();
cms.Items.AddRange(new ToolStripItem[] { contextJumpTo,
contextJumpToHeatmap});
cms.Size = new System.Drawing.Size(176, 148);
contextJumpTo.Size = new System.Drawing.Size(175, 22);
contextJumpTo.Text = "Jump To (No Heatmapping)";
contextJumpToHeatmap.Size = new System.Drawing.Size(175, 22);
contextJumpToHeatmap.Text = "Jump To (With Heatmapping)";
contextJumpToHeatmap.DropDownItems.AddRange(new ToolStripItem[] { contextJumpToHeatmapStart,
contextJumpToHeatmapLast });
contextJumpToHeatmapStart.Size = new System.Drawing.Size(165, 22);
contextJumpToHeatmapStart.Text = "From Start of File";
contextJumpToHeatmapLast.Size = new System.Drawing.Size(165, 22);
contextJumpToHeatmapLast.Text = "From Last Data Point";
I then setup an event listener for the click events of the three ToolStripMenuItem
s that I want to respond to. Here are the methods (I only listed two of the three methods):
void contextJumpTo_Click(object sender, EventArgs e)
{
// Try to cast the sender to a ToolStripItem
ToolStripMenuItem menuItem = sender as ToolStripMenuItem;
if (menuItem != null)
{
// Retrieve the ContextMenuStrip that owns this ToolStripItem
ContextMenuStrip owner = menuItem.Owner as ContextMenuStrip;
if (owner != null)
{
// Get the control that is displaying this context menu
DataGridView dgv = owner.SourceControl as DataGridView;
if (dgv != null)
// DO WORK
}
}
}
void contextJumpToHeatmapStart_Click(object sender, EventArgs e)
{
// Try to cast the sender to a ToolStripItem
ToolStripMenuItem menuItem = sender as ToolStripMenuItem;
if (menuItem != null)
{
// Retrieve the ToolStripItem that owns this ToolStripItem
ToolStripMenuItem ownerItem = menuItem.OwnerItem as ToolStripMenuItem;
if (ownerItem != null)
{
// Retrieve the ContextMenuStrip that owns this ToolStripItem
ContextMenuStrip owner = ownerItem.Owner as ContextMenuStrip;
if (owner != null)
{
// Get the control that is displaying this context menu
DataGridView dgv = owner.SourceControl as DataGridView;
if (dgv != null)
// DO WORK
}
}
}
}
Here is the issue I have:
My contextJumpTo_Click
method works perfectly fine. We get all the way down to where I determine which DataGridView
the click came from and I can proceed. The contextJumpTo
ToolStripMenuItem
is, however, NOT a nested menu item on the ContextMenuStrip
.
But my method for contextJumpToHeatmapStart_Click
does not work right. When I get down to the line where I determine owner.SourceControl
, the SourceControl
is null and I cannot proceed. Now I know that this ToolStripMenuItem
is nested under another one in my ContextMenuStrip
, but why is the SourceControl
property suddently null on my ContextMenuStrip
?
How do I obtain the SourceControl
for a nested ToolStripMenuItem
for a ContextMenuStrip
?
I believe that's a bug.
I tried to crawl up the list of toolstrip parents to get to the ContextStripMenu owner, which worked, but the SourceControl property was always null.
It looks like the common work around is to set the control on the opening of the context menu:
private Control menuSource;
cms.Opening += cms_Opening;
void cms_Opening(object sender, CancelEventArgs e) {
menuSource = ((ContextMenuStrip)sender).SourceControl;
}
Then your code basically turns into this:
DataGridView dgv = menuSource as DataGridView;
if (dgv != null) {
// do work
}