DOBON.NET

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をご利用いただく際は、注意事項をお守りください。
共有する

この記事への評価
良い / 悪い = 19 / 2

この記事へのコメント
通常のコメント [ o ] 2013年4月2日 15:11:41
セルにホストされているコントロールを取得できれば、使い慣れのイベントや、プロパティもそのまま。大変便利です。
ありがとうございました。

通常のコメント [ 匿名 ] 2011年8月13日 01:24:37
SelectedIndexChangedイベント内で、編集中のセルの位置を取得する方法も欲しいです。

通常のコメント [ 管理人 ] 2010年6月28日 17:17:58
> SelectedIndexChangedイベントハンドラを削除するのはdataGridView1_CellValueChangedにした方がいいと思います。
> 上記のdataGridView1_CellEndEditで削除する場合、SelectedIndexChangedイベントを3回繰り返すことがあります。

遅くなって申し訳ありません。

CellValueChangedですと現在と同じ値を選択した時は発生しませんので、ちょっと問題があるように思えます。もし、CellEndEditを使った場合にどのような状況で問題が起こるのかお分かりでしたら、教えていただけないでしょうか?

やはりCellEndEditで問題があるようでしたら、

DataGridViewでセルが編集中の時にキーイベントを捕捉する
http://dobon.net/vb/dotnet/datagridview/textboxevent.html

の方法をお試しください。

評価の理由 [ てづか ] 2010年4月12日 06:26:15
評価:良い
わかりやすく助かります。

通常のコメント [ はは ] 2010年3月11日 10:05:25
SelectedIndexChangedイベントハンドラを削除するのはdataGridView1_CellValueChangedにした方がいいと思います。
上記のdataGridView1_CellEndEditで削除する場合、SelectedIndexChangedイベントを3回繰り返すことがあります。


この記事に関するコメントを投稿するには、下のボタンをクリックしてください。投稿フォームへ移動します。通常のご質問、ご意見等は掲示板へご投稿ください。