2009-04-23 11 views
8

Ho un menu in wpf che ha una casella di input e un pulsante su di esso. Una volta che l'utente fa clic sul pulsante, ho bisogno di chiudere il menu.C'è un modo per chiudere in modo programmatico un menu in WPF

C'è un modo per farlo?

<Menu x:Name="MainMenu"> 
     <MenuItem Header="Main"> 
      <MenuItem Header="SubMenu" x:Name="SubMenu"> 
       <StackPanel Orientation="Horizontal"> 
        <TextBox Width="50" x:Name="TextBox" /> 
        <Button Content="Click Me and Close" x:Name="Button" IsDefault="True"/> 
       </StackPanel> 
      </MenuItem> 
     </MenuItem> 

Grazie, Jon

risposta

12

entrare in possesso del MenuItem e fare:

_menuItem.IsSubmenuOpen = false; 

Un modo semplice per entrare in possesso di esso:

<Button x:Name="_button" Tag="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type MenuItem}, AncestorLevel=2}"/> 

Codice-behind:

_button.Click += delegate 
{ 
    (_button.Tag as MenuItem).IsSubmenuOpen = false; 
}; 
+1

Che ha fatto :) Grazie! –

3

Trovo che usando IsSubmenuOpen non elimina correttamente attenzione dal menu contenente il MenuItem (soprattutto se il menu è in una barra degli strumenti - il primo livello MenuItem rimane Selected anche se il menu è chiuso"). Trovo l'invio di un evento MouseUp al MenuItem funziona meglio (nel tasto del, o di controllo nested di, Cliccate gestore di eventi):

 private void button_Click(object sender, RoutedEventArgs e) { 
      Button b = sender as Button; 

      if (b == null || !(b.Parent is MenuItem)) 
       return; 

      MenuItem mi = b.Parent as MenuItem; 

      mi.RaiseEvent(
       new MouseButtonEventArgs(
       Mouse.PrimaryDevice, 0, MouseButton.Left 
      ) 
       {RoutedEvent=Mouse.MouseUpEvent} 
      ); 
     } 
+1

Ho passato il codice con .NET Reflector e Steve è corretto. L'impostazione di IsSubmenuOpen lascia una variabile interna denominata MenuMode in uno stato intermedio. L'effetto finale è che il Menu ha ancora lo stato attivo e passando con il mouse sopra le intestazioni del menu di livello superiore verrà visualizzato il menu a discesa. Sembra che l'invio dell'evento MouseUp ripristinerà correttamente gli stati interni gestiti dal controllo Menu. –

2

Steve, grazie per la vostra soluzione. Questa è in realtà una risposta giusta, e infine qualcosa che funziona davvero a parte tonnellate di cattive risposte su Internet. Ho una soluzione più breve (e più sicura) basata sul tuo anser. Poiché il padre diretto (e.Parent) del pulsante non è sempre MenuItem (dalla risposta originale che è StackPanel), la soluzione non funzionerà. Quindi, solo impostare la proprietà Name del MenuItem (Name = "MyMenuItem") e agganciare questo gestore sul pulsante:

private void Button_Click(object sender, RoutedEventArgs e) { 
     MyMenuItem.RaiseEvent(new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left) { 
      RoutedEvent = Mouse.MouseUpEvent 
     }); 
    } 
Problemi correlati