16

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

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

游戏在 a 中进行Windows.UI.Xaml.Controls.Page,主要由 a 中的数百个Shapes组成,Canvas但没有单个s或任何其他支持键盘交互的东西。唯一的交互是单击或点击形状。ButtonTextBox

我需要全局捕获整个页面的键盘事件,无论哪个元素具有焦点,甚至是否有任何焦点等。每当按下 Esc 键时,都必须触发一个事件。

我尝试了什么:

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

  • 使用不可见(Opacity = 0和/或隐藏在画布下)的文本框作为使 KeyDown 工作的黑客:只要单击/点击画布或任何形状,文本框就会失去焦点并且黑客停止工作。因此,需要更多的技巧来使其保持焦点,这与菜单按钮等其他东西有关。此外,TextBox 偶尔会显示 Windows 软件键盘,这是相当不受欢迎的。一个勉强工作,脆弱的黑客。

  • 使用InputGesturesKeyBinding:不适用于 Windows 应用商店应用程序。

有什么想法或解决方案吗?

4

2 回答 2

24

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

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

void MyPage_KeyDown(CoreWindow sender, KeyEventArgs args)
{
    Debug.WriteLine(args.VirtualKey.ToString());
}
于 2013-04-03T16:46:07.990 回答
4

CoreWindow.GetForCurrentThread().KeyDown 如果焦点位于其他网格/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;
            }
        }
    }
}
于 2016-10-08T05:52:57.880 回答