MenuクラスはMainMenuやMenuItemの基本クラスですが、これらは.NET 2.0から新しいクラスに置き換えられています。
旧 | 新 | |
---|---|---|
MainMenu MainMenu クラス (System.Windows.Forms) | MSDN |
→ | MenuStrip |
MenuItem MenuItem クラス (System.Windows.Forms) | MSDN |
→ | ToolStripMenuItem |
ContextMenu ContextMenu クラス (System.Windows.Forms) | MSDN |
→ | ContextMenuStrip |
メニュー全体を管理します。このオブジェクトをFormのMainMenuStripプロパティに設定することで、フォームにメニューが表示されます。
メニューの項目は、Itemsプロパティから取得できるToolStripItemCollectionクラスのメソッドを通して設定します。ToolStrip.Items プロパティ (System.Windows.Forms) | MSDN
menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { toolStripMenuItem1, toolStripMenuItem2, toolStripMenuItem3});
メニューを自動で隠す。c# - Autohide MenuStrip - How to activate it when showing? - Stack Overflow Auto-hide menu in Windows Forms – Reza Aghaei
型 | イベント | 発生タイミング |
---|---|---|
EventHandler | MenuActivate | MenuStripがアクティブになったとき |
EventHandler | MenuDeactivate | MenuStripが非アクティブになったとき |
一般的に、MenuStripのGotFocus、LostFocus、EnterそれにLeaveイベントは、キーボードによってアクティブになったときには発生しないことがあります。そのような場合にはMenuActivateとMenuDeactivateを代わりに用います。Remarks - MenuStrip.MenuActivate Event (System.Windows.Forms) | Microsoft Learn
メニュー階層の最上位であるMenuStrip.Itemsにフォーカスがあるとき、フォーム上の他のコントロールへFocus()などでフォーカスを移動しようとしても、キー入力は引き続きメニューへ送られます。そもそもメニューにフォーカスを移動してもForm.ActiveControlはフォーム上のコントロールを示したままのため、メニューからフォーカスを外すことになりません。
よってメニューにフォーカスがあるならば入力を破棄し、ユーザーにフォーカスを外すように促します。そのときメニューの項目にフォーカスがあることは、ToolStripMenuItem.Selectedで判定できます。
bool HasFocus() { foreach (ToolStripMenuItem item in menuStrip.Items) { if (item.Selected) return true; } return false; }
コンテキストメニュー (context menu / ショートカットメニュー / shortcut menu) を表すクラスです。
ControlのContextMenuStripプロパティに設定することで、そのコントロールを右クリックしたときに割り当てたContextMenuStripが表示されるようになります。Control.ContextMenuStrip プロパティ (System.Windows.Forms) | MSDN
Controlには同様のプロパティとしてContextMenuもありますが、両方に割り当てた場合にはContextMenuが優先されます。Remarks - Control.ContextMenuStrip Property (System.Windows.Forms) | MSDN
コンテキストメニューの表示を制御したいならばコントロールのプロパティには割り当てず、表示したい時機にContextMenuStripのShow()メソッドを呼びます。
public void Show( Control control, // 座標の基準となるコントロール Point position, // 座標の基準となるコントロールからの、相対的な表示位置 ToolStripDropDownDirection direction // 指定位置になる、コントロールの位置 )ToolStripDropDown.Show メソッド (Control, Point, ToolStripDropDownDirection) (System.Windows.Forms) | MSDN
directionは既定でToolStripDropDownDirection.Defaultで、左から右へ記述する言語の環境では、コンテキストメニューの左上または左下が指定位置になるように表示されます。
public ContextMenuStrip (System.ComponentModel.IContainer container);ContextMenuStrip(IContainer) - ContextMenuStrip コンストラクター (System.Windows.Forms) | Microsoft Learn
Formの子ではないためにContextMenuStripが破棄されないことがないように、ContextMenuStripのコンテナとなるIContainerを渡します。終了時にはこのIContainerのDispose()を呼ぶことで、それに格納されているContextMenuStripのDispose()が呼ばれます。
c# - When should we implement a constructor with the IContainer parameter for a Component? - Stack Overflowイベント | 発生タイミング |
---|---|
Opening | メニューが開くとき |
Opened | メニューが開かれたとき |
Closing | メニューが閉じるとき |
Closed | メニューが閉じたとき |
メニュー項目を動的に決定するには、Openingイベントのハンドラで処理します。
public event CancelEventHandler OpeningToolStripDropDown.Opening イベント (System.Windows.Forms) | MSDN
Openingイベントはメニューが開かれるときに発生するため、キーの押下によって呼び出されるToolStripMenuItem.ShortcutKeysが割り当てられたメニュー項目の有効/無効は制御できません。
ToolStripMenuItem.Enabledをfalseにすることでメニュー項目を無効にできますが、その設定はメニューを閉じた後も維持されるため、ShortcutKeysによるキーの割り当ても無効なままとなります。このように変更が維持されることを期待しないならば、Closedイベントで既定の設定に戻します。
引数のCancelEventArgs.Cancelをtrueとすることで、メニューが開かれるのを阻止できます。
IMEがオンの状態ではキー入力に対して変換の処理がされるため、意図した通りにアクセスキーで操作できません。たとえばメニューのTextプロパティが"&開く"ならば、IMEで「開」と変換することでこのメニューを実行できます。しかし実際にはアクセスキーは"開く(&O)"のように設定することが多く、この場合はoキーを押してもIMEによって「お」と解釈されるため、これを「o」に変換して確定しないとメニューを実行できません。
これに対処するにはContextMenuStripを拡張し、PreProcessMessage()でIMEが処理する前のキーを取得し、それをニーモニック文字としてコントロールへ送ります。
public class CustomContextMenuStrip : ContextMenuStrip
{
public override bool PreProcessMessage(ref Message msg)
{
const int WM_KEYDOWN = 0x100;
const int VK_PROCESSKEY = 0xE5; // IME PROCESS key
if (msg.Msg == WM_KEYDOWN && (int)msg.WParam == VK_PROCESSKEY)
{
uint virtualKey = ImmGetVirtualKey(Handle);
return ProcessMnemonic((char)virtualKey);
}
return base.PreProcessMessage(ref msg);
}
[DllImport("imm32.dll")]
static extern uint ImmGetVirtualKey(IntPtr hWnd);
}
ContextMenuStripに関する各種Tips・その1 - hnx8のブログ
Re[8]: IME入力中のキー入力を取得したい
ImmGetVirtualKey function (imm.h) - Win32 apps | Microsoft Learn
Virtual-Key Codes (Winuser.h) - Win32 apps | Microsoft Learn
MenuStripまたはContextMenuStrip内に表示される、個々のメニューの項目です。一方でこれらの項目の区切りを表すセパレータには、ToolStripSeparatorを用います。
ToolStripMenuItem() |
ToolStripMenuItem(Image) |
ToolStripMenuItem(String) |
ToolStripMenuItem(String, Image) |
ToolStripMenuItem(String, Image, EventHandler) |
ToolStripMenuItem(String, Image, EventHandler, Keys) |
ToolStripMenuItem(String, Image, EventHandler, String) |
ToolStripMenuItem(String, Image, ToolStripItem[]) |
imageを設定する必要がなければ、その引数にはnullを渡します。
EventHandlerのonClickをコンストラクタで指定しない場合には、後からClickイベントに設定できます。
型 | プロパティ | |
---|---|---|
string | Text | 項目のテキスト |
string | Name | 項目の名前。これはToolStripItemCollectionのキーとして使用できる |
Keys | ShortcutKeys | 項目のショートカットキー |
string | ShortcutKeyDisplayString | 項目のショートカットキーのテキスト |
Font | Font | 項目のテキストのフォント |
bool | Checked | trueならば、項目が選択されている |
bool | CheckOnClick | trueならば、クリックで項目が自動的にチェックされる。そのときCheckedの値が変更され、CheckedChangedイベントが発生する |
bool | Available | trueならば、ToolStripに配置される
※表示されるかどうかを示すもので、表示状態を示すVisibleとは異なる Remarks - ToolStripItem.Available Property (System.Windows.Forms) | MSDN |
bool | Visible | trueならば、表示されている |
bool | Enabled | trueならば、有効 |
項目に表示されるテキストです。ToolStripItem.Text プロパティ (System.Windows.Forms) | MSDN
文字の直前に「&」をつけることでそれがアクセスキー (access key) となり、Altキーと同時に押すことでその項目を選択できるようになります。
コード | アプリケーションでの表示 |
---|---|
"&File" |
File |
"ファイル(&F)" |
ファイル(F) |
ショートカットキーを設定することで、そのキーの押下でこの項目のClickイベントのハンドラを呼び出せるようになります。ToolStripMenuItem.ShortcutKeys Property (System.Windows.Forms) | Microsoft Learn
ToolStripManager.IsValidShortcut()がfalseを返すキーは無効であり、「引数値 'value' (***) は列挙型 'Keys' に対して無効です。」としてInvalidEnumArgumentExceptionが投げられます。 ShortcutKeys - ToolStripMenuItem.cs IsValidShortcut - ToolStripManager.cs
無効とされるキーでも、KeyDownなどのイベントを用いればキーに応答することは可能です。そのときはShortcutKeyDisplayStringでそのキーをメニューに表示できます。
Visibleがfalseでもショートカットキーは有効ですが、Enabledがfalseならば無効になります。
設定したショートカットキーが機能しないときには、フォーム上のコントロールによって入力が捕捉され破棄されていないか確認します。
メソッド | 機能 |
---|---|
PerformClick() | Clickイベントを発生できる |
EnabledやVisibleがfalseでクリックできない状態になっていると、このメソッドを呼び出してもClickイベントは発生しません。
イベント | 発生タイミング |
---|---|
Click | 項目がクリックされたとき |
DropDownOpening | 項目のDropDownが開くとき |
Visual Studioのビュー デザイナーからは、実際の構造を確認しながらメニューを作成できます。
追加したメニュー項目の詳細は、デザイナー下部のMenuStripコンポーネントのコンテキストメニューの[項目の編集]から確認できます。