ContextMenu
コントロールを使用してこれを行う良い方法はありません。これは、ネイティブの Win32 メニューの単なるラッパーです。他のすべてのアプリケーションのメニューと同様に、OS API を使用して描画されます。
ContextMenuStrip
これを、フレームワークによって C# コードで完全にカスタム描画されたコントロールと比較してください。それが最初にリリースされたとき、Windows と Office XP が棚の最新の製品だったとき、それは非常にクールに見えました (私は推測します)。Windows Vista が登場したとき、それは恐ろしく時代遅れになりました。唯一の利点は、メニューをより細かく制御できることです。たとえば、メニューでカスタム コントロールをホストし、項目の 1 つをクリックしたときにメニューが閉じないようにすることができます。ネイティブの Win32 メニューはそれをサポートしていません。
もちろん、それは単なる見落としや偶発的な省略ではありません。ユーザーが何かを選択した後もコンテキスト メニューを開いたままにしておくことは、設計が間違っていることを示す良い手がかりです。コンテキスト メニューの目的は、コンテキストに関連するオプションにユーザーがすばやくアクセスできるようにすることです。右クリック (またはキーボードの特別なボタンを押す) するだけで、作業中または達成しようとしていることに直接関連する選択肢のメニューが表示されます。通常のメニューと同様に、オプションを選択してメニューを非表示にすることができるはずです。
Windows では、すべてのメニューが「自動終了」です。メニューが永続的である必要がある場合は、メニューであってはなりません。代わりに、ツールバー、サイド バー、または何らかの種類のカスタム コントロールを使用することを検討してください。これらは、オプションの 1 つが選択されたときに消えるように設計されていないため、常に表示されるべき関連オプションを表示するのに理想的です。
オプションを選択した後、アプリケーションのコンテキスト メニューが消えない場合、それはバグだと思います。少なくとも、選択したものが「取得」されなかったと仮定して、もう一度クリックしてみます。
なぜWPFチームStaysOpen
がコンテキスト メニューにオプションを提供することにしたのか、そもそもなぜ独自のコンテキスト メニュー クラスを書き直したのか、私にはまったくわかりません。WinForms チームが既に同じことを行っていることから、彼らは何かを学んだのではないでしょうか?
コントロール (およびネイティブ メニュー) で求めていることを実行する唯一の方法ContextMenu
は、説明したものと同様のハックです。メニューの前の位置を保存し、コマンドが選択された後にポップを再表示します。メニューを前の場所に移動します。ちらつきに対してどのような治療法を思いついたとしても (たとえば、画面をフリーズさせ、コンテキスト メニューが再表示されるまで再描画を抑制するなど)、病気よりも悪いことがほぼ保証されています。