Removing rows from an Unbound DataGridView?

I have 2 DataGridViews on a form. The 2nd DGV is manually loaded based on selections from the 1st DGV. My problem is that when I go to remove the rows (I click on a button) in the 2nd DGV, it removes all but 2 rows and what's even stranger and I'm not sure why this happens is that when I go to add rows again to the 2nd DGV, there are blank rows representing the deleted rows as well as the new rows. I hope this makes sense.

Anyway, I need to be able to permanently remove all the rows at once or just selected ones. Below is the code that I use for removing all rows.

            If dgvSTSelectedEquipment.Rows.Count > 0 Then
                For Each row As DataGridViewRow In dgvSTSelectedEquipment.Rows
                      dgvSTSelectedEquipment.Rows.Remove(row)
                Next
            End If
BlakeMcKennaAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Jacques Bourgeois (James Burger)PresidentCommented:
Instead of looping, simply call dgvSTSelectedEquipment.Rows.Clear.

If you still have the problem, it might be because one of the rows is currently in editing mode. Move the cursor to another row before going into your loop.
0
käµfm³d 👽Commented:
I agree with the above, but to give you a bit more information...

The reason you get the error is that you cannot remove items from a collection that you are iterating over. In order to remove from a collection that you are iteration over, you need to use a reverse For loop.

e.g.

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

Open in new window

0
Jacques Bourgeois (James Burger)PresidentCommented:
1 little mistake and one important omission in your first line kaufmed:

For i As Integer = dgvSTSelectedEquipment.Rows.Count - 1 To 0 Step -1
0
C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

käµfm³d 👽Commented:
Agreed  = )
0
BlakeMcKennaAuthor Commented:
That works fine if you one to delete one at a time. However, I wish to click a button and delete all rows at one time. Plus, once all the rows are cleared and I decide to enter 1 or more new rows, the other rows appear to have not actually been removed as you can see in the screenshots. Here is my code.


                If dgvSTSelectedEquipment.Rows.Count > 0 Then
                     For i As Integer = dgvSTSelectedEquipment.Rows.Count = -1 To 0 Step -1
                           dgvSTSelectedEquipment.Rows.RemoveAt(i)
                     Next
                End If
screenshot1.jpg
screenshot2.jpg
0
BlakeMcKennaAuthor Commented:
I responded to the wrong post. This is still an issue.
0
Jacques Bourgeois (James Burger)PresidentCommented:
Go back to my answer : Instead of looping, simply call dgvSTSelectedEquipment.Rows.Clear.

kaufmed explained why your code did not work and gave you a general way of solving that type of problem. This is something useful to have in your bag of tricks.

But when a collection does have a Clear method, it is usually the best way to go. It should solve your problem, but is also faster because you are accessing the collection only once instead of doing it repetitively in a loop.
0
BlakeMcKennaAuthor Commented:
I tried your suggestion and it did clear the rows, however, it's as if it's keeping the rows in memory because when I go to add a new row, this is what happens. See attached image. I added 5 rows before I cleared it and then added another, which you see in the screenshot.
screenshot1.jpg
0
Jacques Bourgeois (James Burger)PresidentCommented:
I do not have VS available right now, so I cannot check, but I would try to call the Refresh method on the grid after the Clear.

Also, I do not personally work with data binding in my grids, but if your grid is binded to a datasource (collection, datatable...), it is possible that it still someway see the old source. I would try to first set the DataSource property to Nothing, and then reset it to a new empty source.
0
BlakeMcKennaAuthor Commented:
Hi James,

I tried doing the refresh and also setting the Grids Datasource to nothing and that didn't to the trick either. The Grid is not bound to a datasource. Basically, the way it works is that I select a row of data from another grid and simply take some of that data from that Grid and create a new row in the Grid in question. So it's not bound by a DataTable/DataSet or anything like that. It's just a straight dgv.rows.add(row) type of thing.

There's never a dull moment with my code!!! LOL
0
BlakeMcKennaAuthor Commented:
Here is the code in which I actually add the row to the DGV.

        Private Sub LoadSelectedEquipmentList()
        Try
            iSelectedEquipmentCount += 1
            dgvSTSelectedEquipment.RowCount = iSelectedEquipmentCount

            dgvSTSelectedEquipment.Rows(iSelectedEquipmentCount - 1).Cells(0).Value = stSE.ID
            dgvSTSelectedEquipment.Rows(iSelectedEquipmentCount - 1).Cells(1).Value = stSE.type
            dgvSTSelectedEquipment.Rows(iSelectedEquipmentCount - 1).Cells(2).Value = stSE.equipName
            dgvSTSelectedEquipment.Rows(iSelectedEquipmentCount - 1).Cells(3).Value = stSE.SN
            dgvSTSelectedEquipment.Rows(iSelectedEquipmentCount - 1).Cells(4).Value = stSE.description
            dgvSTSelectedEquipment.Rows(iSelectedEquipmentCount - 1).Cells(5).Value = stSE.equipID

        Catch ex As Exception
            strErr = gfrmID & "/LoadSelectedEquipmentList() - " & ex.Message
            MessageBox.Show(strErr, "User Notification", MessageBoxButtons.OK)
        End Try
    End Sub
0
Jacques Bourgeois (James Burger)PresidentCommented:
Might have got it with your code, but I am not quite sure, because you use something that I never did, set the RowCount. I was even very surprised to see that it is not ReadOnly when I did a quick research to prepare this comment. This would be standard for most collections. I usually use DataGridView.Rows.Add when I want to add a new row, and DataGridView.Rows.Clear works well in such a case.

According to the documentation, "If RowCount is set to a value greater than the current value, rows will be added to the end of the Rows collection". My guess is that when you Clear the Rows, the RowCount stays at the last value it had and the rows are recreated as empty rows.

Try setting back RowCount to 0. According to the documentation, "If you set the RowCount property to 0, all rows will be removed from the DataGridView".
0
BlakeMcKennaAuthor Commented:
I tried that and it still didn't work. I have never had this issue before but then again, this is the first time I've tried adding rows to a DGV in this way. This is what I had in the Button_Click Event.

        Private Sub btnSTClearSelections2_Click(sender As Object, e As EventArgs) Handles btnSTClearSelections2.Click
        Try
            If dgvSTSelectedEquipment.Rows.Count > 0 Then
                dgvSTSelectedEquipment.Rows.Clear()
                dgvSTSelectedEquipment.DataSource = Nothing
                dgvSTSelectedEquipment.RowCount = 0
            End If

        Catch ex As Exception
            strErr = gfrmID & "/btnSTClearSelections2_Click() - " & ex.Message
            MessageBox.Show(strErr, "User Notification", MessageBoxButtons.OK)
        End Try
    End Sub

None of this code worked. The DGV somehow still retained in memory the number of rows that were initially added. Did you see the post above your last one. That is how I actually add a row to the DGV. Not sure if that has anything to do with it but it seems pretty straight forward.
0
Jacques Bourgeois (James Burger)PresidentCommented:
Yes, I saw your post, and this is what triggered my discussion about the RowCount. Unfortunately, I am on a business trip and do not have access to Visual Studio in my hotel room, so I cannot test anything.

As I told you in my last post, I do not use RowCount as you do. I use it only to request the information, not to set the number of rows. Personnally, when I want to add a row I do as in most collection, I use the Add method.

You might try dgvSTSelectedEquipment.Rows.Add instead of setting the RowCount. I never encoutered your problem doing so, and I have been working with .NET since 2000 (although the DataGridView was not there at the beginning. It was added to the Framework after a few versions, possibly in 2005).

If this still does not work, then I am sorry, there is nothing else I could add without running the code and examining the situation in the debugger, in order of maybe finding a clue somewhere in there.
0
BlakeMcKennaAuthor Commented:
No worries James...I'll fiddle around with it some more...

Thanks!
0
BlakeMcKennaAuthor Commented:
I figured it out.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
BlakeMcKennaAuthor Commented:
I finally figured it out thru trial and error.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic.NET

From novice to tech pro — start learning today.