Datatable (DatatGridView) MoveLineUP - is my solution rubbish ?

chris_asa

Active member
Joined
Sep 4, 2009
Messages
26
Location
Switzerland
Programming Experience
10+
I have the following code to move a line up in the ....datagridview (datatable, (database)):

VB.NET:
            If Not Me.dgvLines.CurrentRow Is Nothing Then
                Dim i As Integer = Me.dgvLines.CurrentRow.Index
                If i > 0 Then
                    With CurrentCase.Lines
                        Dim u As Integer = .Rows(i - 1).Item("LineSort")
                        Dim d As Integer = .Rows(i).Item("LineSort")
                        .Rows(i - 1).Item("LineSort") = d
                        .Rows(i).Item("LineSort") = u
                        .AcceptChanges()
                    End With
                    Me.dgvLines.Sort(Me.dgvLines.Columns("LineSort"), System.ComponentModel.ListSortDirection.Ascending)
                    IsDirty = True
                    Me.dgvLines.Rows(i - 1).Selected = True
                End If
           End If


CurrentCase object contains a disconnected datatable .Lines
CurrentCase.Lines.Columns("LineSort") is there to persist the desired line-sequence at the db

dgvLines is a datagridview <-- bindingsource <-- datatable (CurrentCase.Lines)

IsDirty is a Private form Boolean that eventually triggers an update to the DB in code elsewhere.


Is there a neater solution than u, d ?
Is dgvLines.Sort the best way through this ?


regards Chris
 
That's basically the way I'd go as well except that I wouldn't call Sort grid but rather set the Sort of the BindingSource and just let it happen of its own accord thereafter. Also, is that AcceptChanges call really appropriate?
 
Thanks for the reply.

BindingSource.Sort does indeed seem attractive (and, for now, I'll forgo the .AcceptChanges).

However, I'm having MANY issues that I can't yet diagnose / explain / reliably repeat.
It often seems to work correctly, but bizarre things happen if:
- I select-moveup-moveup
- I select-moveup, select-moveup, select-moveup, selectLastRow-moveup

Bizarre might be:
row stupidity: 1,2,3,4,5 with 5 selected after moveup becomes 1,2,5,4,3
row madness: 1,2,3,4,5 with 5 selected after moveup becomes 1,2,5,4,3 and after another moveup 1,2,3,4,5 and another moveup 1,2,5,4,3 etc
sometimes combined with
my MultiSelect=False dgv ends up with a strange selection: one row highlit (no ">") plus another row (with ">") and the first .visible cell selected

Where does the Bindingsource.Sort take place? The UI-Thread?


Anyhow, it's brains are scrambled and I need to devote a few(?) hours to try to understand what is going on.
Fun!

regards Chris

Here's the code that smells (no errors thrown):

The moveup
VB.NET:
            If Not Me.dgvLines.CurrentRow Is Nothing Then
                Dim i As Integer = Me.dgvLines.CurrentRow.Index
                If i > 0 Then
                    With CurrentCase.Lines
                        Dim u As Integer = .Rows(i - 1).Item("LineSort")
                        Dim d As Integer = .Rows(i).Item("LineSort")
                        .Rows(i - 1).Item("LineSort") = d
                        .Rows(i).Item("LineSort") = u

                        'forget AcceptChanges for now
                        '.AcceptChanges()

                    End With

                    'forget dgv sort for now, and try bs.sort
                    'Me.dgvLines.Sort(Me.dgvLines.Columns("LineSort"), System.ComponentModel.ListSortDirection.Ascending)

                    IsDirty = True
                    'Me.dgvLines.Rows(i - 1).Selected = True

                End If
            End If

and the dgv init code:
VB.NET:
            With Me.dgvLines

                '// remove any existing rows
                '.Rows.Clear()

                '// define binding source
                Dim bs As BindingSource = New BindingSource
                bs.DataSource = CurrentCase.Lines
                bs.Sort = "LineSort ASC"

                '// populate new rows
                .DataSource = bs
 
E.g.
Public Class Form1

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Dim table As New DataTable

        With table.Columns
            .Add("ID", GetType(Integer))
            .Add("Name", GetType(String))
            .Add("Ordinal", GetType(Integer))
        End With

        With table.Rows
            .Add(1, "Peter", 1)
            .Add(2, "Paul", 2)
            .Add(3, "Mary", 3)
            .Add(4, "John", 4)
            .Add(5, "Jenny", 5)
            .Add(6, "Linda", 6)
        End With

        With BindingSource1
            .DataSource = table
            .Sort = "Ordinal"
        End With

        DataGridView1.DataSource = BindingSource1
    End Sub

    Private Sub BindingSource1_CurrentChanged(sender As System.Object, e As System.EventArgs) Handles BindingSource1.CurrentChanged
        moveUpButton.Enabled = (BindingSource1.Position > 0)
        moveDownButton.Enabled = (BindingSource1.Position < BindingSource1.Count - 1)
    End Sub

    Private Sub moveUpButton_Click(sender As System.Object, e As System.EventArgs) Handles moveUpButton.Click
        Dim currentRow = DirectCast(BindingSource1.Current, DataRowView)
        Dim previousRow = DirectCast(BindingSource1(BindingSource1.Position - 1), DataRowView)
        Dim ordinal = currentRow("Ordinal")

        currentRow("Ordinal") = previousRow("Ordinal")
        previousRow("Ordinal") = ordinal

        BindingSource1.EndEdit()
    End Sub

    Private Sub moveDownButton_Click(sender As System.Object, e As System.EventArgs) Handles moveDownButton.Click
        Dim currentRow = DirectCast(BindingSource1.Current, DataRowView)
        Dim nextRow = DirectCast(BindingSource1(BindingSource1.Position + 1), DataRowView)
        Dim ordinal = currentRow("Ordinal")

        currentRow("Ordinal") = nextRow("Ordinal")
        nextRow("Ordinal") = ordinal

        BindingSource1.EndEdit()
    End Sub

End Class
 
Huge thanks for the e.g.

It is a copy/paste solution to my problem. More importantly, it tells me that I need to spend a couple of days getting to grips with all the good things BindingSource has to offer before I start pecking at the keyboard again.

regards Chris
 
Back
Top