繁体   English   中英

WPF 在键盘导航模式下显示菜单

[英]WPF Show Menu in Keyboard Navigation Mode

背景故事又名我的配置

像许多人一样,我有一个应用程序,它有一个停靠在顶部的菜单。 我希望在按下alt键之前隐藏此菜单,然后我可以使用键盘或通过单击菜单项来导航此菜单。

在我的ViewModel,我做了一个叫布尔属性ShowMenu ,一个ICommand所谓ShowMenuCommand操作为一个触发器ShowMenu ,并着手线的事情了数据绑定。 你可以在这里看到:

ShowMenuCommand = new RelayCommand(
    _ => ShowMenu = !ShowMenu);

菜单设置如下:

<Menu Name="MainMenu" DockPanel.Dock="Top"
    Visibility="{Binding ShowMenu, Converter={StaticResource BoolToVis}}"
    LostFocus="MainMenu_OnLostFocus">

我还为触发ShowMenuCommand左右 alt 配置了键绑定。

<Window.InputBindings>
    <KeyBinding Key="F1" Command="{Binding AboutCommand}" />
    <KeyBinding Key="LeftAlt" Modifiers="Alt" Command="{Binding ShowMenuCommand}" />
    <KeyBinding Key="RightAlt" Modifiers="Alt" Command="{Binding ShowMenuCommand}" />
</Window.InputBindings>

这完全按照我的配置工作:菜单通常是隐藏的,但是当我按下alt它会出现并允许我导航菜单项,直到我单击离开或我选择一个项目并且它失去焦点, LostFocus处理程序设置ShowMenu为假。

问题

这样做后,我似乎失去了进入键盘导航模式的能力。 对于那些不知道我的意思的人,通常当您在 gui 应用程序中按alt时,某些字符会变成下划线,您可以按键盘上的这些字符来导航 UI。 我不知道它的正式名称,因此任何可以提供实际名称的人都会获得奖励积分。

达到此目的的来源

按下ALT键时如何使WPF菜单栏可见

WPF 中的 LeftAlt 键绑定

现在怎么办?

我一直在搜索高低,通过键盘类和UIElement爬行,希望能找到解决这个问题的方法,我想出了几个可能的解决方案。 也就是说,我求助于 StackOverflow 的原因是因为我不知道如何以这样一种方式来定位我的谷歌搜索,以便我找到我正在寻找的东西。

我提出的解决方案如下:

  1. 除了修改可见性之外,还修改ShowMenuCommand以切换键盘导航模式。
  2. 删除我的键绑定并将菜单的可见性连接到是否启用了键盘导航模式。
    • 我以为我会在UIElement#IsInputMethodEnabled ,但情况似乎并非如此。 也就是说,我不知道你选择什么元素是否重要,我不记得我是否尝试过定位菜单或窗口。

如果其他人有任何第三个想法或可能知道我遗漏的东西,请告诉我。 隐藏菜单栏直到你用alt取消隐藏它应该是非常简单的设置,所以如果我遗漏了什么我不会感到惊讶。

附加上下文

如果您想查看围绕所提供代码段的任何代码,可以在 GitHub 上查看项目源代码

因此,经过一些额外的研究和@Vlad 的帮助,最终的解决方案如下:

  1. 菜单可见性绑定到视图控制器中的ShowMenu属性。
  2. Window 有 KeyUp 事件处理程序,它监视 alt 键。
private void MainWindow_OnKeyUp(object sender, KeyEventArgs e)
{
    if (e.Key == Key.System && (e.SystemKey == Key.LeftAlt || e.SystemKey == Key.RightAlt))
    {
        MainWindowViewModel mwvm = (MainWindowViewModel)DataContext;

        mwvm.ShowMenu = !mwvm.ShowMenu;
    }
}

这是有效的,除了在选择项目后菜单将保持可见。 我尝试创建一个项目模板来一次性完成所有工作,但它不想触发。

  1. 处理相关菜单项上的 Click 事件,跳过那些只是类别的事件。

唯一没有注意的是当用户点击菜单时。 我尝试将 LostFocus 事件附加到菜单,但是当菜单打开时会触发此事件,这可能是因为焦点从菜单本身转移到 ContextMenu 提供程序或实际处理绘制打开菜单的任何内容上。

我需要做更多的研究和一些代码清理,但上述解决方案的工作相对还好。

编辑:我会在几天内不选择这个答案,以防其他人有任何其他想法。

编辑 2:我找到了一个供我使用的解决方案。 因为我在这个菜单上只有一个顶级菜单项,所以我挂钩了 MenuItem 的SubmenuClosed事件。 当发生这种情况时(因为用户选择了一个选项或他们点击离开),它会通过将ShowMenu设置为 false 来隐藏菜单。

这可能不是最优雅的解决方案,但它很实用。 稍后我会考虑清理它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM