How to Set DataGridView Row Tag - vb.net

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

Related

How to use function to prevent duplicated record for datagridview

I use function to prevent the same record goes into my datagridview but it doesnt work , when i separate the code out then its worked
i tried to seperate the for loop part out then the code work , but i wan to use function to do it so the code look more neater
Private Sub PicFavNote10_Click(sender As Object, e As EventArgs) Handles picFavNote10.Click
If validationDataGrid(lblNameNote10.Text) <> True Then
'if item didn added to the favorite data table yet
'add to favorite table
addTofavorite(lblUserLogin.Text, lblNameNote10.Text, lblDecpNote10.Text, txtPicNote10.Text, "SmartPhone", lblPriceNote10.Text)
End If
lblPriceNote10.Text = FormatCurrency(lblPriceNote10.Text)
End Sub
Private Function validationDataGrid(ByRef data As String) As Boolean
'validation on data grid view
For Each itm As DataGridViewRow In DGTFavTable.Rows 'loop though every item in datagrid
If itm.Cells(0).Value = data Then 'check wherter the text already exist
MsgBox(data & " Already added to your favorite cart")
Return True
Else
Return False
End If
Next
End Function
I expected the MsgBox(data & " Already added to your favorite cart") will excecute but instead the validationDataGrid function return false value even the item is already added to favorite datagridview
Before you loop all rows you need to call this sub as is an efficient workaround to validate new data on DataGridView:
Private Sub ForceGridValidation()
'Get the current cell
Dim currentCell As DataGridViewCell = DGTFavTable.CurrentCell
If currentCell IsNot Nothing Then
Dim colIndex As Integer = currentCell.ColumnIndex
If colIndex < DGTFavTable.Columns.Count - 1 Then
DGTFavTable.CurrentCell = DGTFavTable.Item(colIndex + 1, currentCell.RowIndex)
ElseIf colIndex > 1 Then
DGTFavTable.CurrentCell = DGTFavTable.Item(colIndex - 1, currentCell.RowIndex)
End If
'Set the original cell
DGTFavTable.CurrentCell = currentCell
End If
End Sub

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

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.

'AddRange' is not a member of... (while i attempt to save column order of a DataGridView

I'm trying to save and load the data grid view column order.
I'm using this code that i suppose is also right.
Private Sub SaveColumnOrder()
Dim upperBound As Integer = Me.DataTable1DataGridView.ColumnCount - 1
Dim columnIndexes(upperBound) As String
For index As Integer = 0 To upperBound
Dim column As DataGridViewColumn = Me.DataTable1DataGridView.Columns(index)
columnIndexes(column.DisplayIndex) = index.ToString()
Next
My.Settings.GridColumnIndexes = New StringCollection
My.Settings.GridColumnIndexes.AddRange(columnIndexes)
End Sub
Private Sub LoadColumnOrder()
Dim columnIndexes As StringCollection = My.Settings.GridColumnIndexes
For displayIndex As Integer = 0 To columnIndexes.Count - 1
Dim index As Integer = CInt(columnIndexes(displayIndex))
Me.DataTable1DataGridView.Columns(index).DisplayIndex = displayIndex
Next
End Sub
Problem is that i don't know how to set the GridColumnIndexes inside project property settings.
I set to string and other "data" options but i always get the error: 'AddRange' is not a member of... {option selected}
Which is the right option in settings to make it finally work? Thank you :)

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

Getting data from a ListView into an array

I have a ListView control on my form set up like this in details mode:
What I would like to do, is get all the values of the data cells when the user presses the Delete booking button.
So using the above example, my array would be filled with this data:
values(0) = "asd"
values(1) = "BS1"
values(2) = "asd"
values(3) = "21/04/2010"
values(4) = "2"
This is my code so far:
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
Dim items As ListView.SelectedListViewItemCollection = _
Me.ManageList.SelectedItems
Dim item As ListViewItem
Dim values(0 To 4) As String
Dim i As Integer = 0
For Each item In items
values(i) = item.SubItems(i).Text
i = i + 1
Next
End Sub
But only values(0) gets filled with the first data cell of the selection (in this case "asd") and the rest of the array entries are blank. I have confirmed this with a breakpoint and checked the array entries myself.
I'm REALLY lost on this, and have been trying for about an hour now. Any help would be appreciated, thanks :)
Also please note that there can only be one row selection at once. Thanks.
Costin is right about needing to iterate the subitems and if you're sure that there'll only be one selection iterating through the items just confuse things, I'd write it as:
Dim values As New List(Of String)
If ManageList.SelectedItems.Count > 0 Then
For Each item As ListViewItem.ListViewSubItem In ManageList.SelectedItems(0).SubItems
values.Add(item.Text)
Next
End If
I don't know how you populate the list but for me it seems that you need to iterate the item.Subitems to get the values. I don't know VB but I think you can use a something like :
For i As Integer = 0 To item.SubItems.Count
values(i) = item.SubItems(i).Text
Try this instead..
Dim values() As String
If items.Count = 1 Then
subitems = items(0).SubItems
ReDim values(0 To subitems.Count - 1)
For i As Integer = 0 To subitems.Count
values(i) = subitems(i).Text
Next
Else
Throw New Exception("boom")
End If