VB.NET How to add Event Handler to ComboBoxColumn located in programmatically created controls? - vb.net

I've got part of my code that creates a tab in a tabcontrol, and then fills it with a datagridview which contains a couple columns that are DataGridViewComboBoxColumn.
It looks like this:
Private Sub NewTabPage()
Dim TabPageCount As Integer = RacerOrderTAB.TabPages.Count
RacerOrderTAB.TabPages.Add(TeamNames(TabPageCount)) 'teamnames() is an array of team names
Dim CurrentTabPage = RacerOrderTAB.TabPages(TabPageCount)
Dim GridToAdd As New DataGridView
GridToAdd.Size = CurrentTabPage.Size
GridToAdd.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
GridToAdd.Location = New Point(CurrentTabPage.Location.X, CurrentTabPage.Location.Y)
GridToAdd.Columns.Add("ShiftCOL", "Shift Name")
GridToAdd.Name = "grid_" & CurrentTabPage.Text
For y As Integer = 1 To ShiftSetup.racerspershift 'add extra column for each racer in shift
Dim cmb As New DataGridViewComboBoxColumn
cmb.HeaderText = "Racer" & y
cmb.Name = "Racer_" & y
cmb.MaxDropDownItems = AmountOfRacers
cmb.DisplayStyle = DataGridViewComboBoxDisplayStyle.DropDownButton
GridToAdd.Columns.Add(cmb)
Next
RacerOrderTAB.TabPages(TabPageCount).Controls.Add(GridToAdd)
End Sub
But I've been having difficulty in adding an eventhandler for the comboboxes. What I want to happen is that when a combobox is clicked and opened, I populate it with the items I want.
I managed to vaguely get it working by adding:
AddHandler GridToAdd.EditingControlShowing, AddressOf <sub name>
but then have been unable to figure out which combobox was clicked, and how to populate it. It's also been requiring like four clicks before the drop list will appear. I'm only slightly very confused.
Thanks for any advice; these DataGridViewComboBoxColumns [deep breath] have been confusing me a lot!

It may be a little hacky but it should do what you are asking… hopefully. I created two List(Of String) variables. AllRacers contains all the racers… i.e. all the names we want to appear in a combo box such that there is no other combo box on that row that has an item selected. These names are what all combo boxes on all rows would initially contain in the selectable items list.
The other List(Of String) UsedRacers contains a list of all the “comboboxes” on the current row that have selected items. Each time a cell value is changed and it is one of the “combobox” column cells, then UsedRacers is cleared/updated to reflect the added/changed selected item on the current row.
When a “comboBox” cell value is changed, SetUsedRacersForRow is called…
Private Sub SetUsedRacersForRow(rowIndex As Int16)
UsedRacers.Clear()
Dim curValue = ""
For i = 1 To racersPerShift
If (Not (dgvRacers.Rows(rowIndex).Cells(i).Value Is Nothing)) Then
curValue = dgvRacers.Rows(rowIndex).Cells(i).Value.ToString()
If (Not (String.IsNullOrEmpty(curValue))) Then
UsedRacers.Add(curValue)
End If
End If
Next
End Sub
The code above loops through all the “combobox” cells in the given row and if a “combobox” cell has something selected, the selected value is added to the UsedRacers list.
Now that the selected items for all the “comboboxes” in that row are in the UsedRacers list, we can now loop through each “combobox” cell in that row and set the proper list of names. To help, a method is created that returns a DataGridViewComboBoxCell such that the names in the current UsedRacers list will NOT be in the DataGridViewComboBoxCell’s list of selectable names.
The only issue here would be with cells that currently have an item selected. Each “combobox” cell with an item selected will uniquely need to have its selected item in its list of items. To remedy this, a check is needed to see if the “combobox” cell contains a value. If the “combobox” cell DOES contain a selected value, then this value is also contained in the UsedRacers list. Since THIS cell is the cell that is in the UseRacers list… then we need to ADD this value to this cells items list. Otherwise, we would not be able to display the unique selection.
To keep the UsedRacers list consistent, we need to add this item directly to the individual “combobox” cell and not remove or alter the UsedRacers list as this will be used for the other “combobox” cells. In other words… whatever value is selected in a combo box, we need to make sure it is one of the items in the “combobox’s” list of selectable items. I hope that makes sense.
This can all be done in the DataGridViews CellChanged event.
Private Sub dgvRacers_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles dgvRacers.CellValueChanged
If (e.ColumnIndex >= 1 And e.ColumnIndex <= racersPerShift) Then
SetUsedRacersForRow(e.RowIndex)
For i = 1 To racersPerShift
Dim newCell As DataGridViewComboBoxCell = GetCurrentComboBoxCell()
If (Not (dgvRacers.Rows(e.RowIndex).Cells(i).Value Is Nothing)) Then
Dim curValue = dgvRacers.Rows(e.RowIndex).Cells(i).Value.ToString()
newCell.Items.Add(curValue)
newCell.Value = curValue
End If
dgvRacers.Rows(e.RowIndex).Cells(i) = newCell
Next
End If
End Sub
In the code above, a method GetCurrentComboBoxCell (below) returns a DataGridViewComboBoxCell such that the items in the combo boxes list of items does not contain any items that are in the UsedRacers list. Because of this, a check is needed (above) to see if the cell already contains a value. NOTE: the DataGridViewComboBoxCell returned will always contain a “blank” empty item. This is necessary to allow the user to “De-Select” any currently selected value and then make the “De-Selected” item available to the other combo box cells.
Public Function GetCurrentComboBoxCell() As DataGridViewComboBoxCell
Dim newComboCell = New DataGridViewComboBoxCell()
newComboCell.DisplayStyle = DataGridViewComboBoxDisplayStyle.DropDownButton
newComboCell.FlatStyle = FlatStyle.Flat
newComboCell.Items.Add("")
For Each curRacer In AllRacers
If (Not UsedRacers.Contains(curRacer)) Then
newComboCell.Items.Add(curRacer)
End If
Next
Return newComboCell
End Function
Finally, putting all this together…
Dim racersInShift = 3
Dim AllRacers As List(Of String) = New List(Of String) From {"John", "Bobby", "Trent", "Josh", "Chapman", "Henry", "George", "Marvin"}
'Dim racersPerShift As Int16 = AllRacers.Count '<-- should be MAX value
Dim racersPerShift As Int16 = 4
Dim UsedRacers = New List(Of String)
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
BuildGrid()
End Sub
Private Sub BuildGrid()
dgvRacers.Size = New Size(800, 200)
dgvRacers.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
'dgvRacers.Location = New Point(50, 200)
dgvRacers.Columns.Add("ShiftCOL", "Shift Name")
dgvRacers.Name = "RacersDGV"
dgvRacers.EditMode = DataGridViewEditMode.EditOnEnter
dgvRacers.AllowUserToAddRows = False
AddRacerColumns()
AddRacerRows()
End Sub
Private Sub AddRacerColumns()
Dim newColumn As DataGridViewComboBoxColumn
For i As Integer = 1 To racersPerShift
newColumn = GetNewComboBoxColumn("Racer" & i, "Racer " & i)
dgvRacers.Columns.Add(newColumn)
Next
End Sub
Private Sub AddRacerRows()
For i As Integer = 1 To racersInShift
Dim row As New DataGridViewRow
dgvRacers.Rows.Add(row)
Next
End Sub
Private Sub dgvRacers_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs)
‘See code above
End Sub
Private Sub SetUsedRacersForRow(rowIndex As Int16)
‘See code above
End Sub
Public Function GetCurrentComboBoxCell() As DataGridViewComboBoxCell
‘See code above
End Function
‘Lastly a method to set a whole `DataGridviewComboBoxColumn` which is used to initialize all the combo box columns
Public Function GetNewComboBoxColumn(colName As String, colHeader As String) As DataGridViewComboBoxColumn
Dim newComboCol = New DataGridViewComboBoxColumn()
newComboCol.DisplayStyle = DataGridViewComboBoxDisplayStyle.DropDownButton
newComboCol.FlatStyle = FlatStyle.Flat
newComboCol.Items.Add("")
newComboCol.HeaderText = colHeader
newComboCol.Name = colName
For Each curRacer In AllRacers
newComboCol.Items.Add(curRacer)
Next
Return newComboCol
End Function
I hope this helps, I am guessing there is an easier way to do this.

Related

Dynamicly add new or remove a line of comboboxes in Userform also a refernce code to handle those comboboxes input

I have this userform
The form contains three comboboxes along with "add new" command button
Once user click add new button it will add another row of comboboes with a clear button.
The clear button will remove that particular row of comboboxes only. add button will add a new line below this line
each row is an element i.e A,B,C... The insert button will write conditions e.g. A OR B OR C
inserted text gathered from comboboxes would be
{#(ProductA === "P25" || ProductB === "P26" || ProductC === "P27")}
I am trying to have a button that can dynamically add new line of comboboxes with a clear button. also clear button that will only remove that line of comboboxes. I can user the code as discussed here. But don't know how I can handle the position and clear button.
An interesting mini-project, so here is my "solution" (obviously still far from being fully-functional but has the basic add/remove row capability.
The userform I tested with had only a single command button btnAddRow (for adding new rows).
Class DataRow:
Option Explicit
Private WithEvents Combo1 As MSForms.ComboBox
Private WithEvents Combo2 As MSForms.ComboBox
Private WithEvents ClearButton As MSForms.CommandButton
Dim controlContainer As Object
Public id As Long
Private Sub ClearButton_Click()
'calls a method on the parent form to remove the row
CallByName controlContainer, "RemoveRow", VbMethod, id
End Sub
'create and set up a few properties the controls for a row
Public Sub Create(container As Object, rowId As Long)
Set Combo1 = container.Controls.Add("Forms.ComboBox.1", "C1_" & rowId)
Combo1.Left = 20
Combo1.Width = 60
Combo1.List = Array("Item1", "Item2")
Set Combo2 = container.Controls.Add("Forms.ComboBox.1", "C2_" & rowId)
Combo2.Left = 90
Combo2.Width = 60
Combo2.List = Array("Red", "Blue")
Set ClearButton = container.Controls.Add("Forms.commandbutton.1", "BC_" & rowId)
ClearButton.Left = 160
ClearButton.Width = 50
ClearButton.Height = 20
ClearButton.Caption = "Clear"
Set controlContainer = container 'keep a reference to the place where the controls are created
id = rowId 'identifies this row
End Sub
'set the vertical position on the form for the row
Public Sub Position(rowIndex)
Dim pTop
pTop = 15 + (25 * (rowIndex - 1))
Combo1.Top = pTop
Combo2.Top = pTop
ClearButton.Top = pTop
End Sub
'remove the row - called from the parent form
Public Sub Remove()
With controlContainer.Controls
.Remove Combo1.Name
.Remove Combo2.Name
.Remove ClearButton.Name
End With
End Sub
'move the "add row" button to this row
Public Sub TakeAdd(btn As MSForms.CommandButton)
btn.Left = ClearButton.Left + ClearButton.Width + 10
btn.Top = ClearButton.Top
End Sub
'is this row removable? (last remaining row can't be removed)
Public Sub CanRemove(bRemovable As Boolean)
ClearButton.Enabled = bRemovable
End Sub
The code for the userform:
Option Explicit
Dim id As Long 'sequence number for assigning unique id to each row
Dim col As New Collection 'holds instances of the class `DataRow`
Private Sub btnAddRow_Click()
AddRow 'add a new row
End Sub
Private Sub UserForm_Activate()
AddRow 'add starting row
End Sub
'add a row
Sub AddRow()
Dim obj As New DataRow
id = id + 1
obj.Create Me, id 'creates the controls
col.Add obj 'add to the collection
obj.Position col.Count 'sets row index on form
obj.TakeAdd Me.btnAddRow 'position the "add row" button
checkRemove 'check if remove buttons are enabled
End Sub
'remove the specified row
Sub RemoveRow(rowId As Long)
Dim i As Long
i = 1
Do While i <= col.Count
If col(i).id = rowId Then 'is this the row to remove?
col(i).Remove 'removes the row from the form
col.Remove (i) 'removes the class instance from the collection
Else
col(i).Position i '(re)position this row
i = i + 1
End If
Loop
col(col.Count).TakeAdd Me.btnAddRow '(re)position the "add row" button
checkRemove 'check if remove buttons are enabled
End Sub
'see if the "remove" buttons should be enabled
Sub checkRemove()
Dim obj
For Each obj In col
obj.CanRemove (col.Count > 1) 'enabled if >1 row on form
Next obj
End Sub

Mutually Exclusive Comboboxes?

So, I've got 4 Comboboxes. They all share the same list of options, lets say Apple, Banana, Carrot, Dill.
However, once the user selects one, that selection should not be available in the other comboboxes. E.g. if they pick Apple in Combobox1, then the only selections available in Combobox2, 3, and 4 should be Banana, Carrot, and Dill.
Is there a good way to do this? I originally thought to link the boxes datasource to a list containing the options, but they need separate datasources for separate choices.
Radio and checkboxes aren't really an option in the actual program, as the list of options is much larger than 4. A Combobox seems to be the best way to represent the user's available choices here.
Here's a fairly simple way to do what you are asking. This code assumes that the datasource uses an integer value to keep track of the items. If you are using the string value itself {Apple, Banana, etc.} as the id, the code will need to be amended slightly. If you need further help let me know but hopefully this gets you on the right track.
You can test this by creating a new blank form (Form1) and drop 4 combo boxes onto it (ComboBox1, ComboBox2, ComboBox3, ComboBox4). Copy/paste this code over top of the form code and run to see how it works:
Public Class Form1
Dim oComboBoxArray(3) As ComboBox
Dim bPreventSelectedChange As Boolean = False
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' Set up an array with the combo box references to reduce code size by using loops later
oComboBoxArray(0) = Me.ComboBox1
oComboBoxArray(1) = Me.ComboBox2
oComboBoxArray(2) = Me.ComboBox3
oComboBoxArray(3) = Me.ComboBox4
' Populate all four combo boxes with the same datasource to start
For Each oCbo In oComboBoxArray
PopulateDataSource(oCbo)
Next
End Sub
Private Sub PopulateDataSource(oCombo As ComboBox, Optional nIdToSelect As Integer = 0)
bPreventSelectedChange = True ' Prevent code in ComboBox_SelectedIndexChanged from executing while we change the datasource
' Using manually populated datatable as datasource because it's quick and easy to use
Dim dt As New DataTable
Dim dr As DataRow
dt.Columns.Add("ID", GetType(Int32))
dt.Columns.Add("Name", GetType(String))
' Need to have some kind of "Please select an item:" in the list or else we will be unable to clear an already selected combo box
dr = dt.NewRow
dr("ID") = 0
dr("Name") = "Select..."
dt.Rows.Add(dr)
' If you are populating from a database or other dynamic source you will only have one of these 'if' statements within a loop
If CheckSkipItem(oCombo, 1) = False Then
dr = dt.NewRow
dr("ID") = 1
dr("Name") = "Apple"
dt.Rows.Add(dr)
End If
If CheckSkipItem(oCombo, 2) = False Then
dr = dt.NewRow
dr("ID") = 2
dr("Name") = "Banana"
dt.Rows.Add(dr)
End If
If CheckSkipItem(oCombo, 3) = False Then
dr = dt.NewRow
dr("ID") = 3
dr("Name") = "Carrot"
dt.Rows.Add(dr)
End If
If CheckSkipItem(oCombo, 4) = False Then
dr = dt.NewRow
dr("ID") = 4
dr("Name") = "Dill"
dt.Rows.Add(dr)
End If
oCombo.DataSource = dt
oCombo.DisplayMember = "Name"
oCombo.ValueMember = "ID"
oCombo.SelectedValue = nIdToSelect ' Set value to either a) the "Select..." item or b) the item that was selected previously depending on the situation
bPreventSelectedChange = False ' Allow code in ComboBox_SelectedIndexChanged to be executed by user again
End Sub
Private Function CheckSkipItem(oCombo As ComboBox, nID As Integer) As Boolean
Dim bSkip As Boolean = False
' Loop through all combo boxes and see if this id has already been chosen in another combo box
For Each oCbo In oComboBoxArray
If oCbo IsNot oCombo AndAlso oCbo.SelectedValue = nID Then
' It has been chosen already so it is not valid for the current combo box that we are checking
bSkip = True
Exit For
End If
Next
Return bSkip
End Function
Private Sub ComboBox_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged, ComboBox2.SelectedIndexChanged, ComboBox3.SelectedIndexChanged, ComboBox4.SelectedIndexChanged
' Jump out of this event if the bPreventSelectedChange boolean is set to true (ie. if the combo box is being repopulated)
If bPreventSelectedChange = False Then
' A value was chosen by the user. Reset all other combo box datasources and remove the recently selected value
For Each oCbo As ComboBox In oComboBoxArray
If sender IsNot oCbo Then
PopulateDataSource(oCbo, If(oCbo.SelectedValue = Nothing, 0, oCbo.SelectedValue))
End If
Next
End If
End Sub
End Class

How to compare DataGridView cell data to DataSet cell data

In a VB.NET WinForms project I'm working on in VS2013 I am detecting when the user changes something in a cell on the CellValueChanged event. When a row in the DataGridView is found that is different from the DataSet I highlight the row in pink.
In my code though, I only know how to iterate through all of the rows, rather than just compare the row that fired the CellValueChanged event to the DataSet.
Here's my current code:
Private Sub dgvEmployees_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles dgvEmployees.CellValueChanged
' Pass the row and cell indexes to the method so we can change the color of the edited row
CompareDgvToDataSource(e.RowIndex, e.ColumnIndex)
End Sub
Private Sub CompareDgvToDataSource(ByVal rowIndex As Integer, ByVal columnIndex As Integer)
' Force ending Edit mode so the last edited value is committed
EmployeesBindingSource.EndEdit()
Dim dsChanged As DataSet = EmployeesDataSet.GetChanges()
If Not dsChanged Is Nothing Then
For Each dt As DataTable In dsChanged.Tables
For Each row As DataRow In dt.Rows
For i As Integer = 0 To dt.Columns.Count - 1
Dim currentColor As System.Drawing.Color = dgvEmployees.AlternatingRowsDefaultCellStyle.BackColor
If Not row(i, DataRowVersion.Current).Equals(row(i, DataRowVersion.Original)) Then
Console.WriteLine("Row index: " & dt.Rows.IndexOf(row))
' This works
dgvEmployees.Rows(rowIndex).DefaultCellStyle.BackColor = Color.LightPink
Else
' Need to change the BackColor back to what it should be based on its original alternating row color
End If
Next
Next
Next
End If
End Sub
As you can see, I'm passing the row and column index of the changed cell, so how can I take that and compare it to the specific row and/or cell in the unchanged DataSet?
UPDATE
Nocturnal reminded me that I need to allow for sorting of the DGV, so using row indexes won't work. He offered this as a solution (changed slightly to work with my objects):
If Not dsChanged Is Nothing Then
For Each dtrow As DataRow In dsChanged.Tables("employees").Rows
If DirectCast(dtrow, EmployeesDataSet.employeesRow).employeeID.ToString = dgvEmployees.Rows(rowIndex).Cells("employeeID").Value.ToString Then
For i As Integer = 0 To dsChanged.Tables("employees").Columns.Count - 1
If Not dtrow(i, DataRowVersion.Current).Equals(dtrow(i, DataRowVersion.Original)) Then
Console.WriteLine("Employees ID: " & DirectCast(dtrow, EmployeesDataSet.employeesRow).employeeID)
dgvEmployees.Rows(rowIndex).Cells(columnIndex).Style.BackColor = Color.LightPink
Else
' Need to change the BackColor back to what it should be based on its original alternating row color
End If
Next
End If
Next
End If
However, I'm getting an error on the If DirectCast... line saying "Column named "employeeID" cannot be found." I'm not sure if the error is on the DataSet or on the DGV, but there is an employeeID column in the database and DataSet. There is an employeeID as a bound column for the DataGridView, but it is set to Visible = False. That's the only thing I can think of that could possibly cause that error, but if it's a bound column, I would think it could be compared against as in this case.
FINAL WORKING VERSION
Private Sub dgvEmployees_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles dgvEmployees.CellValueChanged
' Pass the row and cell indexes to the method so we can change the color of the edited row
CompareDgvToDataSource("employees", e.RowIndex, e.ColumnIndex)
End Sub
Private Sub CompareDgvToDataSource(ByVal dataSetName As String, ByVal rowIndex As Integer, ByVal columnIndex As Integer)
' Takes a dataset and the row and column indexes, checks if the row is different from the DataSet and colors the row appropriately
EmployeesBindingSource.EndEdit()
Dim dsChanges As DataSet = EmployeesDataSet.GetChanges()
If Not dsChanges Is Nothing Then
For Each dtrow As DataRow In dsChanges.Tables("employees").Rows
If DirectCast(dtrow, EmployeesDataSet.employeesRow).employeeID.ToString = dgvEmployees.Rows(rowIndex).Cells("employeeID").Value.ToString Then
For i As Integer = 0 To dsChanges.Tables("employees").Columns.Count - 1
If dtrow.RowState.ToString = DataRowState.Added.ToString Then
' TODO: Color entire new row
ElseIf dsChanges.Tables(dataSetName).Rows(0).HasVersion(DataRowVersion.Original) Then
If Not dtrow(i, DataRowVersion.Current).Equals(dtrow(i, DataRowVersion.Original)) Then
Console.WriteLine("Employees ID: " & DirectCast(dtrow, EmployeesDataSet.employeesRow).employeeID)
dgvEmployees.Rows(rowIndex).Cells(columnIndex).Style.BackColor = Color.LightPink
Else
' TODO: Need to change the BackColor back to what it should be based on its original alternating row color
End If
End If
Next
End If
Next
End If
End Sub
My project has four DGVs in it, so this will eventually be expanded to allow for all four DGVs to be checked for changes.
have a look at this approach it is simlar but only iterating the specific Table
Private Sub dgvEmployees_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles dgvEmployees.CellValueChanged
' Pass the row and cell indexes to the method so we can change the color of the edited row
CompareDgvToDataSource(e.RowIndex, e.ColumnIndex, sender.DataSource.datamember.ToString)
End Sub
and comparing the ID of the given Table
Private Sub CompareDgvToDataSource(ByVal rowIndex As Integer, ByVal columnIndex As Integer, tablename As String)
EmployeesBindingSource.EndEdit()
Dim dsChanged As DataSet = EmployeesDataSet.GetChanges()
If Not dsChanged Is Nothing Then
For Each dtrow As DataRow In dsChanged.Tables(tablename).Rows
If DirectCast(dtrow, EmployeesDataSet.EmployeeRow).EmployeeID = dgvEmployees.Rows(rowIndex).Cells("EmployeeID").Value Then
Dim currentColor As System.Drawing.Color = dgvEmployees.AlternatingRowsDefaultCellStyle.BackColor
For i As Integer = 0 To dsChanged.Tables(tablename).Columns.Count - 1
If Not dtrow(i, DataRowVersion.Current).Equals(dtrow(i, DataRowVersion.Original)) Then
Console.WriteLine("Employees ID: " & DirectCast(dtrow, EmployeesDataSet.EmployeeRow).EmployeeID)
' This works
dgvEmployees.Rows(rowIndex).Cells(columnIndex).Style.BackColor = Color.LightPink
Else
' Need to change the BackColor back to what it should be based on its original alternating row color
End If
Next
End If
Next
End If
End Sub
and i am only changing the backcolor of the cell that was changed not the entire row....but depends how you would use that information anyways
EDIT:
with
Console.WriteLine(EmployeesDataSet.Employee(rowIndex)(columnIndex, DataRowVersion.Original).ToString())
Console.WriteLine(EmployeesDataSet.Employee(rowIndex)(columnIndex, DataRowVersion.Current).ToString())
you can see Current and Original Values
123456

Changing double clicking activation on Combo box cell to single click?

I have a setup in my code where there is a datagridview. For each row I have a combo box cell that I have a separate combo box cell since I want a different selection of items for each cell.
Problem : The cell only drops down when the arrow is double clicked. How can I change the cell formatting, or possibly a cell click event, so that the cell response to just one click?
Here's my cell creation code. Frankly, I didn't start any other code since I didn't know what event to touch or call. Is there a property I can edit?
Code:
'add items to combobox list
Dim comboCell As New DataGridViewComboBoxCell
comboCell.FlatStyle = FlatStyle.Flat
Dim resolutionList As New List(Of cmbStruct)
Dim currentResIndex As Integer = 0
'create list of resolutions
For j As Integer = 0 To resolutions.Length - 1
Dim resClass As New cmbStruct
resClass.Name = resolutions(j)
resClass.ID = resolutions(j)
resolutionList.Add(resClass)
comboCell.Items.Add(resolutions(j))
Next
'set combocell values
comboCell.DisplayMember = "Name"
comboCell.ValueMember = "ID"
'set the default value to the current resolution index
Try
comboCell.Value = resolutions(currentResIndex)
Catch ex As Exception
End Try
comboCell.ValueType = GetType(cmbStruct)
comboCell.DataSource = resolutionList
editCameraTable("Resolution", i) = comboCell
Next
Change the EditMode property:
DataGridView1.EditMode = DataGridViewEditMode.EditOnEnter
There seems to be a nearly identical question and a very good answer. It involves using the click_event. Here is the link:
How to manually drop down a DataGridViewComboBoxColumn?
In the link:
Private Sub cell_Click(ByVal sender As System.Object, ByVal e As DataGridViewCellEventArgs) Handles DataGridView1.CellClick
DataGridView1.BeginEdit(True)
If DataGridView1.Rows(e.RowIndex).Cells(ddl.Name).Selected = True Then
DirectCast(DataGridView1.EditingControl, DataGridViewComboBoxEditingControl).DroppedDown = True
End If
End Sub

How to Set DataGridView Row Tag

I am using a double click event on a listview that will add three columns to a datagridview. I'm not sure how to set the "Tag" property on the "selectedText" variable.
Private Sub lwArticles_DoubleClick(sender As Object, e As System.EventArgs) Handles lwArticles.DoubleClick
Dim selectedText = lwArticles.SelectedItems(0).SubItems.Item(0).Text 'Article No
Dim selectedDesc = lwArticles.SelectedItems(0).SubItems.Item(1).Text 'Description
Dim currRowNo As String = ""
Dim alreadyExists = False
For i As Integer = 0 To dgvDetail.Rows.Count - 1
currRowNo = dgvDetail.Rows(i).Cells(0).Value
If currRowNo = selectedText Then
alreadyExists = True
dgvDetail.Rows(i).Cells(2).Value += 1
Exit For
End If
Next
'If the entry doesn't exist, add it
If Not alreadyExists Then
dgvDetail.Rows.Add(New String() {selectedText, selectedDesc, 1})
End If
End Sub
After this I loop through the row's tags to see the article numbers. It will be near my dgvDetail.Rows.Add() that I should be setting the Tag property to equal the selectedText ... Any one know how to do this?
Edit:
The datagridview columns being populated are: "Article Number", "Description" and "Quantity". The quantity is set in the loop, basically if I've double clicked on the same thing twice, it will increment the third column (Cell(2)) by one.
The Add "function" for the DataGridView control returns the index of the row in the grid, so you can try using that to reference the row:
Dim rowIndex As Integer
rowIndex = dgvDetail.Rows.Add(New String() {selectedText, selectedDesc, 1})
dgvDetails.Rows(rowIndex).Tag = selectedText