2012-08-23 7 views
8

Tengo una configuración de ContextMenuStrip con dos ToolStripItem s. El segundo ToolStripItem tiene dos anidados adicionales ToolStripItem s. Me defino como este:ContextMenuStrip.Owner Propiedad null Al recuperar de Nested ToolStripMenuItem

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 a continuación, configurar un detector de eventos para los eventos de clic de los tres ToolStripMenuItem s que quiero responder. Aquí están los métodos (que sólo enumerado 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í es el problema que tengo:

Mi método contextJumpTo_Click funciona perfectamente bien. Bajamos hasta donde determiné de qué DataGridView salió el clic y puedo continuar. El contextJumpToToolStripMenuItem no es, sin embargo, un elemento de menú anidado en el ContextMenuStrip.

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

¿Cómo obtengo el SourceControl para un ToolStripMenuItem anidado para un ContextMenuStrip?

Respuesta

8

Creo que es un error.

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

Parece que el trabajo común en torno a 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; 
} 

A continuación, el código básicamente se convierte en esto:

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

me he instalado en el misma conclusión. Un poco molesto tener que crear una propiedad para algo donde esa propiedad ya existe. Pero no hay mucho que pueda hacer. –

+0

También llegó a esta conclusión justo antes de ver esta respuesta ... pero en retrospectiva, creo que en realidad es mejor hacerlo de esta manera de todos modos. – BVernon

+0

Obtengo nulo de esta manera también. –