【问题标题】:Is there a way to programatically close a menuitem in WPF有没有办法以编程方式关闭 WPF 中的菜单项
【发布时间】:2009-04-23 14:52:09
【问题描述】:

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

谢谢, 乔恩

【问题讨论】:

    标签: wpf menu menuitem


    【解决方案1】:

    获取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;
    };
    

    【讨论】:

      【解决方案2】:

      我发现使用IsSubmenuOpen 并不能正确消除包含MenuItem 的菜单的焦点(尤其是如果菜单位于工具栏中 - 顶级MenuItem 仍然是Selected,即使菜单是“关闭”)。我发现向MenuItem 发送MouseUp 事件效果更好(在按钮或嵌套控件的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}
                 );
              }
      

      【讨论】:

      • 我已经使用 .NET Reflector 浏览了代码,Steve 是正确的。设置 IsSubmenuOpen 会使名为 MenuMode 的内部变量处于中间状态。最终效果是菜单仍然具有焦点,并且将鼠标悬停在顶级菜单标题上将导致下拉菜单出现。似乎发送 MouseUp 事件将正确重置 Menu 控件维护的内部状态。
      【解决方案3】:

      史蒂夫感谢您的解决方案。这实际上是正确的答案,最后是除了互联网上大量错误答案之外真正有效的东西。根据您的 anwser,我有一个更短(更安全)的解决方案。因为按钮的直接父级(e.Parent)并不总是 MenuItem(来自 StackPanel 的原始答案),所以您的解决方案将不起作用。因此,只需设置 MenuItem 的 Name 属性 (Name="MyMenuItem") 并将此处理程序挂钩到 Button:

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

      【讨论】:

        猜你喜欢
        • 2015-07-13
        • 1970-01-01
        • 2012-05-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-29
        • 1970-01-01
        相关资源
        最近更新 更多