Вопрос по wpf, windows-store-apps, c#, keyboard-events – Глобальные события клавиатуры в приложениях Магазина Windows

16

Я работаю над игрой, Windows Store App, основанной на WPF и написанной на C #. Когда игрок нажимает клавишу Esc, я хочу приостановить игру и показать меню (Продолжить, Выйти и т. Д.).

Звучит просто. К сожалению, это не так.

Действие игры происходит вWindows.UI.Xaml.Controls.Page и в основном состоит из сотенShapeвCanvas, но ни одногоButton, TextBox или что-нибудь еще, что поддерживает взаимодействие с клавиатурой. Единственное взаимодействие - нажатие или постукивание по фигурам.

Мне нужно отлавливать события клавиатуры, глобально для всей страницы, независимо от того, какой элемент имеет фокус или есть ли вообще какой-либо фокус и т. Д. При каждом нажатии клавиши Esc событие должно срабатывать.

Что я пробовал:

Использование событияPage.KeyDown или переопределениеPage.OnKeyDown(KeyRoutedEventArgs e) (или KeyUp): не срабатывает, если нет элемента, такого какTextBox с фокусом клавиатуры. Но в моем пользовательском интерфейсе такого элемента нет.

Использование невидимого (Opacity = 0 и / или скрытый под Canvas) TextBox как хакер для работы KeyDown: как только Canvas или любая Shape нажата / нажата, TextBox теряет фокус и хак перестает работать. Таким образом, требуется больше хаков, чтобы держать его в фокусе, что связано с другими вещами, такими как кнопки меню. Кроме того, TextBox иногда показывает программную клавиатуру Windows, что довольно нежелательно. Едва работающий, хрупкий взломать.

С помощьюInputGestures, KeyBinding и т.д .: Недоступно для приложений Магазина Windows.

Есть идеи или решения?

Ваш Ответ

2   ответа
24

Попробуйте использоватьCoreWindow.KeyDown, Назначьте обработчик на своей странице, и я считаю, что он должен перехватывать все события нажатия клавиш.

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

void MyPage_KeyDown(CoreWindow sender, KeyEventArgs args)
{
    Debug.WriteLine(args.VirtualKey.ToString());
}
@keyboardP ты спас мой день !! Нет слов, чтобы поблагодарить вас ... :-) hellodear
@SebastianNegraszus - Нет проблем, надеюсь, это работает! keyboardP
Кажется, работает, спасибо. Завтра я сделаю еще тестирование, а затем приму ваш ответ. Sebastian Negraszus
4

я, если фокус находится на каком-то другом сетке / webView / текстовом поле, поэтому вместо этого используйте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;
            }
        }
    }
}

Похожие вопросы