2013-04-03 10 views
16

我正在研究基于WPF并以C#编写的Windows应用商店游戏。当玩家按Esc键时,我想暂停游戏并显示菜单(继续,退出等)。Windows应用商店应用中的页面全局键盘事件

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

游戏的故事发生在一个Windows.UI.Xaml.Controls.Page并在Canvas主要由数百Shape S的,但没有一个ButtonTextBox或其他任何支持键盘交互。唯一的互动是点击或点击形状。

我需要捕捉整个页面的全局键盘事件,无论哪个元素有焦点或者是否有任何焦点等等。每当按Esc键时,事件必须触发。

我试了一下:

  • 使用事件Page.KeyDown或压倒一切的Page.OnKeyDown(KeyRoutedEventArgs e)(或KEYUP):不火,除非有一个元件,如与键盘焦点TextBox。但在我的UI中没有这样的元素。

  • 使用不可见(Opacity = 0和/或帆布下隐藏的)文本框作为一个黑客,使的KeyDown工作:只要帆布或任何形状点击/挖掘,文本框失去焦点和黑客停止工作。因此,需要更多的黑客来保持焦点,这与其他事物(如菜单按钮)紧密相关。此外,TextBox偶尔会显示Windows软件键盘,这是相当不必要的。几乎没有工作,脆弱的黑客。

  • 使用InputGestures,KeyBinding等:不适用于Windows应用商店应用。

任何想法或解决方案?

回答

21

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

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

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

似乎工作,谢谢。我明天会做更多的测试,然后接受你的答案。 –

+0

@SebastianNegraszus - 没问题,希望它的作品! – keyboardP

2

CoreWindow.GetForCurrentThread()的KeyDown不会捕获事件,如果它的重点是一些其他的网格/ web视图/文本框,所以改用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; 
      } 
     } 
    } 
}