ToolStripMenuItemにKeyDownイベントを追加する
.NET Framework(WinForms)のメニュー項目コントロールToolStripMenuItemには、KeyDown/KeyUp/KeyPressイベントは用意されていません。
特定のメニュー項目が選ばれてる状態で、何らかのキー、たとえば「Delete」「F2」キーなどが押されたことを検出するのはちょっと面倒くさいです。
(そのメニュー項目の親項目ContextMenuStripにKeyDownイベント等を仕掛け、押されたキー/SelectedになっているToolStripMenuItemの組み合わせに応じた処理を書けばよいのですが・・・メニュー項目ごとに処理が異なる場合などソースコードがかなり煩雑になってしまいます)
ToolStripMenuItemを拡張し、キーをが押されたらKeyDownイベントを発動するようにしてみましょう。こんなソースになります。
ToolStripMenuItemEx.cs ソースコード
/// <summary> /// 改良版ToolStripMenuItem /// <para>・KeyDownイベント追加</para> /// </summary> public class ToolStripMenuItemEx : ToolStripMenuItem { /// <summary> /// 新しいインスタンスを初期化します。(フォームデザイナ向け) /// </summary> public ToolStripMenuItemEx() : base() { } /// <summary> /// 新しいインスタンスを初期化します。(Text指定) /// </summary> public ToolStripMenuItemEx(string text) : base(text) { } //ソースコードで動的生成する場合は、適宜便利な形のコンストラクタを追加すると幸せになれます。 //---------------------------------------------------------------------- /// <summary> /// この項目にフォーカスがあるときにキーが押されると発生します。 /// (通常Controlと同等のイベントを疑似的に発生させています) /// </summary> [Category("キー")] [Description("キーが最初に押されたときに発生します。")] public event KeyEventHandler KeyDown; /// <summary> /// 疑似的にKeyDownイベントを発動します。 ///</summary> protected override bool ProcessDialogKey(Keys keyData) { bool ret = base.ProcessDialogKey(keyData); if (ret == false && KeyDown != null) { //KeyDownイベントを発生させる KeyEventArgs e = new KeyEventArgs(keyData); KeyDown(this, e); return e.Handled; } return ret; } }
使い方
いったんビルドしてください。
フォームデザイナでメニュー項目を設定する際に、「MenuItemEx」が選べるようになります。MenuItemの代わりに追加してください。
ソースコードから動的にメニュー項目を生成するのであれば適切なコンストラクタを呼び出してください。
制限事項等
やっていることはソースの通り、押下されたキーを処理するProcessDialogKeyメソッドを上書きして自作KeyDownメソッドを呼び出しているだけです。
KeyDownイベント発動のタイミング/発動のされ方が通常のControlどおりではないため、イベントが発生しないキーがあったり、Handled=trueを設定しても入力がキャンセルされなかったりするかもしれません。動作確認は慎重に行ってください。
もし不具合を見つけたら、教えていただけると助かります。