コンテキストメニューとはWindowsで右クリックすると表示されるメニューのことです。コンテクストとは「文脈」や「状況」のことで、選択していたものや作業状態によって、メニューに表示される項目が切り替わることを意味します。だから同じ右クリックでも場所によって異なるメニューを表示させることができます。

C#なら簡単にコンテキストメニューを表示させ、ユーザーがメニューを選択するとそれに対応した処理をおこなうことができます。

デザイナを使う方法

C# WindowsFormsアプリケーションを作るのであればWindows フォームデザイナーという便利なものがあります。これをつかってコンテキストメニューを表示させる方法を紹介します。

まずツールボックスからContextMenuStripをフォームのうえにドラッグアンドドロップします。

すると以下のようになります。通常のメニューが表示される位置にContextMenuStripが表示されます。他の部分をクリックしてしまうと通常のメニューが表示される位置に表示されていたContextMenuStripは見えなくなってしまいますが、その場合はフォームの下に表示されているcontextMenuStrip1(下の図の下の赤枠で囲まれている部分)を選択すると再度表示されます。

ここへ入力と書かれている部分(上の図の上の赤枠で囲まれている部分)にメニューの項目名を書きます。ここでは「メニューその1」「メニューその2」という項目を追加しました。すると以下の画像のようになります。

メニューをクリックしたらなにをしたいのかを定義します。そのためにはContextMenuStripのメニューの項目が表示されている部分(上の図の赤枠で囲まれている部分)をダブルクリックします。すると以下のようなコードが自動生成されます。

ここでは単純にメニューがクリックされたらMessageBoxを表示させるだけにします。

イベントハンドラ名に日本語が入ってしまうのはよくないというのであればダブルクリックするまえにContextMenuStripのメニューの項目を選択してプロパティの(Name)の部分を書き換えます。ここではSecondMenuItemという名前に書き換えています(下の図の赤枠で囲まれている部分)。そしてこれをダブルクリックすると以下のようなコードが自動生成されます。

さてこれだけでは右クリックしてもコンテキストメニューは表示されません。なにを右クリックしたらコンテキストメニューが表示されるのかを指定していないからです。

もしフォームを右クリックしたときにコンテキストメニューが表示されるようにしたいのであればForm1クラスのコンストラクタに以下の1行を追加します。

これで右クリックしたときにコンテキストメニューが表示されますが、なにか物足りないです。多くのアプリケーションはメニューの左側にアイコンが表示されます。ではコンテキストメニューにアイコンを表示させるためにはどうすればいいのでしょうか?

まずアイコンを用意します。アイコンがないなら普通の画像ファイルでもかまいません。

そしてアイコンを設定したいメニューを選択してプロパティのImageの右側をクリックします。

すると下の図のようなダイアログが現れるので、プロジェクトリソースファイルを選択してインポートをクリックします。

インポートしたい画像ファイルを選びます。icoファイルやpng,jpeg,bmpファイルを選択できます。複数選択可なのでインポートしたい画像ファイルを選んだら[開く]を選択します。

インポートされたイメージからメニューのアイコンにしたいものを選択して[OK]をクリックします。

デザイナを使わない方法

デザイナを使わない方法も紹介します。メニューの項目が固定ではなく変化する場合はこちらのほうがいいかもしれません。

ContextMenuStripのインスタンスを生成してForm1.ContextMenuStripプロパティにセットし、あとはContextMenuStrip.Items.Addメソッドで項目を追加します。ContextMenuStrip.Items.Addメソッドにはオーバーロードがいくつかありますが、引数が3つ(string型、Image型、EventHandler型)のものがわかりやすいと思います。

そのときにメニューにアイコンをつけたい場合は、アイコンまたは画像ファイルをリソースに追加しておき、それを使います。

右クリックされた場所でコンテキストメニューを変える

右クリックされた場所でコンテキストメニューを変えるアプリをつくってみましょう。ContextMenuStripを2つ作り、右クリックした座標がフォームの左半分と右半分で切り替えて表示させます。

フォーム上にLabelを貼り付けておき、メニューがクリックされたら項目名を表示させます。

マウスが移動するとOnMouseMoveが呼び出されます。フォーム上におけるマウスのX座標を調べてフォームの幅の半分未満なら左半分、そうでないなら右半分にマウスポインタがあると判断します。そしてForm1.ContextMenuStripプロパティに適切なContextMenuStripのインスタンスを設定します。

実際に動作させてみるとこんな感じになります。