トップ回答者
TextBox の特定の定義済みショートカットキーを無効にする方法

質問
-
お世話になります。Dominica と申します。
現在、VB2005(sp1) で TextBox を継承したコントロールを作成中です。
この TextBox の Undo 機能を改良し、TextChanged イベントの発生履歴を取って、詳細な Undo、Redo を可能にするようにしました。そして、ContextMenuStrip にも「元に戻す(&Z)」と「やり直し(&Y)」の ToolStripMenuItem を追加し、それぞれショートカットキーを Ctrl+Z、Ctrl+Y と設定しました。
ところが、定義済みのショートカットキーのほうが ToolStripMenuItem より優先されるみたいで、Ctrl+Z を押下すると TextBox 標準の Undo が効いてしまい、自作のメソッドがうまく動きません。
ShortcutsEnabled プロパティを False に設定すると、確かに標準の Undo は効かなくなりますが、ToolStripMenuItem のショートカットもすべて無効になってしまいます。Ctrl+Z 以外の定義済みショートカットキーがすべて無効になるのも都合が良くありません。
MSDN には、ShortcutsEnabled プロパティをオーバライドすれば他のショートカットキーも追加可能とありますが、Boolean のプロパティでどうやれば追加できるのか、やってはみたものの結局ただのBoolean 型プロパティにしかならず、意味がさっぱりわかりません。Ctrl+Z に限った話ではなく、他の自作コントロールでも同様の問題が発生している状況でして、各コントロール、各キーごとに、KeyDown イベントであれこれ制御したくないので、どうにかショートカットキーの範囲内で事を収めてしまいたいのですが、どうにかならないものでしょうか?
定義済みショートカットキーが最優先され、且つ変更できないというこの状態が VS2005の仕様だとは考えにくく、何かしらの手段があるのではと思い、質問させていただきました。何か情報をお持ちの方がいらっしゃいましたら、ぜひコメントください。
よろしくお願いいたします。
回答
-
Dominica です。
やはりこれまで書いたような動きはおかしいので、流用元を疑い再調査しました。
その結果、自作コントロールの継承元のイベントを AddHandler で拾って処理をしているクラスがあり、
特定条件で MenuItem のEnabled プロパティが False となり、ショートカットが無効になっていることがわかりました。
完全にこちらの不具合です。ソースを追っても実際動かしても問題点を見つけ切れなかったので、VS2005 のせいにしてしまいました。調査不足、なんとも情けない。前述の AddHandler のような仕組みは取り除くなど、一度根本から見直すことにします。
大変お騒がせしました。
すべての返信
-
えムナウさん、コメントありがとうございます。 Dominica です。
まだ実際に試せていませんが、確かに ProcessCmdKey のオーバライドで解決できそうです。
具体的には ContextMenuStrip を継承し、
IsCmdKeyExists(ByVal cmdKey As Keys) As Boolean
といったメソッドを実装して、まず ContextMenuStrip のアイテムのショートカットに一致するかを判定することになるかと思います。が、やはりちょっと腑に落ちませんね。
MSDN の ProcessCmdKey のトピックには、
・ProcessCmdKey メソッドは、まずコントロールに ContextMenu があるかどうかを確認する。
・コンテキスト メニューがある場合は、 ContextMenu でコマンド キーを処理できるようにする。
・コマンド キーがメニューのショートカットでない場合、コントロールが親を持っていれば、キーは親の ProcessCmdKey メソッドに渡される。
とあるので、本来の使用方法とは異なるというか、本来ならばオーバライドせずとも、望む動作になるものである気がします。今の動作が VS2005 の仕様なのであればコメント頂いたオーバライドの方法で解決なのですが、不具合なのであれば将来修正された場合に2回動作してしまったり、同じ動作にならなかったりと色々ありそうでちょっと不安です。
最悪を想定して不具合だとして、ProcessCmdKey の戻り値はしっかり考えないといけないですね。
実際に試して処理を実装したら、こちらで報告させていただきます。他にもご意見をお持ちの方いらっしゃいましたら、コメント下さい。
よろしくお願い致します。 -
Dominica です。
やはりこれまで書いたような動きはおかしいので、流用元を疑い再調査しました。
その結果、自作コントロールの継承元のイベントを AddHandler で拾って処理をしているクラスがあり、
特定条件で MenuItem のEnabled プロパティが False となり、ショートカットが無効になっていることがわかりました。
完全にこちらの不具合です。ソースを追っても実際動かしても問題点を見つけ切れなかったので、VS2005 のせいにしてしまいました。調査不足、なんとも情けない。前述の AddHandler のような仕組みは取り除くなど、一度根本から見直すことにします。
大変お騒がせしました。