Есть ли способ программно закрыть пункт меню в WPF - PullRequest
8 голосов
/ 23 апреля 2009

У меня есть меню в 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>

Спасибо, Jon

Ответы [ 3 ]

12 голосов
/ 23 апреля 2009

Возьми 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;
};
4 голосов
/ 07 марта 2012

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

        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}
           );
        }
2 голосов
/ 11 августа 2016

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

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