Reputation: 173
Good morning I have the following question, how can I validate that the record is not duplicated in my datagridview.
this is my code to send data from gridview list to gridview details
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim rowSelected As List(Of DataGridViewRow) = New List(Of DataGridViewRow)()
For Each row As DataGridViewRow In dgvlistarproductos.Rows
Dim cellSelecion As DataGridViewCheckBoxCell = TryCast(row.Cells("SELECCIONAR"), DataGridViewCheckBoxCell)
If Convert.ToBoolean(cellSelecion.Value) Then
rowSelected.Add(row)
End If
Next
For Each row As DataGridViewRow In rowSelected
dgvdetalleproduc.Rows.Add(New Object() {row.Cells(1).Value, row.Cells(2).Value
})
Next
End Sub
Any suggestion or help I know I have to validate but I don't know where to place it, thanks
Upvotes: 0
Views: 1915
Reputation: 173
Thanks to both of you for giving me an idea of how to solve this case.
I managed to solve and detect if the selected record is repeated or duplicated when passing to the Datagridview with the following code
Dim existe = False
Dim rowSelected As List(Of DataGridViewRow) = New List(Of DataGridViewRow)()
For Each row As DataGridViewRow In dgvlistarproductos.Rows
Dim cellSelecion As DataGridViewCheckBoxCell = TryCast(row.Cells("SELECCIONAR"), DataGridViewCheckBoxCell)
If Convert.ToBoolean(cellSelecion.Value) Then
rowSelected.Add(row)
End If
Next
For Each row As DataGridViewRow In dgvdetalleproduc.Rows
If Convert.ToString(row.Cells(0).Value).Equals(dgvlistarproductos.CurrentRow.Cells(1).Value) Then
existe = True
End If
Next
For Each row As DataGridViewRow In rowSelected
If (existe = True) Then
MsgBox("ESTE PRODUCTO YA FUE AGREGADO", MsgBoxStyle.OkOnly, "INFORMACIÓN")
Else
dgvdetalleproduc.Rows.Add(New Object() {row.Cells(1).Value, row.Cells(2).Value
})
End If
Next
Upvotes: 0
Reputation: 74730
The easiest way to do this is to just have both grids use a single data source(datatable) for their info and have a Boolean column in the datatable like "isChosen". Each grid binds to a separate bindingsource or dataview, one of which has its [Row]Filter set to "[isChosen] = True"
, the other filters for false. The >>
button sets the selected row(s)' ischosen to true, the other button sets it false
Because there is only ever one row, and it doesn't "move" anywhere (it just appears in a different grid depending on the value of isChosen) there are no duplicates
To demonstrate this:
Dim dt as New DataTable
dt.Columns.Add("Name")
dt.Columns.Add("IsChosen", GetType(Boolean))
dt.Rows.Add("John", False)
dt.Rows.Add("Mark", False)
dt.Rows.Add("Luke", False)
Dim bs1 = New BindingSource()
bs1.Filter = "[IsChosen] = False"
bs1.DataSource = dt
dataGridView1.DataSource = bs1
Dim bs2 = New BindingSource()
bs2.Filter = "[IsChosen] = True"
bs2.DataSource = dt
dataGridView2.DataSource = bs2
DirectCast(DirectCast(dataGridView1.DataSource, BindingSource).Current, DataRowView)("IsChosen") = True
DirectCast(DirectCast(dataGridView2.DataSource, BindingSource).Current, DataRowView)("IsChosen") = False
Run the app, click on a name in dgv1 and click button1, it will move to dgv2
You can also toggle the state of the ✅ checkbox column in the grid and it will move - it doesn't matter how the datatable column comes to be True/False to move the row into dgv 2/1 respectively
Upvotes: 1
Reputation: 4695
If IDPRODUCTO
means unique product ID as it sounds then use it to identify and skip the duplicates thru a LINQ query like so:
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim checkedRows = dgvlistarproductos.Rows.Cast(Of DataGridViewRow).
Where(Function(r1) r1.Cells(0).Value IsNot Nothing AndAlso Convert.ToBoolean(r1.Cells(0).Value)).
Where(Function(r1) Not dgvdetalleproduc.Rows.Cast(Of DataGridViewRow).
Any(Function(r2) r2.Cells(0).Value IsNot Nothing AndAlso r2.Cells(0).Value.ToString().
Equals(r1.Cells(1).ToString(), StringComparison.OrdinalIgnoreCase)))
For Each row In checkedRows
dgvdetalleproduc.Rows.Add(row.Cells(1).Value, row.Cells(2).Value)
Next
End Sub
You can use the columns names rather than their indices to get the cells values.
Upvotes: 0
Reputation:
Try placing your validation code in the RowValidating event of the DataGridView control, or try this code below:
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim rowSelected As List(Of DataGridViewRow) = New List(Of DataGridViewRow)()
For Each row As DataGridViewRow In dgvlistarproductos.Rows
Dim cellSelecion As DataGridViewCheckBoxCell = TryCast(row.Cells("SELECCIONAR"), DataGridViewCheckBoxCell)
If Convert.ToBoolean(cellSelecion.Value) Then
rowSelected.Add(row)
End If
Next
For Each row As DataGridViewRow In rowSelected
If dgvdetalleproduc.Rows.Contains(row) = False Then
dgvdetalleproduc.Rows.Add(New Object() {row.Cells(1).Value, row.Cells(2).Value})
End If
Next
End Sub
Upvotes: 0