2009-04-23 9 views
8

Tengo un menú en wpf que tiene un cuadro de entrada y un botón en él. Una vez que el usuario hace clic en el botón, necesito cerrar el menú.¿Hay alguna manera de cerrar programáticamente un elemento de menú en WPF

¿Hay alguna manera de hacerlo?

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

Gracias, Jon

Respuesta

12

controlar la MenuItem y hacer:

_menuItem.IsSubmenuOpen = false; 

manera fácil de hacerse con ella:

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

de código subyacente:

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

Eso lo hizo :) ¡Gracias! –

3

Me parece que el uso IsSubmenuOpen no elimina adecuadamente el enfoque desde el menú que contiene el MenuItem (especialmente si el menú está en una barra de herramientas - el nivel superior MenuItem queda Selected aunque el menú está cerrado"). Encuentro que el envío de un evento MouseUp a la MenuItem funciona mejor (en el botón de, o el control anidado de, Haga clic controlador de eventos):

 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

He revisado el código con .NET Reflector y Steve está en lo cierto. Configurar IsSubmenuOpen deja una variable interna llamada MenuMode en un estado intermedio. El efecto final es que el Menú todavía tiene el foco y al pasar el cursor sobre los encabezados del menú de nivel superior hará que aparezca el menú desplegable. Parece que enviar el evento MouseUp restablecerá correctamente los estados internos que mantiene el control de menú. –

2

Steve gracias por su solución. Esa es la respuesta correcta, y finalmente algo que realmente funciona además de toneladas de malas respuestas en internet. Tengo una solución más corta (y más segura) basada en tu información. Debido a que el padre directo (e.Parent) del botón no es siempre MenuItem (de la respuesta original que es StackPanel), su solución no funcionará. Así que simplemente configure la propiedad Name del MenuItem (Name = "MyMenuItem") y enganche este controlador en el Botón:

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