1

私は C# で電卓をプログラミングしており、それにキーボード入力を追加しようとしています。問題は、GUI のボタンをクリックすると、Enter/Return キーがそれにフォーカスされることです。Return キーが押されると、KeyDown イベント ハンドラーによって処理される代わりに、そのキーをもう一度クリックします。どうすればこれを修正できますか?

private void Window_KeyDown(object sender, KeyEventArgs e)
    {
        switch (e.Key)
        {
            case Key.NumPad1:
            case Key.D1:
                addInput('1');
                break;
            case Key.Return:
                MessageBox.Show("Enter!");
                break;
        }
    }
4

3 に答える 3

2

PreviewKeyDownフォームのイベントを処理する必要があります。次に、イベントを処理するかどうかを確認し、処理する場合は、処理後Handledにイベントのプロパティを設定trueします。

それはおそらく次のようになります。

public MainWindow()
{
    InitializeComponent();

    PreviewKeyDown += new KeyEventHandler(MainWindow_PreviewKeyDown);
}

void MainWindow_PreviewKeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Space)
    {
        Log("Intercepted space in preview");
        e.Handled = true;
    }
}

Handledに設定する必要があるのはなぜtrueですか? WPF のイベントは、「ルーティング戦略」に依存する方法で、いくつかの UI 要素でトリガーされます。イベント ハンドラーを に設定Handledするとtrue、そのイベントの可視性は他の UI 要素に制限されます。まもなく、他の UI 要素ではトリガーされなくなります。上記のソリューションの詳細については、以下の回答の残りの部分をお読みください。


WPF でイベントを適切に使用するには、理解しておく必要があることがいくつかあります。イベントは UI 要素 (テキスト ボックス、ボタンなど) に関連付けられ、イベント ハンドラーはそれらの UI 要素に接続できます。また、UI 要素はツリー構造で編成されます。各要素には、ルート UI 要素までの親要素があります。すでに述べたように、イベントは「ルーティング戦略」に応じて複数の要素でトリガーされます。ここでの複数の要素とは、イベントの対象となる要素とその親、ルート要素までを意味します。イベント ルーティング戦略は次のとおりです。

  • バブリング: イベントは、イベント ターゲット要素に対して最初に発生します。次に、その親、次にその親の親、というようにルート要素 (多くの場合、これは Window) まで起動されます。
  • トンネリング: イベントは最初にルート UI 要素に対して発生し、次に UI 要素ツリーを下ってターゲット要素へのルートに沿って発生します。
  • Direct : イベントはターゲット要素に対してのみ発生します。

ここに画像の説明を入力

これは財産とどのように関係していHandledますか?イベントがバブリングまたはトンネリング ルーティング戦略を使用している場合、Handledプロパティを使用して、UI 要素ツリーの下または上へのイベントの伝播を停止します。

KeyDownでは、イベントを としてマークしたときに、イベントの伝播が停止しなかったのはなぜHandledですか? KeyDownイベントはバブリング戦略を使用するためです。Handledこれは、に設定した Window ハンドラに到達する前に、テキスト ボックスが KeyDown イベントをすでに処理していることを意味しますtrue

そのため、PreviewKeyDownトンネリング戦略を使用するものを使用する必要があります。ウィンドウ ハンドラーはイベントをチェックし、Handled必要に応じてマークします。マークされている場合、HandledUI ツリーからイベント ターゲットまでトリガーされません。

これは、.NET フレームワークの規則として表示できます。PreviewXトンネリング戦略を使用するイベントであり、戦略を使用するXイベントの対応物ですbubbling

ルーティング イベントの詳細については、この MSDN ページにアクセスしてください。MSDN は、WPF に関する優れた情報源です。

于 2013-03-19T16:24:48.527 に答える
1

これを試して:

    private void Window_KeyDown(object sender, KeyEventArgs e)
    {
        switch (e.Key)
        {
            case Key.NumPad1:
            case Key.D1:
                addInput('1');
                MyTextBox.Focus(); // <-- NEW LINE OF CODE
                break;
            case Key.Return:
                MessageBox.Show("Enter!");
                MyTextBox.Focus(); // <-- NEW LINE OF CODE
                break;
        }
    }
于 2013-03-19T16:24:20.377 に答える
0

Focusable を false に設定します。

<Button Focusable="False" Click="Button_Click" />
于 2013-03-19T18:11:48.607 に答える