Menuクラス

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

クラス階層

  • System.ComponentModel.Component
    • System.Windows.Forms.Control
      • System.Windows.Forms.ScrollableControl
        • System.Windows.Forms.ToolStrip … ツールバーのコンテナ
          • System.Windows.Forms.MenuStrip
          • System.Windows.Forms.ToolStripDropDown
            • System.Windows.Forms.ToolStripDropDownMenu
    • System.Windows.Forms.ToolStripItemToolStrip内に配置できる個々の項目
      • System.Windows.Forms.ToolStripControlHost
      • System.Windows.Forms.ToolStripButton
      • System.Windows.Forms.ToolStripDropDownItem
        • System.Windows.Forms.ToolStripMenuItem
        • System.Windows.Forms.ToolStripDropDownButton
        • System.Windows.Forms.ToolStripSplitButton
    • System.Windows.Forms.Menu
      • System.Windows.Forms.MainMenu
      • System.Windows.Forms.MenuItem
      • System.Windows.Forms.ContextMenu

MenuStrip

メニュー全体を管理します。このオブジェクトをFormのMainMenuStripプロパティに設定することで、フォームにメニューが表示されます。

プロパティ

Items

メニューの項目は、Itemsプロパティから取得できるToolStripItemCollectionクラスのメソッドを通して設定します。ToolStrip.Items プロパティ (System.Windows.Forms) | MSDN

menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
    toolStripMenuItem1,
    toolStripMenuItem2,
    toolStripMenuItem3});

ContextMenuStrip

コンテキストメニュー (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 メニューが閉じたとき
   
イベント - ContextMenuStrip クラス (System.Windows.Forms) | Microsoft Learn

Openingイベント

メニュー項目を動的に決定するには、Openingイベントのハンドラで処理します。

public event CancelEventHandler Opening
ToolStripDropDown.Opening イベント (System.Windows.Forms) | MSDN

Openingイベントはメニューが開かれるときに発生するため、キーの押下によって呼び出されるToolStripMenuItem.ShortcutKeysが割り当てられたメニュー項目の有効/無効は制御できません。

ToolStripMenuItem.Enabledをfalseにすることでメニュー項目を無効にできますが、その設定はメニューを閉じた後も維持されるため、ShortcutKeysによるキーの割り当ても無効なままとなります。このように変更が維持されることを期待しないならば、Closedイベントで既定の設定に戻します。

引数のCancelEventArgs.Cancelをtrueとすることで、メニューが開かれるのを阻止できます。

トラブル対処法

IMEがオンだと、アクセスキーでの操作が困難

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

ToolStripMenuItem

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[])
コンストラクター - ToolStripMenuItem クラス (System.Windows.Forms) | Microsoft Learn

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ならば、有効
プロパティ - ToolStripMenuItem クラス (System.Windows.Forms) | Microsoft Learn

Text

項目に表示されるテキストです。ToolStripItem.Text プロパティ (System.Windows.Forms) | MSDN

文字の直前に「&」をつけることでそれがアクセスキー (access key) となり、Altキーと同時に押すことでその項目を選択できるようになります。

コード アプリケーションでの表示
"&File" File
"ファイル(&F)" ファイル(F)
方法 : Windows フォーム コントロールのアクセス キーを作成する | MSDN

ShortcutKeys

ショートカットキーを設定することで、そのキーの押下でこの項目の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イベントを発生できる
   

イベント

イベント 発生タイミング
Click 項目がクリックされたとき
DropDownOpening 項目のDropDownが開くとき
   
イベント - ToolStripMenuItem クラス (System.Windows.Forms) | Microsoft Learn

メニュー デザイナ (Menu Designer)

Visual Studioのビュー デザイナーからは、実際の構造を確認しながらメニューを作成できます。

  1. メニューを追加するフォームを、ビュー デザイナーで開く。
  2. ツールボックスで[MenuStrip]の項目をダブルクリックし、フォームに追加する。
  3. [ここへ入力]に項目名を入力する。これが表示されていない場合はデザイナー下部のMenuStripコンポーネントをクリックし、アクティブにする。
  4. 他のトップレベルの項目やサブメニュー項目も、同様に[ここへ入力]から追加する。

追加したメニュー項目の詳細は、デザイナー下部のMenuStripコンポーネントのコンテキストメニューの[項目の編集]から確認できます。

Microsoft Learnから検索