Page-global keyboard events in Windows Store Apps

主宰稳场 提交于 2019-11-29 07:33:57

问题


I'm working on a game, a Windows Store App based on WPF and written in C#. When the player presses the Esc key, I want to pause the game and show a menu (Continue, Quit etc.).

Sounds simple. Sadly, it's not.

The game takes place in a Windows.UI.Xaml.Controls.Page and primarily consists of hundreds of Shapes in a Canvas, but no single Button, TextBox or anything else that supports keyboard interaction. The only interaction is clicking or tapping shapes.

I need to catch keyboard events, globally for the whole page, no matter what element has the focus or if there even is any focus at all etc. Whenever the Esc key is pressed, an event has to fire.

What I tried:

  • Using the event Page.KeyDown or overriding Page.OnKeyDown(KeyRoutedEventArgs e) (or KeyUp): Does not fire, unless there is an element such as a TextBox with keyboard focus. But in my UI there is no such element.

  • Using an invisible (Opacity = 0 and/or hidden under the Canvas) TextBox as a hack to make KeyDown work: As soon as the Canvas or any Shape is clicked/tapped, the TextBox loses focus and the hack stops working. So, more hacks are needed to make it keep the focus, which screws with other things such as the menu buttons. Futhermore, the TextBox occasionally shows the Windows software keyboard, which is rather unwanted. A barely working, fragile hack.

  • Using InputGestures, KeyBinding etc.: Not available for Windows Store Apps.

Any ideas or solutions?


回答1:


Try using CoreWindow.KeyDown. Assign the handler in your page and I believe it should intercept all keydown events.

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

void MyPage_KeyDown(CoreWindow sender, KeyEventArgs args)
{
    Debug.WriteLine(args.VirtualKey.ToString());
}



回答2:


CoreWindow.GetForCurrentThread().KeyDown will not capture events if it the focus is on some other grid/webView/text box, so instead use AcceleratorKeyActivated event. Irrespective of where the focus is it will always capture the event.

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


来源:https://stackoverflow.com/questions/15792978/page-global-keyboard-events-in-windows-store-apps

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!