我正在开发一款游戏,一款基于WPF的Windows应用商店应用,用C#编写。当玩家按下Esc键时,我想暂停游戏并显示一个菜单(继续,退出等)。
听起来很简单。可悲的是,事实并非如此。
游戏以Windows.UI.Xaml.Controls.Page
进行,主要包含Shape
中的数百Canvas
个,但没有Button
,TextBox
或任何内容否则支持键盘交互。唯一的互动是点击或点击形状。
我需要为整个页面全局捕捉键盘事件,无论焦点是什么元素,或者根本没有任何焦点等等。每当按下Esc键时,必须触发一个事件。
我尝试了什么:
使用事件Page.KeyDown
或覆盖Page.OnKeyDown(KeyRoutedEventArgs e)
(或KeyUp):除非存在具有键盘焦点的TextBox
等元素,否则不会触发。但是在我的UI中没有这样的元素。
使用Canvas下的不可见(Opacity = 0
和/或隐藏)TextBox作为黑客来使KeyDown工作:只要点击/点击Canvas或任何Shape,TextBox就会失去焦点,黑客停止工作。因此,需要更多的黑客来保持焦点,这与其他东西(例如菜单按钮)有关。此外,TextBox偶尔会显示Windows软件键盘,这是非常不需要的。一个勉强工作,脆弱的黑客。
使用InputGestures
,KeyBinding
等:不适用于Windows应用商店应用。
任何想法或解决方案?
答案 0 :(得分:24)
尝试使用CoreWindow.KeyDown。在页面中分配处理程序,我相信它应该拦截所有keydown事件。
public MyPage()
{
CoreWindow.GetForCurrentThread().KeyDown += MyPage_KeyDown;
}
void MyPage_KeyDown(CoreWindow sender, KeyEventArgs args)
{
Debug.WriteLine(args.VirtualKey.ToString());
}
答案 1 :(得分:4)
CoreWindow.GetForCurrentThread()。如果焦点位于某个其他网格/ webView /文本框上,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;
}
}
}
}