Trouble moving rows in DGV

timh

Well-known member
Joined
Nov 28, 2008
Messages
50
Programming Experience
Beginner
I probably am missing something blindingly obvious here, but try as I might, I can't find the solution to this issue...

I have a DGV bound to a bindingsource. I want to be able to move rows within the DGV, each of which has a "classindex" column. The bindingsource is sorted on this column.

I tried programming a drag-drop system to re-order the rows, but ended up with two buttons btnMoveUp and btnMoveDown.

What is supposed to happen when you click "Up" is that the selected row "classindex" value swaps with the row above and so moves up one row. The opposite happens with the "Down" button.

All works fine until you click "Up" after clicking "Down" or vice versa. It all seems to go a bit pear shaped then and I can't work out why.

Here is my code for the two buttons...

intRowSelected is declared as a public integer

VB.NET:
    Private Sub btnMoveUp_Click(sender As Object, e As EventArgs) Handles btnMoveUp.Click

        With dgvEventcategories
            intRowSelected = .CurrentRow.Index
            If intRowSelected = 0 Then Exit Sub ' top of list
            Dim intTemp As Integer = .Rows.Item(intRowSelected - 1).Cells("classindex").Value
            .Rows.Item(intRowSelected - 1).Cells("classindex").Value = .Rows.Item(intRowSelected).Cells("classindex").Value
            .Rows.Item(intRowSelected).Cells("classindex").Value = intTemp
            .CurrentCell = .Rows.Item(intRowSelected - 1).Cells("classindex")
            .CurrentRow.Selected = True
        End With

    End Sub

    Private Sub btnMoveDown_Click(sender As Object, e As EventArgs) Handles btnMoveDown.Click

        With dgvEventcategories
            intRowSelected = .CurrentRow.Index
            If intRowSelected = EventcategoriesBindingSource.Count - 1 Then Exit Sub ' end of list
            Dim intTemp As Integer = .Rows.Item(intRowSelected + 1).Cells("classindex").Value
            .Rows.Item(intRowSelected + 1).Cells("classindex").Value = .Rows.Item(intRowSelected).Cells("classindex").Value
            .Rows.Item(intRowSelected).Cells("classindex").Value = intTemp
            .CurrentCell = .Rows.Item(intRowSelected + 1).Cells("classindex")
            .CurrentRow.Selected = True
        End With

    End Sub

Can someone spot the flaw please??

Thanks.

Tim
 
You should not be touching the grid at all. That's exactly why you use a BindingSource. Here's code for moving up:
VB.NET:
Dim currentRow = DirectCast(myBindingSource.Current, DataRowView)
Dim previousRow = DirectCast(myBindingSource(myBindingSource.Position - 1), DataRowView)
Dim currentClassIndex = CInt(currentRow("ClassIndex"))
Dim previousClassIndex = CInt(previousRow("ClassIndex"))

currentRow("ClassIndex") = previousClassIndex
previousRow("ClassIndex") = currentClassIndex
I'll let you work out the code to move down.
 
Sorted, thanks!

Thanks! A minor tweak needed to keep the selection on the row being moved and I worked out the opposite direction ;-)

This is what I've ended up with:

VB.NET:
    Private Sub reorder(sender As Object, e As EventArgs) Handles btnMoveUp.Click, btnMoveDown.Click

        Dim currentRow = DirectCast(EventcategoriesBindingSource.Current, DataRowView)
        Dim currentClassIndex = CInt(currentRow("index"))

        Select Case sender.name
            Case "btnMoveUp"
                If EventcategoriesBindingSource.Position <= 1 Then Exit Sub ' 0 index row must not be moved
                Dim previousRow = DirectCast(EventcategoriesBindingSource(EventcategoriesBindingSource.Position - 1), DataRowView)
                Dim previousClassIndex = CInt(previousRow("index"))
                currentRow("index") = previousClassIndex
                previousRow("index") = currentClassIndex
                EventcategoriesBindingSource.Position = previousClassIndex
            Case "btnMoveDown"
                If EventcategoriesBindingSource.Position = 0 Then Exit Sub ' 0 index row must not be moved
                If EventcategoriesBindingSource.Position = EventcategoriesBindingSource.Count - 1 Then Exit Sub ' can't move below last index
                Dim nextRow = DirectCast(EventcategoriesBindingSource(EventcategoriesBindingSource.Position + 1), DataRowView)
                Dim nextClassIndex = CInt(nextRow("index"))
                currentRow("index") = nextClassIndex
                nextRow("index") = currentClassIndex
                EventcategoriesBindingSource.Position = nextClassIndex
        End Select

    End Sub

Working perfectly, so thanks again.

Tim
 
Back
Top