Existe uma maneira para programaticamente perto um menuitem em WPF
Pergunta
Eu tenho um menu no WPF que tem uma caixa de entrada e um botão nele. Uma vez que o usuário clica no botão que eu preciso para fechar o menu.
Existe uma maneira de fazer isso?
<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>
Obrigado, Jon
Solução
Se apossar do MenuItem
e fazer:
_menuItem.IsSubmenuOpen = false;
Fácil maneira de se apossar dela:
<Button x:Name="_button" Tag="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type MenuItem}, AncestorLevel=2}"/>
Código-behind:
_button.Click += delegate
{
(_button.Tag as MenuItem).IsSubmenuOpen = false;
};
Outras dicas
Eu acho que o uso de IsSubmenuOpen
não elimina corretamente foco a partir do menu que contém o MenuItem
(especialmente se o menu é em uma barra de ferramentas - os restos MenuItem
de nível superior Selected
embora o menu é "fechado"). Acho enviar um evento MouseUp
ao MenuItem
funciona melhor (no botão de ou controle aninhado de, clique em manipulador 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}
);
}
Steve obrigado pela sua solução. Isso é realmente resposta certa, e, finalmente, algo que realmente funciona ao lado de toneladas de respostas ruins sobre a internet. Eu tenho uma solução mais curta (e mais seguro) com base no seu anwser. Porque controladora direta (e.Parent) do botão não é sempre MenuItem (de resposta original que é StackPanel), sua solução não vai funcionar. Então, basta definir a propriedade Nome do MenuItem (Name = "MyMenuItem") e ligar este manipulador no Botão:
private void Button_Click(object sender, RoutedEventArgs e) {
MyMenuItem.RaiseEvent(new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left) {
RoutedEvent = Mouse.MouseUpEvent
});
}