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

DataGridViewのコンボボックスにユーザーが文字列を入力できるようにする

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

DataGridViewの列にコンボボックスを表示する」のようにDataGridViewComboBoxColumnを使ってDataGridViewにコンボボックスを表示すると、通常はDropDownStyleがDropDownListになっており、ユーザーが文字列を入力することができません。ユーザーが文字列を入力できるようにするには、こちらで紹介した方法によりコンボボックスのDropDownStyleプロパティをDropDownに変更するだけでよさそうですが、実際にはこれだけではうまくいきません。入力された値がコンボボックスのリストに登録されていなければ、エラーが発生します。

How do I enable typing in the combo box cell?(リンク切れのため、Internet Archiveへのリンク)」では、DropDownStyleプロパティをDropDownに変更して、さらに、CellValidatingイベントハンドラでユーザーが入力した値をコンボボックスに追加するという方法が紹介されています。

この方法を使った例を以下に示します。この例では、"ComboBox"という名前の列がDataGridViewComboBoxColumnであり、この列のコンボボックスのDropDownStyleをDropDownに変更しています。

VB.NET
コードを隠すコードを選択
'EditingControlShowingイベントハンドラ
Private Sub DataGridView1_EditingControlShowing(ByVal sender As Object, _
        ByVal e As DataGridViewEditingControlShowingEventArgs) _
        Handles DataGridView1.EditingControlShowing
    If TypeOf e.Control Is DataGridViewComboBoxEditingControl Then
        '該当する列か調べる
        Dim dgv As DataGridView = CType(sender, DataGridView)
        If dgv.CurrentCell.OwningColumn.Name = "ComboBox" Then
            '編集のために表示されているコントロールを取得
            Dim cb As DataGridViewComboBoxEditingControl = _
                CType(e.Control, DataGridViewComboBoxEditingControl)
            cb.DropDownStyle = ComboBoxStyle.DropDown
        End If
    End If
End Sub

'CellValidatingイベントハンドラ
Private Sub DataGridView1_CellValidating(ByVal sender As Object, _
        ByVal e As DataGridViewCellValidatingEventArgs) _
        Handles DataGridView1.CellValidating
    Dim dgv As DataGridView = CType(sender, DataGridView)
    '該当する列か調べる
    If dgv.Columns(e.ColumnIndex).Name = "ComboBox" AndAlso _
        TypeOf dgv.Columns(e.ColumnIndex) Is DataGridViewComboBoxColumn Then
        Dim cbc As DataGridViewComboBoxColumn = _
            CType(dgv.Columns(e.ColumnIndex), DataGridViewComboBoxColumn)
        'コンボボックスの項目に追加する
        If Not cbc.Items.Contains(e.FormattedValue) Then
            cbc.Items.Add(e.FormattedValue)
        End If
        'セルの値を設定しないと、元に戻ってしまう
        dgv(e.ColumnIndex, e.RowIndex).Value = e.FormattedValue
    End If
End Sub
C#
コードを隠すコードを選択
//EditingControlShowingイベントハンドラ
private void DataGridView1_EditingControlShowing(object sender,
    DataGridViewEditingControlShowingEventArgs e)
{
    if (e.Control is DataGridViewComboBoxEditingControl)
    {
        //該当する列か調べる
        DataGridView dgv = (DataGridView)sender;
        if (dgv.CurrentCell.OwningColumn.Name == "ComboBox")
        {
            //編集のために表示されているコントロールを取得
            DataGridViewComboBoxEditingControl cb =
                (DataGridViewComboBoxEditingControl)e.Control;
            cb.DropDownStyle = ComboBoxStyle.DropDown;
        }
    }
}

//CellValidatingイベントハンドラ
private void DataGridView1_CellValidating(object sender,
    DataGridViewCellValidatingEventArgs e)
{
    DataGridView dgv = (DataGridView)sender;
    //該当する列か調べる
    if (dgv.Columns[e.ColumnIndex].Name == "ComboBox" &&
        dgv.Columns[e.ColumnIndex] is DataGridViewComboBoxColumn)
    {
        DataGridViewComboBoxColumn cbc =
            (DataGridViewComboBoxColumn)dgv.Columns[e.ColumnIndex];
        //コンボボックスの項目に追加する
        if (!cbc.Items.Contains(e.FormattedValue))
        {
            cbc.Items.Add(e.FormattedValue);
        }
        //セルの値を設定しないと、元に戻ってしまう
        dgv[e.ColumnIndex, e.RowIndex].Value = e.FormattedValue;
    }
}
  • 履歴:
  • 2009/2/5 セルの値がすぐに元に戻ってしまう不具合を修正。(掲示板等でご指摘いただきました。)
  • 2016/5/30 リンク切れを修正。

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

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