Есть ли способ программно закрыть menuitem в WPF

У меня есть меню в wpf, которое имеет поле ввода и кнопку на нем. Как только пользователь нажимает кнопку, Мне нужно закрыть меню.

есть ли способ сделать это?

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

спасибо, Джон!--2-->

3 ответов


достали MenuItem и у:

_menuItem.IsSubmenuOpen = false;

простой способ сделать это:

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

код:

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

Я нахожу, что с помощью IsSubmenuOpen неправильно устраняет фокус из меню, содержащего MenuItem (особенно если меню в Меню верхнего уровня MenuItem остается Selected даже если меню "закрыто"). Я нахожу отправку MouseUp событие MenuItem работает лучше (в кнопке или вложенном элементе управления нажмите обработчик событий):

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

Стив спасибо за ваше решение. Это на самом деле правильный ответ, и, наконец, то, что действительно работает рядом с тоннами плохих ответов через интернет. У меня есть более короткое (и более безопасное) решение на основе вашего anwser. Потому что прямой родитель (e.Родитель) кнопки не всегда MenuItem (из исходного ответа, который является StackPanel), ваше решение не будет работать. Поэтому просто установите свойство Name меню (Name= "MyMenuItem") и закрепите этот обработчик на кнопке:

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