3

I'm having difficulty populating a dropdown list in my gridview. I have created the column with the code below:

  If Not Me.GridViewIsConstructed Then
            gv.Columns.Add(createComboBoxWithDDL(Me.ddlGPField.Items, "Bank_GP_Field_Name", "GPField"))
            gv.Columns.Add(createComboBoxWithDDL(Me.ddlBankField.Items, "Bank_Bank_Field_Name", "BankField"))
  End IF


  Private Function createComboBoxWithDDL(ByVal obj As Object, ByVal nDataFieldName As String, ByVal nColName As String) As DataGridViewComboBoxColumn
        Dim combo As New DataGridViewComboBoxColumn
        combo.DataSource = obj
        combo.DataPropertyName = nDataFieldName
        combo.Name = nColName
        Return combo
    End Function

The problem is that I cannot get the formatting handle to populate the combo box with the index that I need. here is my code attempts for the BankField DropDown List.

If e.ColumnIndex = gv.Columns("BankField").Index Then
    e.FormattingApplied = True
    Dim _row = gv.Rows(e.RowIndex)
    Dim _cell As New DataGridViewComboBoxColumn
    fillGPFieldList(_cell)
    _cell.DisplayIndex = 1
    _cell.DisplayMember = "Credit"
    _cell.ValueMember = "Credit"
    _cell.DataSource = _cell.Items
    e.Value = _cell

End If
If e.ColumnIndex = gv.Columns("TrxType").Index Then
    e.FormattingApplied = True
    e.Value = "BAL"
End If

The Gridview displays the dropdown object just fine, its just always set to index -1.

Please help

V*********** Addendum Edit ***********V

Unfortunately, no one answered my question. So I worked around the entire problem. Its ugly and I would greatly appreciate any feedback.

I was never able to get the ComboBox to bind to the data source. I tried everything until I turned blue. So I went to the basics and coded all the automatic stuff. I'm curious as to why the automatic binding didn't work. Perhaps its because my gridview datasource was LINQ.

Here is how I pulled it off. I hope someone down the road benefits from the last 48 hours of my delima:

First of all, know that I have two drop down lists on my form, one is the GPField and the other is the BankField. These are already populated DDLs that are static. So I used them to cheat on the values instead of using enums.

I don't think it matters, but here is how I fill the GPField and BankField:

      Sub fillGPFieldListDDL(ByVal obj As Object)
            Dim db As New CompanyDataDataContext
            Dim myConn As New Connection With {.ConnCls = ConnCls}
            myConn.dbConnect(db)
            'Setup the GP Field list
            obj.Items.Clear()
            For Each fld In db.getGPFieldList(Me.ddlImportID.SelectedItem, ddlImportTypes.BNKREC_IMPORTS_WORK)
                obj.Items.Add(fld.Trim)
            Next
            db.Connection.Close()
            db.Connection.Dispose()
            db.Dispose()
        End Sub
        Sub fillBankFieldListDDL(ByVal obj As Object)
            If String.IsNullOrEmpty(ddlImportID.Text) Then
                Return
            End If
            Dim db As New CompanyDataDataContext
            Dim myConn As New Connection With {.ConnCls = ConnCls}
            myConn.dbConnect(db)
            'Setup the Bank Field list
            obj.Items.Clear()
            For Each fld In db.getImportIDVirtualFields(Me.ddlImportID.Text, ddlImportTypes.BNKREC_IMPORTS_WORK)
                obj.Items.Add(fld.Trim)
            Next
            db.Connection.Close()
            db.Connection.Dispose()
            db.Dispose()
        End Sub

Next, based on a selection from the user, I populate my grid with the following function:

    Function fillToleranceFieldsGridView(ByVal nTrxType As String) As Integer
    Dim myConn As New Connection With {.ConnCls = ConnCls}
    Try
        Using db As New CompanyDataDataContext
            myConn.dbConnect(db)
            'Dim _query As IEnumerable(Of TWO_Tolerance_Field) = (From tf In db.getToleranceSetupRecordFields(nTrxType, BankToleranceRecordTypes.MasterRecord) _
            '             Select tf)
            'Dim _query2 As IEnumerable(Of TWO_Tolerance_Field) = db.getToleranceSetupRecordFields(nTrxType, BankToleranceRecordTypes.MasterRecord)
            Dim _query3 = (From t In db.TWO_Tolerance_Fields _
                           Where t.TRXTYPESTRING = nTrxType And t.RCRDTYPE = BankToleranceRecordTypes.MasterRecord _
                           Select t.Bank_Bank_Field_Number, t.Bank_GP_Field_Name, t.TRXTYPESTRING)

            Dim gv = Me.DataGridViewX1
            gv.AutoGenerateColumns = False
            gv.AllowUserToAddRows = False
            gv.AllowUserToDeleteRows = False
            gv.AllowUserToResizeRows = False
            gv.AutoSize = True
            gv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells

            'gv.DataSource = _query3

            If Not Me.GridViewIsConstructed Then

                'Add in the combo box for GPField Names
                Dim _comboCol As DataGridViewComboBoxColumn
                _comboCol = CreateComboBoxColumn(Me.ddlGPField.Items, _
                                                 ColumnNameData.Bank_GP_Field_Name.ToString, _
                                                 FieldNames.GPField.ToString)

                gv.Columns.Add(_comboCol)

                _comboCol = CreateComboBoxColumn(Me.ddlBankField.Items, _
                                                  ColumnNameData.Bank_Bank_Field_Number.ToString, _
                                                  FieldNames.BankField.ToString)

                gv.Columns.Add(_comboCol)

                Dim col As DataGridViewColumn = _
                    New DataGridViewTextBoxColumn()

                Dim _cell = New DataGridViewTextBoxCell
                Dim _coll = New DataGridViewColumn(_cell)
                Dim _colIndex As Integer = 0

                ''Bind to an existing column Left in for easy access for a simple text box
                '_coll = New DataGridViewColumn(_cell)
                '_coll.Name = ColumnNameData.Bank_GP_Field_Name.ToString
                '_coll.ReadOnly = True
                '_coll.HeaderText = ColumnNameData.Bank_GP_Field_Name.ToString
                '_colIndex = gv.Columns.Add(_coll)
                'gv.Columns(_colIndex).DataPropertyName = ColumnNameData.Bank_GP_Field_Name.ToString

                Me.GridViewIsConstructed = True
            End If

            gv.Rows.Clear()
            Dim ri As Integer = 0
            For Each r In _query3
                Dim _row As New DataGridViewRow
                _row.CreateCells(gv)
                _row.Cells(FieldNames.GPField).Value = r.Bank_GP_Field_Name.ToString.Trim
                _row.Cells(FieldNames.BankField).Value = ddlBankField.Items(r.Bank_Bank_Field_Number - 1).ToString.Trim
                gv.Rows.Add(_row)
                ri += 1
            Next
            db.Connection.Close()
            db.Connection.Dispose()
        End Using
        Return 0
    Catch ex As Exception
        Throw ex
    Finally
        myConn.Dispose()
    End Try
End Function

So, the unanswered questions are: 1). I couldn't use the _query or _query2 as datasources for the gridview, but _query3 did work for simple textboxes. 2). If using _query3 as the gv.datasource, why would my combobox throw "bank_gp_field_name" not found error when the gv.Columns.Add(_comboCol) was executed 3). I understand the reason I couldn't do a gv bind to _query3 because of the data in Bank_Bank_field_number is an integer and the DDL values don't have a translation between the integer and the string value. But I commented out that field expecting the GPField to operate on a standard bind. I still got the "Field called "Bank_GP_Field_Name" does not exist on gv.Columns.Add(_comboCol)

So, summed up, why doesn't the code below work whereas the one above does?

    Function fillToleranceFieldsGridView(ByVal nTrxType As String) As Integer
    Dim myConn As New Connection With {.ConnCls = ConnCls}
    Try
        Using db As New CompanyDataDataContext
            myConn.dbConnect(db)
            'Dim _query As IEnumerable(Of TWO_Tolerance_Field) = (From tf In db.getToleranceSetupRecordFields(nTrxType, BankToleranceRecordTypes.MasterRecord) _
            '             Select tf)
            'Dim _query2 As IEnumerable(Of TWO_Tolerance_Field) = db.getToleranceSetupRecordFields(nTrxType, BankToleranceRecordTypes.MasterRecord)
            Dim _query3 = (From t In db.TWO_Tolerance_Fields _
                           Where t.TRXTYPESTRING = nTrxType And t.RCRDTYPE = BankToleranceRecordTypes.MasterRecord _
                           Select t.Bank_Bank_Field_Number, t.Bank_GP_Field_Name, t.TRXTYPESTRING)

            Dim gv = Me.DataGridViewX1
            gv.AutoGenerateColumns = False
            gv.AllowUserToAddRows = False
            gv.AllowUserToDeleteRows = False
            gv.AllowUserToResizeRows = False
            gv.AutoSize = True
            gv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells

            gv.DataSource = _query3

            If Not Me.GridViewIsConstructed Then

                'Add in the combo box for GPField Names
                Dim _comboCol As DataGridViewComboBoxColumn
                _comboCol = CreateComboBoxColumn(Me.ddlGPField.Items, _
                                                 ColumnNameData.Bank_GP_Field_Name.ToString, _
                                                 FieldNames.GPField.ToString)

                gv.Columns.Add(_comboCol)

                '_comboCol = CreateComboBoxColumn(Me.ddlBankField.Items, _
                '                                  ColumnNameData.Bank_Bank_Field_Number.ToString, _
                '                                  FieldNames.BankField.ToString)

                'gv.Columns.Add(_comboCol)

                Dim col As DataGridViewColumn = _
                    New DataGridViewTextBoxColumn()

                Dim _cell = New DataGridViewTextBoxCell
                Dim _coll = New DataGridViewColumn(_cell)
                Dim _colIndex As Integer = 0

                ''Bind to an existing column Left in for easy access for a simple text box
                '_coll = New DataGridViewColumn(_cell)
                '_coll.Name = ColumnNameData.Bank_GP_Field_Name.ToString
                '_coll.ReadOnly = True
                '_coll.HeaderText = ColumnNameData.Bank_GP_Field_Name.ToString
                '_colIndex = gv.Columns.Add(_coll)
                'gv.Columns(_colIndex).DataPropertyName = ColumnNameData.Bank_GP_Field_Name.ToString

                Me.GridViewIsConstructed = True
            End If

            'gv.Rows.Clear()
            'Dim ri As Integer = 0
            'For Each r In _query3
            '    Dim _row As New DataGridViewRow
            '    _row.CreateCells(gv)
            '    _row.Cells(FieldNames.GPField).Value = r.Bank_GP_Field_Name.ToString.Trim
            '    _row.Cells(FieldNames.BankField).Value = ddlBankField.Items(r.Bank_Bank_Field_Number - 1).ToString.Trim
            '    gv.Rows.Add(_row)
            '    ri += 1
            'Next
            db.Connection.Close()
            db.Connection.Dispose()
        End Using
        Return 0
    Catch ex As Exception
        Throw ex
    Finally
        myConn.Dispose()
    End Try
End Function

Private Function CreateComboBoxColumn(ByVal obj As ComboBox.ObjectCollection, ByVal nDataFieldName As String, ByVal nColName As String) _
 As DataGridViewComboBoxColumn

    Dim column As New DataGridViewComboBoxColumn()
    With (column)
        .HeaderText = nColName
        .DropDownWidth = 160
        .Width = 90
        .MaxDropDownItems = 3
        .FlatStyle = FlatStyle.Flat
        .DataSource = obj
        .DataPropertyName = nDataFieldName
        .Name = nColName
        .ValueMember = nDataFieldName
        .DisplayMember = .ValueMember
    End With
    Return column
End Function
gkowieski
  • 31
  • 1
  • 3

1 Answers1

0

Sorry if I've misunderstood or over simplified this but from what I gather the combox is binding fine you just cant set the index to 1? Is this because there is no underlying data for that cell?

Have you tried setting the default value of the column? From what I've read DataGridViewComboBoxColumn doesn't have a cell DefaultValue but works with column default.

Columns("ColumName").DefaultValue = 1

http://msdn.microsoft.com/en-us/library/system.data.datacolumn.defaultvalue.aspx

You could also try handling DefaultValuesNeeded

Private Sub gv_DefaultValuesNeeded(ByVal sender As Object, _
    ByVal e As System.Windows.Forms.DataGridViewRowEventArgs) _
    Handles gv.DefaultValuesNeeded

    With e.Row
        .Cells("GPField") = 1
        .Cells("BankField") = 1
    End With 

End Sub

http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.defaultvaluesneeded(v=vs.110).aspx

GJKH
  • 1,715
  • 13
  • 30