Set selectedindex for comboboxcell in datagridview vb.net - vb.net

I am trying to set the selectedindex for my datagridviewcomboboxcell through cellvaluechanged event,i.e when i change some value in my datagrid row, this column should get automatically changed. here's the code.
Private Sub DataGridView1_CellValueChanged(sender As Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellValueChanged
Try
If Me.DataGridView1.Rows(e.RowIndex).Cells(2).Value.ToString <> Nothing Then
Me.DataGridView1("unit_code", e.RowIndex).Value = "1"
MsgBox(Me.DataGridView1.Rows(e.RowIndex).Cells(6).Value)
End If
Else
Exit Sub
End If
End If
Catch ex As Exception
MessageBox.Show(ex.Message, "Message", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
my datagridview is bound to dataset. Searched many sites and did all research, got the above solution where we need to set the valuemember to .value part. Even after doing that it givessystem.formatexception:datagridviewcomboboxcell value is not valid.
Please help me.
[EDIT]
table structure
unit_code descp
0 -
1 nos
2 kgs
3 gms
[EDIT 2]
query = "select Switch(qty=0,'2',qty<=rcvd_qty,'1',rcvd_qty=0,'2',qty>rcvd_qty,'3') as Status,item_type,catalogue,name,pd.rate,qty,pd.unit_code" _
& " from pur_det pd,itemhead th where pd.item_code=th.itemcode and order_no=0 order by catalogue"
adap1 = New OleDbDataAdapter(query, conn)
Dim saldet As New DataSet
adap1.Fill(saldet, "puritems")
Me.DataGridView1.DataSource = saldet.Tables(0)
DataGridView1.Columns.Item(0).HeaderText = "STATUS"
DataGridView1.Columns.Item(0).Width = 68
DataGridView1.Columns.Item(1).HeaderText = "TYPE"
DataGridView1.Columns.Item(1).Width = 60
DataGridView1.Columns.Item(2).HeaderText = "CATALOGUE"
DataGridView1.Columns.Item(2).Width = 140
DataGridView1.Columns.Item(3).HeaderText = "DESCRIPTION"
DataGridView1.Columns.Item(3).Width = 300
DataGridView1.Columns.Item(4).HeaderText = "RATE"
DataGridView1.Columns.Item(4).Width = 60
DataGridView1.Columns.Item(5).HeaderText = "QUANTITY"
DataGridView1.Columns.Item(5).Width = 84
DataGridView1.Columns.Item(6).HeaderText = "UNIT" ' this column is removed below because it only had primary key values of this table("unitmast").
DataGridView1.Columns.Item(6).Width = 70
adap1 = New OleDbDataAdapter("select * from unitmast order by unitcode ASC", conn)
Dim unitc As New DataSet
adap1.Fill(unitc, "unitmast")
Me.DataGridView1.Columns.RemoveAt(6) 'here the same is added with display member to view its actual value
Dim uncol As New DataGridViewComboBoxColumn
With uncol
.Name = "unit_code"
.DataPropertyName = "unit_code"
.DataSource = unitc.Tables(0)
.ValueMember = "unitcode"
.DisplayMember = "desc"
.HeaderText = "UNIT"
.FlatStyle = FlatStyle.Flat
.DropDownWidth = 160
.Width = 70
End With
Me.DataGridView1.Columns.Insert(6, uncol)

A DataGridViewComboBoxCell has no SelectedIndex or SelectedValue property.
You can set the value directly like this:
CType(Me.DataGridView1("unit_code", e.RowIndex), DataGridViewComboBoxCell).Value = "your value string"
Or using the index of the items collection: (this works only if you have not set ValueMember and DisplayMember properties)
Dim combo As DataGridViewComboBoxCell
combo = CType(Me.DataGridView1("unit_code", e.RowIndex), DataGridViewComboBoxCell)
combo.Value = combo.Items('your index')
You can also check a value for nothing like this:
If Not Me.DataGridView1.Rows(e.RowIndex).Cells(2).Value Is Nothing Then
'Your code
End If

I Write and Test that Code For You Good Luck:
Dim Dt As New DataTable
Sub CreateDT()
Dt.Columns.Add("Col1")
Dt.Columns.Add("Col2")
Dt.Rows.Add(New Object(1) {"1", "A"})
Dt.Rows.Add(New Object(1) {"2", "B"})
Dt.Rows.Add(New Object(1) {"3", "C"})
End Sub
Private Sub ChildRibbonForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
CreateDT()
'
'Dim CellCol As DataGridViewComboBoxColumn = CType(DataGridView1.Columns(0), DataGridViewComboBoxColumn)
Dim CellCol As New DataGridViewComboBoxColumn
CellCol.Items.Add("Test1")
CellCol.Items.Add("Test2")
CellCol.Items.Add("Test3")
Me.DataGridView1.DataSource = Dt
Me.DataGridView1.Columns.Insert(0, CellCol)
Dim CellBox As DataGridViewComboBoxCell = CType(DataGridView1.Rows(1).Cells(0), DataGridViewComboBoxCell)
'Select the Second Item
CellBox.Value = CellCol.Items(1)
End Sub

'Declare datatable
Dim cdt as new Datatable
'Add columns with types. It is important you specify the type for value member column
cdt.Columns.Add("vm", System.Type.GetType("System.Int32"))
cdt.Columns.Add("dm", System.Type.GetType("System.String"))
'Add items to table
cdt.Rows.Add
cdt.Rows(0).Item(0) = 1
cdt.Rows(0).Item(1) = "Red Cat"
cdt.Rows.Add
cdt.Rows(1).Item(0) = 2
cdt.Rows(1).Item(1) = "Black Cat"
'Add datasource to DataGridViewComboBoxColumn
Dim cc As DataGridViewComboBoxColumn
cc = datagridview1.Columns('colIndex')
cc.DataSource = cdt
cc.ValueMember = "vm"
cc.DisplayMember = "dm"
'Setting then selected value is thus:
Datagridview1.Rows('rowIndex').Cells('colIndex').Value = 2 '2 for black cat
This works for me

Related

Display image from filename in a database record to a datagridview

I want to display the picture found in the file location that is in the field "Picture" I have this code that shows the fields in the datagridview but I cannot figure how to properly code image from file.
Update - this below code works fine
enter code here
Imports System.Data.OleDb
Public Class test
Dim ds As New DataSet
Dim dt As New DataTable
Dim da As New OleDbDataAdapter
Private Sub test_Load(sender As Object, e As EventArgs) Handles MyBase.Load
getthedata() ' this does a query and adds a column to the query data datatable
Filldatagrid() ' This fills the datagridview named DG1
End Sub
Sub getthedata()
sel = "select * from dog"
DataConnection()
cmd = New OleDbCommand(sel, con)
ds.Tables.Add(dt)
da = New OleDbDataAdapter(cmd)
da.Fill(dt)
Dim imageColumn As New DataColumn
imageColumn.ColumnName = "Picture"
imageColumn.DataType = GetType(System.Drawing.Image)
dt.Columns.Add(imageColumn)
For Each row As DataRow In dt.Rows
row("Picture") = System.Drawing.Image.FromFile(row("pic"))
Next
dt.AcceptChanges()
con.Close()
End Sub
Sub Filldatagrid()
dg1.AutoGenerateColumns = False
dg1.RowTemplate.Height = 150 ' this is the larger size to accomodate the image
dg1.ColumnCount = 4
dg1.DataSource = dt
dg1.Columns(0).DataPropertyName = "ID"
dg1.Columns(0).Visible = False
dg1.Columns(1).HeaderText = "Name"
dg1.Columns(1).DefaultCellStyle.Font = New Font("Tahoma", 15)
dg1.Columns(1).DefaultCellStyle.ForeColor = Color.DarkGreen
dg1.Columns(1).DataPropertyName = "Nam"
dg1.Columns(1).Width = 100
dg1.Columns(2).HeaderText = "Birthday"
dg1.Columns(2).DefaultCellStyle.Font = New Font("Tahoma", 15)
dg1.Columns(2).DataPropertyName = "Birth"
dg1.Columns(2).Width = 150
dg1.Columns(3).DataPropertyName = "Pic"
dg1.Columns(3).Visible = False
Dim dgvImageColumn As New DataGridViewImageColumn
dgvImageColumn.DataPropertyName = "Picture"
dgvImageColumn.Width = 150
dgvImageColumn.ImageLayout = DataGridViewImageCellLayout.Zoom
dg1.Columns.Add(dgvImageColumn)
End Sub
End Class
The database records are:
Id Nam Birth Pic Comments
1 Brody 5/15/2015 C:\Users\JRS89\Dropbox\Photos\dogs\Brody\Brody.jpg
2 Bella 5/1/2015 C:\Users\JRS89\Dropbox\Photos\dogs\Bella\Bella.jpg
3 Benji 5/15/2016 C:\Users\JRS89\Dropbox\Photos\dogs\Benji\Benji.jpg

DataGridView Yes No ComboBox Column

I have what on the face of it seems a pretty simple requirement, I need an unbound combobox column to hold an option list of 'Yes' and 'No'. In combobox parlance Yes and No are the DisplayMembers corresponding to ValueMembers 1 and 0 respectively which in turn are the values held in the field of the database table. I use bound combobox columns in the application extensively and am very familiar with building them, but can't for the hell of me work out how to incorporate this simple list functionality in the datagridview application. Could somebody please put me out of my misery with some sample code.
Thanks for your feedback Plutonix. The DGV is bound to an underlying table. Hopefully, the following code should give you some idea of what I am attempting to acheive. The code specifically relevant to this post is in the call to PopulateUnboundComboBox(comboBoxCol, {"Yes", "No"}).
Private Sub GetData()
Const procName As String = "GetData()"
Dim myValue As String = ""
Dim myDataSource As Integer = 0
Try
'First clear the existing grid
With Me.uxGrid
If .ColumnCount > 0 Then
'clear the grid
ClearGrid(Me.uxGrid)
End If
End With
_Logger.SendLog(Me.Name & "." & procName & " - Fetching device data.", NLog.LogLevel.Trace)
'Get the data from the database
If Not _dataSourceID = 0 Then
_sqlStatement = "SELECT ID, TEXT, CATEGORY, MOUNTING, DATASOURCEID, TANALYSIS" & _
" FROM P_TBL_DEVICE WHERE DATASOURCEID = " & _dataSourceID
_criteria = "WHERE DATASOURCEID = " & _dataSourceID
Else
_sqlStatement = ""
_criteria = ""
End If
_myDeviceMngr = New DeviceManager(_currentDB, _userName, _myPwd)
'Now get the latest data
_myDataSet = _myDeviceMngr.GetData(_sqlStatement)
_Logger.SendLog(Me.Name & "." & procName & " - Device data fetch completed.", NLog.LogLevel.Trace)
'Update the display
Call BuildGrid(_myDataSet, uxGrid)
Catch ex As Exception
Beep()
MsgBox(ex.Message, MsgBoxStyle.Exclamation, System.Windows.Forms.Application.ProductName)
_Logger.SendLog(ex.Message & ". Thrown in module " & Me.Name.ToString & "." & procName, NLog.LogLevel.Error, ex)
Finally
Call System.GC.Collect()
End Try
End Sub
Private Sub BuildGrid(ByVal myDataSet As DataSet, ByVal myGrid As DataGridView)
Dim myTable As New System.Data.DataTable
Dim myColCount As Integer
Dim comboBoxCol As DataGridViewComboBoxColumn
Dim readOnlyCellStyle As New DataGridViewCellStyle
Dim textBoxCol As DataGridViewTextBoxColumn
Dim gridObject As Object = Nothing
Const procName As String = "BuildGrid"
readOnlyCellStyle.ForeColor = Color.Gray
Try
_Logger.SendLog(Me.Name & "." & procName & " - Building device data grid.", NLog.LogLevel.Trace, Nothing)
myTable = myDataSet.Tables(0)
With myGrid
'Now add the columns to the grid
Dim column As System.Data.DataColumn
For Each column In myDataSet.Tables(0).Columns
'We dont want to include the changedon and changedby fields in the grid build
If column.ColumnName.IndexOf("CHANGED") = -1 Then
Select Case column.ColumnName
Case "DATASOURCEID"
gridObject = New Object
comboBoxCol = New DataGridViewComboBoxColumn
'First create the comboboxcolumn for the column
'Populate combobox
PopulateScadaSourceComboBoxCol(comboBoxCol)
comboBoxCol.DataPropertyName = "DATASOURCEID"
comboBoxCol.HeaderText = "SCADA SOURCE"
comboBoxCol.AutoSizeMode = DataGridViewAutoSizeColumnsMode.AllCells
comboBoxCol.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing
gridObject = comboBoxCol
Case "TEXT"
textBoxCol = New DataGridViewTextBoxColumn
gridObject = textBoxCol
'Now add the columns to the grid
gridObject.DataPropertyName = column.ColumnName.ToString
gridObject.HeaderText = column.ColumnName.Replace("TEXT", "DEVICE")
gridObject.name = column.ColumnName.Replace("TEXT", "DEVICE")
gridObject.AutoSizeMode = DataGridViewAutoSizeColumnsMode.AllCells
Case "CATEGORY"
textBoxCol = New DataGridViewTextBoxColumn
gridObject = textBoxCol
'Now add the columns to the grid
gridObject.DataPropertyName = column.ColumnName.ToString
gridObject.HeaderText = "CATEGORY"
gridObject.name = "CATEGORY"
gridObject.AutoSizeMode = DataGridViewAutoSizeColumnsMode.AllCells
Case "MOUNTING"
textBoxCol = New DataGridViewTextBoxColumn
gridObject = textBoxCol
'Now add the columns to the grid
gridObject.DataPropertyName = column.ColumnName.ToString
gridObject.HeaderText = "MOUNTING"
gridObject.name = "MOUNTING"
gridObject.AutoSizeMode = DataGridViewAutoSizeColumnsMode.AllCells
Case "TANALYSIS"
comboBoxCol = New DataGridViewComboBoxColumn
'First create the comboboxcolumn for the column
'Populate combobox
PopulateUnboundComboBox(comboBoxCol, {"Yes", "No"})
comboBoxCol.DataPropertyName = "TANALYSIS"
comboBoxCol.HeaderText = "TELECONTROL ANALYSIS"
comboBoxCol.AutoSizeMode = DataGridViewAutoSizeColumnsMode.AllCells
comboBoxCol.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing
gridObject = comboBoxCol
Case Else
textBoxCol = New DataGridViewTextBoxColumn
gridObject = textBoxCol
'Now add the columns to the grid
gridObject.DataPropertyName = column.ColumnName.ToString
gridObject.HeaderText = "ID"
gridObject.name = "ID"
gridObject.AutoSizeMode = DataGridViewAutoSizeColumnsMode.AllCells
End Select
'Now add the textbox columns to the grid
'gridObject.DataPropertyName = column.ColumnName.ToString
'gridObject.AutoSizeMode = DataGridViewAutoSizeColumnsMode.AllCells
.Columns.Add(gridObject)
End If
Next
'Set grid default styles/values
.Font = New System.Drawing.Font("Arial", 10, FontStyle.Regular)
.AllowUserToResizeColumns = True
.AllowUserToResizeRows = True
.AllowUserToAddRows = True
.ReadOnly = True
.AutoResizeRows()
.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText
'Now bind the datatable to the DGV datasource property
.DataSource = myTable
End With
_Logger.SendLog(Me.Name & "." & procName & " - Building of device data grid has been completed.", NLog.LogLevel.Trace, Nothing)
Catch ex As Exception
Throw
Finally
textBoxCol = Nothing
comboBoxCol = Nothing
readOnlyCellStyle = Nothing
GC.Collect()
End Try
End Sub
Private Sub PopulateUnboundComboBox(ByVal comboBoxCol As DataGridViewComboBoxColumn, byval valList() as string)
comboBoxCol.Name = "TANALYSIS"
comboBoxCol.DataSource = valList
comboBoxCol.ValueMember = ???
comboBoxCol.DisplayMember = ???
End Sub
EDITED//
Ok, I've made some progress and seem to have almost solved my issue. The one remaining bug is that the column in the DGV is displaying the 'ValueMember' (1 or 0) rather than the 'DisplayMember' (Yes or No). I've checked the valuemember and displaymember properties in the comboboxcolumn definition and and they appear to be set correctly. Here is the associated code:
Excerpt from original code posting listed above
...
Case "TANALYSIS"
gridObject = New Object
comboBoxCol = New DataGridViewComboBoxColumn
'First create the comboboxcolumn for the column
'Populate combobox
Dim item As New CBOItem
Dim itemList As New CBOItemList
item.ValueMember = 0
item.DisplayMember = "No"
itemList.Add(item)
item = New CBOItem
item.ValueMember = 1
item.DisplayMember = "Yes"
itemList.Add(item)
PopulateComboBox(comboBoxCol, itemList)
comboBoxCol.DataPropertyName = "TANALYSIS"
comboBoxCol.HeaderText = "TELECONTROL ANALYSIS"
comboBoxCol.AutoSizeMode = DataGridViewAutoSizeColumnsMode.AllCells
comboBoxCol.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing
gridObject = comboBoxCol
...
Private Sub PopulateComboBox(ByRef comboBoxCol As DataGridViewComboBoxColumn, ByVal itemList As CBOItemList)
Dim tbl As DataTable = New DataTable
Dim row As DataRow
tbl.Columns.Add("ValueMember")
tbl.Columns.Add("DisplayMember")
row = tbl.NewRow
row.Item("ValueMember") = itemList(0).ValueMember
row.Item("DisplayMember") = itemList(0).DisplayMember
tbl.Rows.Add(row)
row = tbl.NewRow
row.Item("ValueMember") = itemList(1).ValueMember
row.Item("DisplayMember") = itemList(1).DisplayMember
tbl.Rows.Add(row)
comboBoxCol.ValueMember = tbl.Columns("ValueMember").ToString
comboBoxCol.DisplayMember = tbl.Columns("DisplayMember").ToString
comboBoxCol.DataSource = tbl
End Sub
Kind Regards
Paul J.

Highlight a row in Datagridview based on textbox value

Good Evening.
I have a program in VB.Net that refreshes datagridview after you edit some data my problem here is im populating over 1000 records.
Let say Im editing row 999 and after i click update the data will refresh causing the datagridview to return at the top (The blue highlighter)
My goal here is how can I maintain it to its current position after update?
My solution here is highlight the data where Textbox1 = value
Is this possible like this?
'SAMPLE CODE
Datagridview1.Column(0).value.BlueHighLighter = Textbox1.text
Pls see my code on how i refresh DGV
Dim con11 As MySqlConnection = New MySqlConnection("server=192.168.2.87;userid=root;password=admin1950;database=inventory")
Dim sql1 As MySqlCommand = New MySqlCommand("select PONo,ItemCode,Description,QtyPack,PackUoM,QtyStan,StanUoM,UnitPrice,Total,Remarks,ExpiryDate from Receiving where RINo = '" & Add_Receiving_Items.TextBox1.Text & "';", con1)
Dim ds1 As DataSet = New DataSet
Dim adapter1 As MySqlDataAdapter = New MySqlDataAdapter
con1.Open()
adapter1.SelectCommand = sql1
adapter1.Fill(ds1, "MyTable")
Add_Receiving_Items.DataGridView1.DataSource = ds1.Tables(0)
con1.close()
With Add_Receiving_Items.DataGridView1()
.RowHeadersVisible = False
.Columns(0).HeaderCell.Value = "PO No"
.Columns(1).HeaderCell.Value = "Item Code"
.Columns(2).HeaderCell.Value = "Description"
.Columns(3).HeaderCell.Value = "Quantity/Pack"
.Columns(4).HeaderCell.Value = "Packaging UoM"
.Columns(5).HeaderCell.Value = "Quantity/Pc"
.Columns(6).HeaderCell.Value = "Standard UoM"
.Columns(7).HeaderCell.Value = "Unit Price"
.Columns(8).HeaderCell.Value = "Total"
.Columns(9).HeaderCell.Value = "Remarks"
.Columns(10).HeaderCell.Value = "Expiry Date"
End With
Add_Receiving_Items.DataGridView1.Columns.Item(0).Width = 80
Add_Receiving_Items.DataGridView1.Columns.Item(1).Width = 80
Add_Receiving_Items.DataGridView1.Columns.Item(2).Width = 120
Add_Receiving_Items.DataGridView1.Columns.Item(3).Width = 86
Add_Receiving_Items.DataGridView1.Columns.Item(4).Width = 68
Add_Receiving_Items.DataGridView1.Columns.Item(5).Width = 75
Add_Receiving_Items.DataGridView1.Columns.Item(6).Width = 68
Add_Receiving_Items.DataGridView1.Columns.Item(7).Width = 70
Add_Receiving_Items.DataGridView1.Columns.Item(8).Width = 80
Add_Receiving_Items.DataGridView1.Columns.Item(9).Width = 105
Add_Receiving_Items.DataGridView1.Columns.Item(10).Width = 63
Add_Receiving_Items.DataGridView1.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.BottomCenter
Add_Receiving_Items.DataGridView1.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.BottomCenter
With Add_Receiving_Items.DataGridView1
.RowsDefaultCellStyle.BackColor = Color.WhiteSmoke
.AlternatingRowsDefaultCellStyle.BackColor = Color.Lavender
End With
TYSM for future help
Use DataGridView.CurrentRow property. But please be aware that CurrentRow is ReadOnly, you must use CurrentCell
Before refreshing your data store Dim oldIndex = DataGridView.CurrentRow.Index and after the refresh set DataGridView.CurrentCell = DataGridView.Rows(oldIndex).Cells(0)
EDIT:
How to test the Code
Create a form with a Button1 and a DataGridView1 with two columns and paste the following code:
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
For i = 1 To 5
DataGridView1.Rows.Add("foo" & i, "bar" & i)
Next
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim currentIndex = DataGridView1.CurrentRow.Index
currentIndex += 1
If currentIndex >= DataGridView1.Rows.Count Then currentIndex = 0
DataGridView1.CurrentCell = DataGridView1.Rows(currentIndex).Cells(0)
End Sub
End Class
EDIT:
Dim oldIndex = DataGridView.CurrentRow.Index
'Put your code here on how you refresh your data
DataGridView.CurrentCell = DataGridView.Rows(oldIndex).Cells(0)

Set DataGridViewComboBoxColumn Value Based on a Datatable

I read several article relating to setting the value of a combobox however I still couldn't come up with a solution.
Below is a basic example of what I want to do and in the comments is exactly what I want to do. Any help is appreciated.
Public Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim dt As New DataTable
dt.Columns.Add("ID")
dt.Columns.Add("Name")
dt.Columns.Add("Value")
dt.Columns(0).AutoIncrement = True
For i As Integer = 0 To 20
Dim R As DataRow = dt.NewRow
R("Name") = "Test" & Date.Now & "" & i
If i = 2 Or i = 5 Or i = 6 Or i = 8 Or i = 10 Then
R("Value") = "yes"
Else
R("Value") = "no"
End If
dt.Rows.Add(R)
DataGridView1.DataSource = dt
Next
DataGridView1.ReadOnly = False
Dim cmb As New DataGridViewComboBoxColumn()
cmb.HeaderText = "Select Data"
cmb.Name = "cmb"
cmb.MaxDropDownItems = 2
cmb.Items.Add("True")
cmb.Items.Add("False")
DataGridView1.Columns.Add(cmb)
For Each dr As DataRow In dt.Rows
If dr("Name").ToString = "Test" Then
'set the combo box value to True
Else
'set the combobox value to False
End If
Next
End Sub
You can set the value by setting the Cells.Value...
DataGridView1.Rows(whatrowdoyouwant).Cells("cmb").Value = True
On another note, you set the DataSource to the DataGridView, but loop through the DataTable. If you want to set each row in the DataGridView this wont work.
For Each dr As DataRow In dt.Rows
If dr("Name").ToString = "Test" Then
'set the combo box value to True
Else
'set the combobox value to False
End If
Next
You would need to loop through each DataGridViewRow in the DataGridView and set the ComboBox value. For example...
For i As Integer = 0 To DataGridView1.Rows.Count - 1
If DataGridView1.Rows(i).Cells("Name").Value.ToString = "Test" Then
DataGridView1.Rows(i).Cells("cmb").Value = True
Else
DataGridView1.Rows(i).Cells("cmb").Value = False
End If
Next

Need to populate a Dropdown combo box in Gridview, (unbound column)

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
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