コントロールのContextMenuStripプロパティ(.NET Framework 1.1以前では、ContextMenuプロパティ)を使用してコンテキストメニューを表示している時、どのコントロールを右クリックしてコンテキストメニューを表示したかを調べる方法を紹介します。例えば、複数のコントロールで同じContextMenuStripを使用している時に役に立ちます。
ContextMenuStrip.SourceControlプロパティにより、ContextMenuStripを表示しているコントロールを取得できます。
ContextMenuStripを表示する直前に、そのContextMenuStripを表示しようとしているコントロールを取得する例を示します。この例では、「ContextMenuStrip1」というContextMenuStripがすでに存在しているものとして、ContextMenuStrip1のOpeningイベントが発生した時(コンテキストメニューが表示された時)、ContextMenuStripを表示しようとしているコントロールの名前を表示しています。
'ContextMenuStrip1のOpeningイベントハンドラ Private Sub ContextMenuStrip1_Opening(sender As Object, e As CancelEventArgs) _ Handles ContextMenuStrip1.Opening Dim menu As ContextMenuStrip = DirectCast(sender, ContextMenuStrip) 'ContextMenuStripを表示しているコントロールを取得する Dim source As Control = menu.SourceControl If source IsNot Nothing Then Console.WriteLine(source.Name) End If End Sub
//ContextMenuStrip1のOpeningイベントハンドラ private void ContextMenuStrip1_Opening(object sender, CancelEventArgs e) { ContextMenuStrip menu = (ContextMenuStrip)sender; //ContextMenuStripを表示しているコントロールを取得する Control source = menu.SourceControl; if (source != null) { Console.WriteLine(source.Name); } }
もう一つ例を示します。今度は、ContextMenuStripの項目(ToolStripMenuItem)がクリックされた時、そのContextMenuStripを表示したコントロールを取得する例です。ここでは、ContextMenuStrip(ContextMenuStrip1)に「CommandToolStripMenuItem」という項目が存在しているものとして、そのClickイベントが発生した時にContextMenuStripを表示したコントロールの名前を表示しています。
'ToolStripMenuItemのClickイベントハンドラ Private Sub CommandToolStripMenuItem_Click(sender As Object, e As EventArgs) _ Handles CommandToolStripMenuItem.Click 'ContextMenuStripを表示しているコントロールを取得する Dim source As Control = ContextMenuStrip1.SourceControl If source IsNot Nothing Then Console.WriteLine(source.Name) End If End Sub
//ToolStripMenuItemのClickイベントハンドラ private void CommandToolStripMenuItem_Click(object sender, EventArgs e) { //ContextMenuStripを表示しているコントロールを取得する Control source = contextMenuStrip1.SourceControl; if (source != null) { Console.WriteLine(source.Name); } }
上記最後の例で、CommandToolStripMenuItemがContextMenuStripの項目の子項目(入れ子になった項目)だった場合、SourceControlプロパティがnullになってしまいます。この問題の解決法は、不明です。しかしContextMenuStripのOpeningやOpenedイベントではSourceControlプロパティで正しく取得できますので、この時にSourceControlプロパティの内容を覚えておくという方法で回避できます。
この方法で問題を回避した例を示します。
'Openedイベント時点でのContextMenuStrip.SourceControlプロパティの内容 Private contextMenuSourceControl As Control = Nothing 'ContextMenuStrip1のOpenedイベントハンドラ Private Sub ContextMenuStrip1_Opened(sender As Object, e As EventArgs) _ Handles ContextMenuStrip1.Opened Dim menu As ContextMenuStrip = DirectCast(sender, ContextMenuStrip) 'SourceControlプロパティの内容を覚えておく contextMenuSourceControl = menu.SourceControl End Sub 'ToolStripMenuItemのClickイベントハンドラ Private Sub CommandToolStripMenuItem_Click(sender As Object, e As EventArgs) _ Handles CommandToolStripMenuItem.Click 'ContextMenuStripを表示しているコントロールを取得する If contextMenuSourceControl IsNot Nothing Then Console.WriteLine(contextMenuSourceControl.Name) End If End Sub
//Openedイベント時点でのContextMenuStrip.SourceControlプロパティの内容 private Control contextMenuSourceControl = null; //ContextMenuStrip1のOpenedイベントハンドラ private void ContextMenuStrip1_Opened(object sender, CancelEventArgs e) { ContextMenuStrip menu = (ContextMenuStrip)sender; //SourceControlプロパティの内容を覚えておく contextMenuSourceControl = menu.SourceControl; } //ToolStripMenuItemのClickイベントハンドラ private void CommandToolStripMenuItem_Click(object sender, EventArgs e) { //ContextMenuStripを表示しているコントロールを取得する if (contextMenuSourceControl != null) { Console.WriteLine(contextMenuSourceControl.Name); } }
ContextMenu.SourceControlプロパティにより、ContextMenuを表示しているコントロールを取得できます。
'ContextMenu1のPopupイベントハンドラ Private Sub ContextMenu1_Popup(ByVal sender As Object, _ ByVal e As System.EventArgs) _ Handles ContextMenu1.Popup 'ContextMenuを表示しているコントロールを表示する Console.WriteLine(ContextMenu1.SourceControl.Name) End Sub
//ContextMenu1のPopupイベントハンドラ private void ContextMenu1_Popup(object sender, System.EventArgs e) { //ContextMenuを表示しているコントロールを表示する Console.WriteLine(ContextMenu1.SourceControl.Name); }
なお、.NET Framework 1.1以前では、RichTextBoxコントロールではSourceControlプロパティが正しく返されません。2.0では、修正されました。