ContextMenuStrip.Owner Property null Al recuperar de Nested ToolStripMenuItem

Tengo una configuración ContextMenuStrip con dos ToolStripItem s. El segundo ToolStripItem tiene dos ToolStripItem s nesteds adicionales. Yo defino esto como:

 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"; 

Luego configuro un detector de eventos para los eventos de clic de los tres ToolStripMenuItem los que deseo responder. Estos son los métodos (solo enumeré dos de los tres métodos):

 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 } } } } 

Aquí está el problema que tengo:

Mi método contextJumpTo_Click funciona perfectamente bien. Bajamos hasta donde determino de qué DataGridView salió el clic y puedo continuar. El contextJumpTo ToolStripMenuItem , sin embargo, NO es un elemento de menú nested en ContextMenuStrip .

Pero mi método para contextJumpToHeatmapStart_Click no funciona bien. Cuando llego a la línea donde determino owner.SourceControl , SourceControl es nulo y no puedo continuar. Ahora sé que este ToolStripMenuItem está nested debajo de otro en mi ContextMenuStrip , pero ¿por qué la propiedad SourceControl nula en mi ContextMenuStrip ?

¿Cómo SourceControl el SourceControl para un ToolStripMenuItem nested para un ContextMenuStrip ?

Yo creo que eso es un error.

Traté de rastrear la lista de padres de la tira de herramientas para llegar al propietario ContextStripMenu, que funcionó, pero la propiedad SourceControl siempre fue nula.

Parece que el trabajo común es establecer el control sobre la apertura del menú contextual:

 private Control menuSource; cms.Opening += cms_Opening; void cms_Opening(object sender, CancelEventArgs e) { menuSource = ((ContextMenuStrip)sender).SourceControl; } 

Entonces tu código básicamente se convierte en esto:

 DataGridView dgv = menuSource as DataGridView; if (dgv != null) { // do work }