【问题标题】:How can I toggle the main menu visibility using the Alt key in WPF?如何使用 WPF 中的 Alt 键切换主菜单可见性?
【发布时间】:2026-01-26 01:30:01
【问题描述】:

我希望我的 WPF 应用程序中的主菜单的行为类似于 IE8 中的主菜单:

  • 应用启动时不可见
  • 按下并释放 Alt 使其可见
  • 再次按下并释放 Alt 使其再次不可见
  • 重复直到无聊

我该怎么做?必须是代码吗?

添加以响应提交的答案,因为我仍然遇到问题:

我的 Shell 代码隐藏现在如下所示:

public partial class Shell : Window
{
    public static readonly DependencyProperty IsMainMenuVisibleProperty;

    static Shell()
    {
        FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata();
        metadata.DefaultValue = false;

        IsMainMenuVisibleProperty = DependencyProperty.Register(
            "IsMainMenuVisible", typeof(bool), typeof(Shell), metadata);
    }

    public Shell()
    {
        InitializeComponent();

        this.PreviewKeyUp += new KeyEventHandler(Shell_PreviewKeyUp);
    }

    void Shell_PreviewKeyUp(object sender, KeyEventArgs e)
    {
        if (e.SystemKey == Key.LeftAlt || e.SystemKey == Key.RightAlt)
        {
            if (IsMainMenuVisible == true)
                IsMainMenuVisible = false;
            else
                IsMainMenuVisible = true;
        }
    }

    public bool IsMainMenuVisible
    {
        get { return (bool)GetValue(IsMainMenuVisibleProperty); }
        set { SetValue(IsMainMenuVisibleProperty, value); }
    }
}

【问题讨论】:

  • 你想模仿 Internet Explorer...?
  • 我尽量让我的应用程序与用户的期望保持一致,所以是的。 :-)
  • 也可以考虑 F10 键触发相同的行为以保持一致性。

标签: wpf menu keyboard-shortcuts toggle visibility


【解决方案1】:

我会尝试处理您窗口上的PreviewKeyDown 事件。我不确定按下 Alt 是否会触发此事件,但如果确实如此,那么我会切换一个绑定到窗口主菜单可见性的 bool

如果PreviewKeyDown 不起作用,我不确定还能尝试什么。您可以查看发送到您窗口的实际 Windows 消息,但这可能很快就会变得混乱。

【讨论】:

  • 感谢您的建议。我同意 Phil Price 对 PreviewKeyUp 的建议,因为这更接近 IE,但在其他方面听起来可行。
【解决方案2】:

您可以在窗口上使用PreviewKeyDown 事件。要检测 Alt 键,您需要检查 KeyEventArgsSystemKey 属性,而不是通常用于大多数其他键的 Key 属性。

您可以使用此事件来设置 bool 值,该值已在 Windows 代码中声明为 DependencyProperty

然后可以使用BooleanToVisibilityConverter 将菜单的Visibility 属性绑定到此属性。

<Menu 
    Visibility={Binding Path=IsMenuVisibile, 
        RelativeSource={RelativeSource AncestorType=Window},
        Converter={StaticResource BooleanToVisibilityConverter}}
    />

【讨论】:

  • 我无法正常工作。我已经用我的 DependencyProperty 的代码隐藏更新了原始问题。这是我第一次声明我自己的所以...我已将您的绑定添加到 Shell.xaml 中的菜单,我得到的错误是:System.Windows.Data 错误:39:BindingExpression 路径错误:'在 'object' ''Shell' (Name='')' 上找不到 IsMenuVisibile' 属性。绑定表达式:路径=IsMenuVisibile;数据项='外壳'(名称='');目标元素是“菜单”(名称=“uxMainMenu”);目标属性是“可见性”(类型“可见性”)。有什么想法吗?
  • 这是您在找不到属性时得到的标准绑定错误。要修复它,您需要在绑定中将 IsMenuVisible 替换为 IsMainMenuVisible。
  • 哦,我真是个白痴!我会登录并整理一下。谢谢。谢谢你没有指出我有多厚。 :-)
  • 就是这样。非常感谢。我不仅实现了(多亏了你)Alt 键功能和我的第一个 DependencyProperty,而且我今天还画了两个天花板:我想我现在就可以了,虽然我领先。 :-)
【解决方案3】:

最好使用GetKeyboardStateVK_MENU 来处理左右 Alt,以模仿 IE / Windows Explorer (Vista+) 的行为,您需要跟踪以前聚焦的元素来存储焦点,当聚焦的元素在你的主菜单中时按下VK_MENU。您还想在PreviewKeyUp 上进行这项工作(而不是停机)。

【讨论】:

  • 谢谢。在mo,我什至无法掌握基础知识,所以我会暂时离开WM!
【解决方案4】:

我自己也遇到了这个问题。我尝试挂钩PreviewKeyDown 事件,但发现它不可靠。相反,我找到了 InputManager 类,您可以在其中从托管代码挂钩到 EnterMenuMode。管理器公开了两个事件,用于进入和退出。诀窍是不要折叠菜单,而是在隐藏菜单时将其容器高度设置为零。要显示它,只需清除本地值,它将采用以前的高度。

来自我的TopMenu 用户控件:

public TopMenu()
{
    InitializeComponent();
    InputManager.Current.EnterMenuMode += OnEnterMenuMode;
    InputManager.Current.LeaveMenuMode += OnLeaveMenuMode;
    Height = 0;
}

private void OnLeaveMenuMode(object sender, System.EventArgs e)
{
    Height = 0;
}

private void OnEnterMenuMode(object sender, System.EventArgs e)
{
    ClearValue(HeightProperty);
}

【讨论】:

    【解决方案5】:

    查看我对以下主题的回答: How to make WPF MenuBar visibile when ALT-key is pressed?

    我在这里描述了如何使用 InputManager 类(来自命名空间 System.Windows.Input)解决您的问题。

    您可以注册类事件EnterMenuModeLeaveMenuMode

    【讨论】: