2012-08-23 2 views
8

Ho un setup ContextMenuStrip con due ToolStripItem s. Il secondo ToolStripItem ha due ulteriori nidificati ToolStripItem s. Mi definisco questo come:Proprietà ContextMenuStrip.Owner null durante il recupero da 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"; 

Ho quindi impostare un listener di eventi per gli eventi click dei tre ToolStripMenuItem s che voglio rispondere. Questi sono i metodi (ho elencato solo due dei tre metodi):

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

Ecco il problema che ho:

Il mio metodo contextJumpTo_Click funziona perfettamente bene. Arriviamo fino a dove determino quale sia il DataGridView da cui proviene il clic e posso procedere. Lo contextJumpToToolStripMenuItem è, tuttavia, NON una voce di menu nidificata su ContextMenuStrip.

Ma il mio metodo per contextJumpToHeatmapStart_Click non funziona correttamente. Quando arrivo alla riga dove determino lo owner.SourceControl, lo SourceControl è nullo e non posso procedere. Ora so che questo ToolStripMenuItem è annidato sotto un altro nel mio ContextMenuStrip, ma perché la proprietà SourceControl è nettamente nulla sul mio ContextMenuStrip?

Come ottengo il SourceControl per un nidificato ToolStripMenuItem per un ContextMenuStrip?

risposta

8

Credo che sia un bug.

Ho tentato di eseguire la scansione dell'elenco di parentesi di toolstrip per raggiungere il proprietario ContextStripMenu, che ha funzionato, ma la proprietà SourceControl era sempre nullo.

Sembra che il lavoro comune intorno è per impostare il controllo sull'apertura del menu contestuale:

private Control menuSource; 

cms.Opening += cms_Opening; 

void cms_Opening(object sender, CancelEventArgs e) { 
    menuSource = ((ContextMenuStrip)sender).SourceControl; 
} 

Poi il codice si trasforma sostanzialmente in questo:

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

ho stabilito sulla stessa conclusione. Un po 'sconvolgente dover creare una proprietà per qualcosa in cui tale proprietà esiste già. Ma non molto posso fare. –

+0

Arrivò anche a questa conclusione poco prima di vedere questa risposta ... ma a posteriori penso che sia comunque meglio farlo in questo modo comunque. – BVernon

+0

Anche io ottengo null. –