2009-04-23 2 views
8

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

Спасибо, Jon

ответ

12

разжиться 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; 
}; 
+1

Это сделало это :) Спасибо! –

3

Я считаю, что использование IsSubmenuOpen не должным образом устранить фокус из меню, содержащего MenuItem (особенно если меню находится в ToolBar - верхний уровень 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} 
      ); 
     } 
+1

Я просмотрел код с помощью .NET Reflector и Steve. Установка IsSubmenuOpen оставляет внутреннюю переменную, называемую MenuMode, в промежуточном состоянии. Конечный эффект заключается в том, что в меню все еще есть фокус и наведение над верхними заголовками меню верхнего уровня приведет к появлению раскрывающегося списка. Похоже, что отправка события MouseUp должным образом приведет к сбросу внутренних состояний, поддерживаемых элементом управления меню. –

2

Steve спасибо за ваше решение. Это на самом деле правильный ответ, и, наконец, что-то, что действительно работает рядом с множеством плохих ответов через Интернет. У меня есть более короткое (и более безопасное) решение, основанное на вашем anwser. Поскольку прямой родительский элемент (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 
     }); 
    } 
Смежные вопросы