views:

349

answers:

4
For Each row As DataGridViewRow In DGV.Rows
                    DGV.Rows.RemoveAt(CInt(row.Index.ToString))
                Next

The above code will remove every other row

For i As Integer = 0 To 7 Step 1
                For Each row As DataGridViewRow In DGV.Rows
                    DGV.Rows.RemoveAt(CInt(row.Index.ToString))
                Next
            Next

This code gets rid of everything (DGV has, at the time the subroutine is called, 250 rows)

DGV is the DataGridView object which is displayed.

What I don't get is why that first one won't work.

To clarify, I used CInt(row.Index.ToString) instead of row.Index because row.Index does not seem to work on its own, yet CInt(row.Index.ToString) does.

I have also tried things like:

For i As Integer = 0 To DGV.Rows.Count Step 1
        DGV.Rows.RemoveAt(i)
    Next

This also failed to work.

I even tried using the actual number 250 in place of DGV.Rows.Count in the last example, but with the same results, it ALWAYS skips every other. I figured that by iterating through the loop a few more times, I could clear the whole thing, so I used trial and error till I wound up at 7 iterations as the magic number.

Can someone explain this oddity to me?

+1  A: 

Just a guess here, but you're changing the row collection you are iterating over. First time through, you remove the row at index 0. This moves all the row items up one index, so the old index 1 is now at new index 0 with 249 items remaining. The second time through the loop, you are removing the row at index 1 but there is a row still at index 0. Keep repeating, and you'll only get half the items.

Try

for n = 0 to dgv.rows.count
     dgv.rows.removeat(0)
next

if you want to remove everything.

pjabbott
+3  A: 

If you have five items in a gridview/listbox, whatever, and remove an item, the remaining items move up:

1
2
3
4
5

Becomes, when removing the third item:

1
2
4
5

So if you remove the third then fourth items from (1,2,3,4,5), you remove values 3 and 5.

Start at the end of the list and work towards element 0.

for i = list.count - 1 to 0 step -1
    list.removeAt( i )
next
Bob Kaufman
That did it, thanks!
Cyclone
A: 

Your assertion about the first code sample is wrong. row.Index is already an Integer, you don't need to call ToString on it, and then convert it back to an Int with CInt.

If you really want to remove everything, try DGV.Rows.Clear()

Scott Ferguson
That method does not function in this case, as I do not want it to expressly clear every row, this was just the example I gave.
Cyclone
A: 

You are altering the collection that you are iterating over, so it's not very surprising that it's not working properly.

What's a little more surprising is that you actually manage to iterate over the collection at all while altering it. For any other collection the Enumerator would be invalidated when you alter the collection, but the Rows collection seems to work differently.

Still, eventhough you manage to iterate the collection while altering it, it doesn't work properly. When you remove the item at index 0, the next item takes it's place. When you then go on to remove the item at index 1, that is the item that was initially at index 2. That leaves every second item in the collection when you have looped through them.

To remove the items one at a time you can loop backwards, that way when you remove an item it doesn't affect the position of any other item:

For i As Integer = DGV.Rows.Count -1 To 0 Step -1
   Dgv.Rows.RemoveAt(i)
Next

You can also remove the item at index 0 as long as there are any items left:

While Dgv.Rows.Count > 0
   Dgv.Rows.RemoveAt(0)
End While

However, the easiest way to remove all items is of course to call the Clear method:

Dgv.Rows.Clear()
Guffa