WPFでコンテキストメニューを使ったプログラムを組んでたときのお話。 MenuItemにRoutedUICommandを登録してショートカットキーを使えるようにしていました。 で、アプリケーション実行中にショートカットキーを変更しようと次のようなコードを書きました。
public readonly static RoutedUICommand FooCommand; ... void bar_function() { FooCommand.InputGestures.Clear(); FooCommand.InputGestures.Add(new KeyGesture(Key.A) ); }
Addのところで例外発生です。 どうやらCtrlなどの修飾キーなしでRoutedUICommandにKeyGestureを追加したら例外が発生する仕様らしいですね。 A-Z、数字、記号など押して文字が出る普通のキーは修飾キーとセットで登録しないとなりません。
wpfでアプリケーションを作る場合、ショートカットキーのカスタマイズを実装するには注意する必要があるようです。 Ctrl+Aとかではなく、AキーだけでショートカットにしたいときはRoutedUICommandは使えません。 そういうときは独自にキーイベントを処理するコードを書くことになります。 まぁ、ゲームとかを除くと「Ctrlと一緒なんて絶対だめだ」というようなケースはたいてい思考が固まっているだけなので、何が便利か考え直せばRoutedUICommandでOKになると思います。
ちなみに、コーディングのミスでKeyGesture(Key.Back)とかしたら例外は出ませんでした。 MSDNには「ほとんどの場合、KeyGestureは1つ以上のModifierKeysに関連付けられている必要があります。 この規則の例外は、単独で有効なKeyGestureにできるファンクションキーとテンキーのキーです。」とあるけど、どうやら他にも単独で有効にできるキーはありそうですね。
完全ではないけど修飾キーなしでショートカットとして登録できるキーを調べてみました。 こんな感じになりました。 oは単独でショートカットキーにできます。 xは特殊なキーのためショートカットキーには使用できません。 (修飾キーとセットでも不可)
- Back … o
- TAB … o
- エンター … o(NumPadと共用)
- Space … o
- Insert … o
- Delete … o
- Home … o
- End … o
- PageUp … o
- PageDown … o
- PrintScreen … x
- Scroll … o
- Pause … o
- NumLock … o
- CapsLock … x
- F1~F12 … o
- 全角半角 … x(該当キーコード不明)
- 無変換 … o
- 前候補/変換 … x(該当キーコード不明)
- カタカナ/ひらがな … x(該当キーコード不明)
- テンキー/ … o
- テンキー* … o
- テンキー- … o
- テンキー+ … o
- テンキーEnter … o(本体のキーと共用)
- テンキー.(小数点) … o
- テンキー0-9 … o
一部を除いてショートカットキーに使えるようですね。 ちなみに、テンキーはNumLockした状態で調べました。
今MSDNどおりじゃない状況なわけですが、将来の仕様変更でMSDNどおりになってこれらのキーのショートカットが単体で使えなくなる可能性も有るんですかね?