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

DataGridViewでセルの編集に使われているコンボボックスのSelectedIndexChangedイベントを捕捉する

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

DataGridViewでセルが編集中の時にキーイベントを捕捉する」で紹介したのと同じ方法により、DataGridViewに表示されているコンボボックスのSelectedIndexChangedイベントを捕捉することもできます。

以下に例を示します。ここでは、DataGridViewに"ComboBox"という名前のDataGridViewComboBoxColumnがあり、ここに表示されるコンボボックスのSelectedIndexChangedイベントを捕捉しています。

VB.NET
コードを隠すコードを選択
Private dataGridViewComboBox As DataGridViewComboBoxEditingControl = Nothing

'EditingControlShowingイベントハンドラ
Private Sub DataGridView1_EditingControlShowing(ByVal sender As Object, _
        ByVal e As DataGridViewEditingControlShowingEventArgs) _
        Handles DataGridView1.EditingControlShowing
    '表示されているコントロールがDataGridViewComboBoxEditingControlか調べる
    If TypeOf e.Control Is DataGridViewComboBoxEditingControl Then
        Dim dgv As DataGridView = CType(sender, DataGridView)

        '該当する列か調べる
        If dgv.CurrentCell.OwningColumn.Name = "ComboBox" Then
            '編集のために表示されているコントロールを取得
            Me.dataGridViewComboBox = _
                CType(e.Control, DataGridViewComboBoxEditingControl)
            'SelectedIndexChangedイベントハンドラを追加
            AddHandler Me.dataGridViewComboBox.SelectedIndexChanged, _
                AddressOf dataGridViewComboBox_SelectedIndexChanged
        End If
    End If
End Sub

'CellEndEditイベントハンドラ
Private Sub DataGridView1_CellEndEdit(ByVal sender As Object, _
        ByVal e As DataGridViewCellEventArgs) _
        Handles DataGridView1.CellEndEdit
    'SelectedIndexChangedイベントハンドラを削除
    If Not (Me.dataGridViewComboBox Is Nothing) Then
        RemoveHandler Me.dataGridViewComboBox.SelectedIndexChanged, _
            AddressOf dataGridViewComboBox_SelectedIndexChanged
        Me.dataGridViewComboBox = Nothing
    End If
End Sub

'DataGridViewに表示されているコンボボックスの
'SelectedIndexChangedイベントハンドラ
Private Sub dataGridViewComboBox_SelectedIndexChanged(ByVal sender As Object, _
        ByVal e As EventArgs)
    '選択されたアイテムを表示
    Dim cb As DataGridViewComboBoxEditingControl = _
        CType(sender, DataGridViewComboBoxEditingControl)
    Console.WriteLine(cb.SelectedItem)
End Sub
C#
コードを隠すコードを選択
private DataGridViewComboBoxEditingControl dataGridViewComboBox = null;

//EditingControlShowingイベントハンドラ
private void DataGridView1_EditingControlShowing(object sender,
    DataGridViewEditingControlShowingEventArgs e)
{
    //表示されているコントロールがDataGridViewComboBoxEditingControlか調べる
    if (e.Control is DataGridViewComboBoxEditingControl)
    {
        DataGridView dgv = (DataGridView)sender;

        //該当する列か調べる
        if (dgv.CurrentCell.OwningColumn.Name == "ComboBox")
        {
            //編集のために表示されているコントロールを取得
            this.dataGridViewComboBox =
                (DataGridViewComboBoxEditingControl)e.Control;
            //SelectedIndexChangedイベントハンドラを追加
            this.dataGridViewComboBox.SelectedIndexChanged +=
                new EventHandler(dataGridViewComboBox_SelectedIndexChanged);
        }
    }
}

//CellEndEditイベントハンドラ
private void DataGridView1_CellEndEdit(object sender,
    DataGridViewCellEventArgs e)
{
    //SelectedIndexChangedイベントハンドラを削除
    if (this.dataGridViewComboBox != null)
    {
        this.dataGridViewComboBox.SelectedIndexChanged -=
            new EventHandler(dataGridViewComboBox_SelectedIndexChanged);
        this.dataGridViewComboBox = null;
    }
}

//DataGridViewに表示されているコンボボックスの
//SelectedIndexChangedイベントハンドラ
private void dataGridViewComboBox_SelectedIndexChanged(object sender,
    EventArgs e)
{
    //選択されたアイテムを表示
    DataGridViewComboBoxEditingControl cb =
        (DataGridViewComboBoxEditingControl)sender;
    Console.WriteLine(cb.SelectedItem);
}

このコードでは、こちらのサンプルとは違い、CellEndEditイベントハンドラでSelectedIndexChangedイベントハンドラを削除しています。EditingControlShowingイベントハンドラで削除する方法では、ユーザーがコンボボックスの項目を変更した時以外に、コンボボックスが別のセルで使用されて初期化されるときに発生するSelectedIndexChangedイベントも捕捉してしまいます。

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

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