title: Need to populate a Dropdown combo box in Gridview, (unbound column)
body: <p>I'm having difficulty populating a dropdown list in my gridview.
  I have created the column with the code below:</p>
  
  <pre><code>  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
  </code></pre>
  
  <p>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.</p>
  
  <pre><code>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
  </code></pre>
  
  <p>The Gridview displays the dropdown object just fine, its just always set to index -1.</p>
  
  <p>Please help</p>
  
  <p>V*<strong><em>*</em>**<em>*</em>**<em>*</em>***<em></strong>  Addendum Edit <strong></em>**<em>*</em>**<em>*</em>****</strong>*V</p>
  
  <p>Unfortunately, no one answered my question.  So I worked around the entire problem.  Its ugly and I would greatly appreciate any feedback.</p>
  
  <p>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.</p>
  
  <p>Here is how I pulled it off.  I hope someone down the road benefits from the last 48 hours of my delima:</p>
  
  <p>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.</p>
  
  <p>I don't think it matters, but here is how I fill the GPField and BankField:</p>
  
  <pre><code>      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
  </code></pre>
  
  <p>Next, based on a selection from the user, I populate my grid with the following function:</p>
  
  <pre><code>    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
  </code></pre>
  
  <p>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)</p>
  
  <p>So, summed up, why doesn't the code below work whereas the one above does?</p>
  
  <pre><code>    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
  </code></pre>