web-dev-qa-db-ja.com

フォーム上のフォーカスされたコントロールに関係なく、Keys.F1をキャプチャするにはどうすればよいですか?

KeyDownイベントを使用し、if (e.KeyCode == Keys.F1)のようないくつかの単純なコードを使用してF1がフォームで押されましたが、フォームにテキストボックスがある場合、またはフォームにDock Fillが含まれているスプレッドシートがある場合は、上記のコード役に立たなくなり、何もしません。しかし、ユーザーがこのフォームでF1を押したときに何かしたいのですが。では、フォーム全体でF1のような特定のkeydownイベントをキャプチャするにはどうすればいいのでしょうか。フォーム上の他のすべてのコントロールのKeyDownをキャプチャして、処理のためにフォームに渡すルートに行きたくありません。これを行うためのより明確な方法はありますか?

29
Bohn

はい、確かにあります。現在入力フォーカスがあるコントロールに関係なく、フォームがキーイベントを処理する正しい方法は、フォームクラスの ProcessCmdKey method をオーバーライドすることです。

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    if (keyData == Keys.F1)
    {
        MessageBox.Show("You pressed the F1 key");
        return true;    // indicate that you handled this keystroke
    }

    // Call the base class
    return base.ProcessCmdKey(ref msg, keyData);
}

キーストロークを処理したことを示すためにtrueを返し、それを他のコントロールに渡したくない必要はありません。 doを他のコントロールのイベントハンドラーに渡したい場合は、単にfalseを返します。

そして、あなたは KeyPreview property を無視するのが最善です。これは、VB 6日間のアナクロニズムであり、.NETの世界でこれを行うには実際に推奨される方法ではありません。さらに読む: Form.KeyPreview = trueを設定することの欠点? =

60
Cody Gray

フォームのKeyPreviewをtrueに設定します。これにより、フォームが最初にキープレスメッセージを取得するようになります。それを処理する場合は、コントロールに渡されないようにe.Handled = trueを設定できます。

5
Bala R

KeyPreviewをオンにすると、フォーム内のすべてのキーが最初にそのキーイベントハンドラーを介してルーティングされます。

4
Blindy

別の方法は、ProcessCmdKey関数をオーバーライドすることです http://msdn.Microsoft.com/en-us/library/system.windows.forms.control.processcmdkey(v = VS.100).aspx

3
JTorrecilla