Windows应用商店应用中的页面全局键盘事件

Seb*_*zus 16 c# wpf keyboard-events windows-store-apps

我正在开发一款游戏,一种基于WPF的Windows应用商店应用,用C#编写.当玩家按下Esc键时,我想暂停游戏并显示一个菜单(继续,退出等).

听起来很简单.可悲的是,事实并非如此.

游戏的故事发生在一个Windows.UI.Xaml.Controls.Page和主要由数百Shape在A S Canvas,但没有一个单一的Button,TextBox否则任何支持键盘交互.唯一的互动是点击或点击形状.

我需要在整个页面上全局捕捉键盘事件,无论焦点是什么元素,或者根本没有任何焦点等等.每当按下Esc键时,必须触发一个事件.

我尝试了什么:

  • 使用事件Page.KeyDown或覆盖Page.OnKeyDown(KeyRoutedEventArgs e)(或KeyUp):不会触发,除非有一个元素,如TextBox键盘焦点.但是在我的UI中没有这样的元素.

  • 使用不可见(Opacity = 0和/或隐藏在Canvas下)TextBox作为黑客来使KeyDown工作:只要点击/点击Canvas或任何Shape,TextBox就会失去焦点并且黑客停止工作.因此,需要更多的黑客来保持焦点,这与其他东西(例如菜单按钮)有关.此外,TextBox偶尔会显示Windows软件键盘,这是非常不需要的.一个勉强工作,脆弱的黑客.

  • 使用InputGestures,KeyBinding等:不适用于Windows应用商店的应用程序.

任何想法或解决方案?

key*_*rdP 24

尝试使用CoreWindow.KeyDown.在页面中分配处理程序,我相信它应该拦截所有keydown事件.

public MyPage()
{
    CoreWindow.GetForCurrentThread().KeyDown += MyPage_KeyDown;
}

void MyPage_KeyDown(CoreWindow sender, KeyEventArgs args)
{
    Debug.WriteLine(args.VirtualKey.ToString());
}
Run Code Online (Sandbox Code Playgroud)


ac-*_*lap 5

如果焦点位于其他网格/webView/文本框上,CoreWindow.GetForCurrentThread().KeyDown 将不会捕获事件,因此请使用AcceleratorKeyActivated事件。无论焦点在哪里,它始终会捕获事件。

public MyPage()
{
    Window.Current.CoreWindow.Dispatcher.AcceleratorKeyActivated += AcceleratorKeyActivated;
}


private void AcceleratorKeyActivated(CoreDispatcher sender, AcceleratorKeyEventArgs args)
{
    if (args.EventType.ToString().Contains("Down"))
    {
        var ctrl = Window.Current.CoreWindow.GetKeyState(VirtualKey.Control);
        if (ctrl.HasFlag(CoreVirtualKeyStates.Down))
        {
            switch (args.VirtualKey)
            {
                case VirtualKey.A:
                    Debug.WriteLine(args.VirtualKey);
                    Play_click(sender, new RoutedEventArgs());
                    break;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)