0

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.

marky
  • 4,878
  • 17
  • 59
  • 103
  • Is the last checked row the last row in the grid? Can you step through using the debugger and see if the value of dgvEmployees.Rows.Count matches the number of rows you see in the grid? – Casey Wilkins Nov 20 '14 at 18:12
  • @CaseyWilkins, thanks for that, I updated my question with details about row counts and index output during the iteration. – marky Nov 20 '14 at 18:31
  • Have you tried stepping through the first 5 or 6 iterations using the debugger, checking the chkCell.Value as you step through? – Casey Wilkins Nov 20 '14 at 18:43
  • I just did and it's the weirdest thing: I'm iterating through the For/Next loop line by line and when I get to the row with the last checkbox (still using the above example, so I'm at row index 4) chkcell.Value is showing as False, when that checkbox is checked. The previous two checkboxes correctly showed True. - And it's always the last checked checkbox that evaluates to False. – marky Nov 20 '14 at 18:56
  • Are you moving/clicking on another row after checking the check box on the last row? It sounds like the datagridview isn't committing your change when you check the last row. Try checking the last row, then click on any other row/cell to move the focus. Then step through your code and see if the value is true. – Casey Wilkins Nov 20 '14 at 19:01
  • Sure enough - that did it. But how do I get around that? I can't exactly tell the users "you need to click on a different row after clicking the last checkbox for it to work"! :) There's got to be some property that "knows" that the checkbox is checked. – marky Nov 20 '14 at 19:09
  • See my answer, I can't figure out how to format code in comments :) Not sure it will work, haven't actually tried it, but I'm sure we can come up with something. – Casey Wilkins Nov 20 '14 at 19:15

1 Answers1

1

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 
Casey Wilkins
  • 2,555
  • 2
  • 23
  • 31