DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

DataGridViewにショートカットメニュー(ContextMenuStrip)を表示する

注意:DataGridViewコントロールは、.NET Framework 2.0で新しく追加されました。

ContextMenuStripプロパティ

DataGridViewにショートカットメニュー(ContextMenuStrip)を表示するには、ContextMenuStripプロパティを使用します。

ContextMenuStripプロパティは、DataGridView、DataGridViewColumn、DataGridViewRow、DataGridViewCellクラスに存在します。DataGridViewのContextMenuStripプロパティにContextMenuStripオブジェクトを設定すると、DataGridViewのどこを右クリックしても設定したContextMenuStripが表示されます。DataGridViewColumnのContextMenuStripプロパティを設定すると、ContextMenuStripはヘッダーを除く列のセルを右クリックした時に表示されます。DataGridViewRowのContextMenuStripプロパティを設定すると、ContextMenuStripはヘッダーを除く行のセルを右クリックした時に表示されます。DataGridViewCellのContextMenuStripプロパティを設定すると、ContextMenuStripはそのセルを右クリックした時に表示されます。

以下に、DataGridView、列、行、セルにContextMenuStripを設定する例を示します。なお、ContextMenuStrip1、ContextMenuStrip2、ContextMenuStrip3、ContextMenuStrip4はあらかじめフォームデザイナ等により作成されているものとします。

VB.NET
コードを隠すコードを選択
'DataGridViewのContextMenuStripを設定する
DataGridView1.ContextMenuStrip = Me.ContextMenuStrip1

'列のContextMenuStripを設定する
DataGridView1.Columns(0).ContextMenuStrip = Me.ContextMenuStrip2
'列ヘッダーのContextMenuStripを設定する
DataGridView1.Columns(0).HeaderCell.ContextMenuStrip = Me.ContextMenuStrip2

'行のContextMenuStripを設定する
DataGridView1.Rows(0).ContextMenuStrip = Me.ContextMenuStrip3

'セルのContextMenuStripを設定する
DataGridView1(0, 1).ContextMenuStrip = Me.ContextMenuStrip4
C#
コードを隠すコードを選択
//DataGridViewのContextMenuStripを設定する
DataGridView1.ContextMenuStrip = this.ContextMenuStrip1;

//列のContextMenuStripを設定する
DataGridView1.Columns[0].ContextMenuStrip = this.ContextMenuStrip2;
//列ヘッダーのContextMenuStripを設定する
DataGridView1.Columns[0].HeaderCell.ContextMenuStrip = this.ContextMenuStrip2;

//行のContextMenuStripを設定する
DataGridView1.Rows[0].ContextMenuStrip = this.ContextMenuStrip3;

//セルのContextMenuStripを設定する
DataGridView1[0, 1].ContextMenuStrip = this.ContextMenuStrip4;

上記のコードを実行して、DataGridViewの(0, 1)の位置にあるセルを右クリックすると、ContextMenuStrip4が表示されます。0番目の行のセル(ヘッダーを除く)を右クリックするとContextMenuStrip3が、0番目の列を右クリックするとContextMenuStrip2が表示されます。DataGridViewのそれ以外の部分では、ContextMenuStrip1が表示されます。

(0, 0)の位置にあるセルを右クリックするとContextMenuStrip3が表示されます。つまり、行のContextMenuStripが優先されます。さらに行のContextMenuStripより、セルのContextMenuStripが優先されます。

CellContextMenuStripNeeded、RowContextMenuStripNeededイベント

CellContextMenuStripNeededイベントを使用して、セルに表示するContextMenuStripを指定することもできます。現在のセルの状態や、値によって表示したいContextMenuStripを変更したい時に役に立ちます。

また、大量のセルや列、行のContextMenuStripプロパティを設定することは、効率的ではありません。そのような場合は、CellContextMenuStripNeededイベントを使用したほうがパフォーマンスが向上します。

ただしこのイベントは、DataSourceプロパティが設定されているか、VirtualModeプロパティがTrueの時にしか発生しません。

以下に、CellContextMenuStripNeededイベントを使用してContextMenuStripを指定する例を示します。

VB.NET
コードを隠すコードを選択
'CellContextMenuStripNeededイベントハンドラ
Private Sub DataGridView1_CellContextMenuStripNeeded( _
        ByVal sender As Object, _
        ByVal e As DataGridViewCellContextMenuStripNeededEventArgs) _
        Handles DataGridView1.CellContextMenuStripNeeded
    Dim dgv As DataGridView = CType(sender, DataGridView)
    If e.RowIndex < 0 Then
        '列ヘッダーに表示するContextMenuStripを設定する
        e.ContextMenuStrip = Me.ContextMenuStrip1
    ElseIf e.ColumnIndex < 0 Then
        '行ヘッダーに表示するContextMenuStripを設定する
        e.ContextMenuStrip = Me.ContextMenuStrip2
    ElseIf TypeOf (dgv(e.ColumnIndex, e.RowIndex).Value) Is Integer Then
        'セルが整数型のときに表示するContextMenuStripを変更する
        e.ContextMenuStrip = Me.ContextMenuStrip3
    End If
End Sub
C#
コードを隠すコードを選択
//CellContextMenuStripNeededイベントハンドラ
private void DataGridView1_CellContextMenuStripNeeded(object sender,
    DataGridViewCellContextMenuStripNeededEventArgs e)
{
    DataGridView dgv = (DataGridView)sender;
    if (e.RowIndex < 0)
    {
        //列ヘッダーに表示するContextMenuStripを設定する
        e.ContextMenuStrip = this.ContextMenuStrip1;
    }
    else if (e.ColumnIndex < 0)
    {
        //行ヘッダーに表示するContextMenuStripを設定する
        e.ContextMenuStrip = this.ContextMenuStrip2;
    }
    else if (dgv[e.ColumnIndex, e.RowIndex].Value is int)
    {
        //セルが整数型のときに表示するContextMenuStripを変更する
        e.ContextMenuStrip = this.ContextMenuStrip3;
    }
}

同じように、RowContextMenuStripNeededイベントにより、行に表示するContextMenuStripを指定することができます。

RowContextMenuStripNeededイベントを使用した例は、以下の通りです。

VB.NET
コードを隠すコードを選択
'RowContextMenuStripNeededイベントハンドラ
Private Sub DataGridView1_RowContextMenuStripNeeded( _
        ByVal sender As Object, _
        ByVal e As DataGridViewRowContextMenuStripNeededEventArgs) _
        Handles DataGridView1.RowContextMenuStripNeeded
    Dim dgv As DataGridView = CType(sender, DataGridView)
    '"Column1"列がBool型でTrueの時、ContextMenuStripを変更する
    Dim boolVal As Object = dgv("Column1", e.RowIndex).Value
    Console.WriteLine(boolVal)
    If TypeOf boolVal Is Boolean AndAlso CBool(boolVal) Then
        e.ContextMenuStrip = Me.ContextMenuStrip1
    End If
End Sub
C#
コードを隠すコードを選択
//RowContextMenuStripNeededイベントハンドラ
private void DataGridView1_RowContextMenuStripNeeded(object sender,
    DataGridViewRowContextMenuStripNeededEventArgs e)
{
    DataGridView dgv = (DataGridView)sender;
    //"Column1"列がBool型でTrueの時、ContextMenuStripを変更する
    object boolVal = dgv["Column1", e.RowIndex].Value;
    Console.WriteLine(boolVal);
    if (boolVal is bool && (bool)boolVal)
    {
        e.ContextMenuStrip = this.ContextMenuStrip1;
    }
}

CellContextMenuStripNeededイベントハンドラでは、「e.ColumnIndex」が-1ならば行ヘッダー、「e.RowIndex」が-1ならば列ヘッダーを意味します。RowContextMenuStripNeededイベントハンドラでは、「e.RowIndex」が-1になることはありません。

  • 履歴:
  • 2010/9/1 「ContextMenuStripプロパティ」のVB.NETのコードが説明と一致していなかったのを修正。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • イベントハンドラの意味が分からない、C#のコードをそのまま書いても動かないという方は、こちらをご覧ください。
  • .NET Tipsをご利用いただく際は、注意事項をお守りください。