none
TextBox の特定の定義済みショートカットキーを無効にする方法 RRS feed

  • 質問

  • お世話になります。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の仕様だとは考えにくく、何かしらの手段があるのではと思い、質問させていただきました。

    何か情報をお持ちの方がいらっしゃいましたら、ぜひコメントください。
    よろしくお願いいたします。

     

    2007年2月15日 14:57

回答

  • Dominica です。

    やはりこれまで書いたような動きはおかしいので、流用元を疑い再調査しました。
    その結果、自作コントロールの継承元のイベントを AddHandler で拾って処理をしているクラスがあり、
    特定条件で MenuItem のEnabled プロパティが False となり、ショートカットが無効になっていることがわかりました。
    完全にこちらの不具合です。ソースを追っても実際動かしても問題点を見つけ切れなかったので、VS2005 のせいにしてしまいました。調査不足、なんとも情けない。

    前述の AddHandler のような仕組みは取り除くなど、一度根本から見直すことにします。
    大変お騒がせしました。

    2007年2月18日 2:15

すべての返信

  • ProcessCmdKey メソッドをオーバーライドしてみたらどうでしょうか。

     

    2007年2月16日 2:38
  • えムナウさん、コメントありがとうございます。 Dominica です。

    まだ実際に試せていませんが、確かに ProcessCmdKey のオーバライドで解決できそうです。
    具体的には ContextMenuStrip を継承し、
     IsCmdKeyExists(ByVal cmdKey As Keys) As Boolean
    といったメソッドを実装して、まず ContextMenuStrip のアイテムのショートカットに一致するかを判定することになるかと思います。

    が、やはりちょっと腑に落ちませんね。
    MSDN の ProcessCmdKey のトピックには、
     ・ProcessCmdKey メソッドは、まずコントロールに ContextMenu があるかどうかを確認する。
     ・コンテキスト メニューがある場合は、 ContextMenu でコマンド キーを処理できるようにする。
     ・コマンド キーがメニューのショートカットでない場合、コントロールが親を持っていれば、キーは親の ProcessCmdKey メソッドに渡される。
    とあるので、本来の使用方法とは異なるというか、本来ならばオーバライドせずとも、望む動作になるものである気がします。

    今の動作が VS2005 の仕様なのであればコメント頂いたオーバライドの方法で解決なのですが、不具合なのであれば将来修正された場合に2回動作してしまったり、同じ動作にならなかったりと色々ありそうでちょっと不安です。
    最悪を想定して不具合だとして、ProcessCmdKey の戻り値はしっかり考えないといけないですね。
    実際に試して処理を実装したら、こちらで報告させていただきます。

    他にもご意見をお持ちの方いらっしゃいましたら、コメント下さい。
    よろしくお願い致します。

     

    2007年2月17日 4:59
  • Dominica です。

    やはりこれまで書いたような動きはおかしいので、流用元を疑い再調査しました。
    その結果、自作コントロールの継承元のイベントを AddHandler で拾って処理をしているクラスがあり、
    特定条件で MenuItem のEnabled プロパティが False となり、ショートカットが無効になっていることがわかりました。
    完全にこちらの不具合です。ソースを追っても実際動かしても問題点を見つけ切れなかったので、VS2005 のせいにしてしまいました。調査不足、なんとも情けない。

    前述の AddHandler のような仕組みは取り除くなど、一度根本から見直すことにします。
    大変お騒がせしました。

    2007年2月18日 2:15