16

私は、WPF に基づいて C# で記述された Windows ストア アプリであるゲームに取り組んでいます。プレイヤーが Esc キーを押したときに、ゲームを一時停止してメニュー (続行、終了など) を表示したい。

シンプルに聞こえます。悲しいことに、そうではありません。

ゲームは で行われ、主に内Windows.UI.Xaml.Controls.Pageの数百の で構成されますが、キーボード操作をサポートする単一のやその他のものはありません。唯一の操作は、図形をクリックまたはタップすることです。ShapeCanvasButtonTextBox

どの要素にフォーカスがあるか、またはフォーカスがあるかどうかなどに関係なく、ページ全体でグローバルにキーボード イベントをキャッチする必要があります。Esc キーが押されるたびに、イベントが発生する必要があります。

私が試したこと:

  • イベントPage.KeyDownまたはオーバーライドPage.OnKeyDown(KeyRoutedEventArgs e)(または KeyUp) の使用:TextBoxキーボード フォーカスのある などの要素がない限り、発生しません。しかし、私の UI にはそのような要素はありません。

  • 非表示(Opacity = 0および/またはキャンバスの下に非表示) の TextBox をハックとして使用して KeyDown を機能させる: キャンバスまたは任意のシェイプをクリック/タップするとすぐに、TextBox はフォーカスを失い、ハックは機能しなくなります。そのため、フォーカスを維持するには、さらにハックが必要です。これにより、メニュー ボタンなどの他の要素がねじ込まれます。さらに、TextBox に Windows ソフトウェア キーボードが表示されることがありますが、これはかなり望ましくありません。ほとんど機能しない脆弱なハック。

  • InputGesturesなどの使用KeyBinding: Windows ストア アプリでは使用できません。

アイデアや解決策はありますか?

4

2 に答える 2

24

CoreWindow.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

フォーカスが他のグリッド/webView/テキスト ボックスにある場合、CoreWindow.GetForCurrentThread().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;
            }
        }
    }
}
于 2016-10-08T05:52:57.880 に答える