Not getting all rows when iterating through DataGridView rows - vb.net

In a VB.NET WinForms application I have a DataGridView with a checkbox as a non-bound column in the first column. I need to add to a collection of rows each row that has its checkbox checked.
I'm using the below code to iterate through the rows and find the ones with a checked checkbox:
For Each row As DataGridViewRow In dgvEmployees.Rows
Dim chkCell As DataGridViewCheckBoxCell = DirectCast(row.Cells(0), DataGridViewCheckBoxCell)
If Convert.ToBoolean(chkCell.Value) = True Then
Console.WriteLine("This should be the Emp No of the checked row: " & row.Cells(1).Value.ToString())
End If
Next
But it is missing the last row with a checked checkbox. I.e. If I check three checkboxes, in the console output I'm seeing the "Emp No" of the first two checked rows.
Thinking it was acting like an issue with zero indexing, I also tried doing an iteration that used a counter:
For rowNum As Integer = 0 To dgvEmployees.Rows.Count - 1
Dim currentRow As DataGridViewRow = dgvEmployees.Rows(rowNum)
Dim chkCell As DataGridViewCheckBoxCell = DirectCast(currentRow.Cells(0), DataGridViewCheckBoxCell)
If Convert.ToBoolean(chkCell.Value) = True Then
Console.WriteLine("This should be the emp no of the checked row: " & currentRow.Cells(1).Value.ToString())
End If
Next
But I get the same behavior with that code. I tried changing around the Integer = 0 and Rows.Count - 1, etc but that didn't help either.
In case it matters, the DataGridView's SelectionMode needs to be set to CellSelect.
UPDATE
There are 694 records in the table that the datagridview is being populated by.
I added a console output to get the rows.count value:
Console.WriteLine("Num rows: " & dgvEmployees.Rows.Count)
and got 695, which makes sense due to the last row in the datagridview is there to allow entry of a new row. (But I would have thought that the Count - 1 in the second iteration method would account for that.)
I also added
Console.WriteLine("Row index: " & chkcell.RowIndex)
right before the If check for a checked checkbox and, with the first, third and fifth rows checked (indexes 0, 2, 4), here's what was output:
Num rows: 695
Row index: 0
this should be the emp no of the checked row: ACS175
Row index: 1
Row index: 2
this should be the emp no of the checked row: AJAW03
Row index: 3
Row index: 4
Row index: 5
Row index: 6
There should have been a "this should be..." output after the Row index: 4 line.

It appears that the last check box that you check is not being committed by the DataGridView because you aren't moving the focus to another cell after checking it. Try this before running your iteration code:
If dgvEmployees.IsCurrentCellDirty Then
dgvEmployees.CommitEdit(DataGridViewDataErrorContexts.Commit)
End If

Related

Load a DataGridView with 100 empty rows with Row number at loading in vb.net

I want to show/load 100 empty rows with row number in datagridview of vb.net at run time, so that user can enter the data. If user fill all the 100 rows then datagridview can create new rows as it do usually. I found this so many time but not find any solution how to load empty rows at run time.
'dgv is your DataGridView object.
dgv.Rows.Add(100)
Dim I As Integer = 1
For Each Row As DataGridViewRow In dgv.Rows
Row.Cells(0).Value = I.ToString()
I += 1
Next

Find and sum value of a datagridview column in vb.net

I want to find and sum qty value of searched id in data grid view column am using this code
Dim tqty As Double
For Each row As DataGridViewRow In dgv.Rows
If row.Cells.Item(0).Value = cmbItemCode.Text Then
tqty += row.Cells.Item(4).Value
Textbox1.text=tqty
Exit For
End If
Next
The problem is that Textbox1 shows only one top searched row value. For example
id item name qty
1 abc 4
2 xyz 10
1 abc 10
Textbox1 shows the Result only 4.
As soon as you hit the first value, you exit the for statement. Therefore you never get pass the first value. Erase the Exit For it should work.
If DataGridView2.RowCount > 1 Then
Dim tqty As Integer = 0
'if you have the other column to get the result you could add a new one like these above
For index As Integer = 0 To DataGridView2.RowCount - 1
amount += Convert.ToInt32(DataGridView2.Rows(index).Cells(2).Value)
'if you have the other column to get the result you could add a new one like these above (just change Cells(2) to the one you added)
Next
TextBox1.Text = tqty

DataGridView Copy a selected row issue

I have a datagridview and i want to copy the exact row that gets selected by the user to the same position (above). I have it right now so it inserts the line above the current line that is selected but it is not copying all the values.
I'm just using a basic grid, no dataset or datatables. heres my code.
If dgvPcPrevMonth.SelectedRows.Count > 0 Then
dgvPcPrevMonth.Rows.Insert(dgvPcPrevMonth.CurrentCell.RowIndex, dgvPcPrevMonth.SelectedRows(0).Clone)
Else
MessageBox.Show("Select a row before you copy")
End If
The clone method only clones the row, not the data in it. You'll have to loop through the columns and add the values yourself after inserting it
Public Function CloneWithValues(ByVal row As DataGridViewRow) _
As DataGridViewRow
CloneWithValues = CType(row.Clone(), DataGridViewRow)
For index As Int32 = 0 To row.Cells.Count - 1
CloneWithValues.Cells(index).Value = row.Cells(index).Value
Next
End Function
The code is taken directly from the msdn link provided below
https://msdn.microsoft.com/en-us/library/system.windows.forms.datagridviewrow.clone(v=vs.110).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1
I updated your code to test if current row was not the first and to clone the cuurent row (not the first one).
If ddgvPcPrevMonth.CurrentCell.RowIndex > 0 Then
dgvPcPrevMonth.Rows.Insert(dgvPcPrevMonth.CurrentCell.RowIndex, dgvPcPrevMonth.Rows(dgvPcPrevMonth.CurrentCell.RowIndex-1).Clone)
Else
MessageBox.Show("Select a row (but not the first one) before you copy")
End If

For Loop to count checked items on datagrid not counting correctly

I worked out the following loop to count and display how many rows on my datagrid are checked. However, the loop is ignoring my first checked row. The count does not start at 1 until I have checked the second row. The same happens when I uncheck, the values are off by one.
Dim chkRowCount As Integer = 0
For Each row As DataGridViewRow In dgvAssignGridView.Rows
If row.Cells(6).Value = True Then
chkRowCount += 1
Else
chkRowCount += 0
End If
Next
lblChkCount.Text = chkRowCount.ToString
I have tried setting the variable to 1 instead of 0, but that had some unwanted results.
I am guessing you have this code in CellContentClick. The problem is that the code in that routine fires before the value of the checkbox is actually changed. However, you can basically force the DataGridView to verify itself first by putting the following line right before your code.
dgvAssignGridView.EndEdit()
That forces the cell click to register before you do your count.

VB6 - what different of .row and .rows in datagridview

If LooseFlexGrid.Row = LooseFlexGrid.Rows - 1 Then
....
end if
wat is different of .row & .rows ??
Using LooseFlexGrid.Row you can get the selected row's index, and LooseFlexGrid.Rows returns the total amount of Rows in your LooseFlexGrid. More info of those can be found at: Visual Basic: MSFlexGrid/MSHFlexGrid Controls
So basically what your code tries to do is to check if the selected row is the last row in LooseFlexGrid (because indexing starts from zero, the last row is at index LooseFlexGrid.Rows - 1)