如何使用 WPF 中的 Alt 键切换主菜单可见性?

Posted

技术标签:

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

我希望我的 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 键触发相同的行为以保持一致性。 【参考方案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

【讨论】:

以上是关于如何使用 WPF 中的 Alt 键切换主菜单可见性?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 WPF 中的代码绑定 DataGridTextColumn 的可见性属性?

XAML 在多个选项之间切换可见性

覆盖 2 个控件并使用 WPF 切换哪一个可见

WPF菜单

如何切换 Vim 的搜索高亮可见性而不禁用它

如何检测 WPF 中的修饰键状态?