Home > Blockchain >  Move Up/Down row in a binding datagridview
Move Up/Down row in a binding datagridview

Time:09-11

I want to develop an up/down row feature inside a binded datagridview (I found some examples but only with unbinded datagridview)

Here's my code:

Private Sub dtgHashtagDescripteurs_KeyUp(ByVal sender As Object, ByVal e As KeyEventArgs) Handles dtgHashtagDescripteurs.KeyUp
        Dim tblUpdatedDataSource As DataTable

        If e.KeyCode.Equals(Keys.Up) Then
            Dim intSelectedRowIndex As Integer = dtgHashtagDescripteurs.CurrentCell.RowIndex
            If intSelectedRowIndex = 0 Then
                Exit Sub
            Else
                tblUpdatedDataSource = TryCast(MoveRowFromDataGridView(dtgHashtagDescripteurs, intSelectedRowIndex, "up"), Datatable)
            End If
            With dtgHashtagDescripteurs
                .DataSource = Nothing
                .Refresh()
                .DataSource = tblUpdatedDataSource
                .Refresh()
            End With
        End If
End Sub
Public Function MoveRowFromDataGridView(dgvToReorder As DataGridView, intSelectedRowIndex As Integer, strDirection As String) As DataTable
        Dim tblSource As New DataTable
        Dim rowToMove As DataRow
        Dim rowCount As Integer
        Dim rowsCollection As DataRowCollection

        tblSource = TryCast(dgvToReorder.DataSource, DataTable)

        If tblSource.Rows.Count > 0 Then
            rowCount = tblSource.Rows.Count
            rowsCollection = tblSource.Rows
            If strDirection = "up" Then
                rowToMove = rowsCollection(intSelectedRowIndex)
                rowsCollection.Remove(rowToMove)
                rowsCollection.InsertAt(rowToMove, intSelectedRowIndex - 1)
            ElseIf strDirection = "down" Then
                rowToMove = rowsCollection(intSelectedRowIndex)
                rowsCollection.Remove(rowToMove)
                rowsCollection.InsertAt(rowToMove, intSelectedRowIndex   1)
            End If
        End If        
        Return tblSource
End Function

Several questions:

  1. In debugging mode, when the app runs in MoveRowFromDataGridView, tblSource got rows correctly sorted but got nothing once back MoveRowFromDataGridView.

  2. Updates to rowsCollection seems to pass on tblSource. Is there a way to prevent from that?

  3. An other weird thing is the line tblUpdatedDataSource = TryCast(MoveRowFromDataGridView(dtgHashtagDescripteurs, intSelectedRowIndex, "up"), Datatable) If I code like this: tblUpdatedDataSource = MoveRowFromDataGridView(dtgHashtagDescripteurs, intSelectedRowIndex, "up") I have an error "Option Strict On disallows implicit conversions from Datatable to Datatable"

CodePudding user response:

I finally found how to do this. I guess there would be more effective and elegant ways to do this, but this one works.

The user is allowed to move up/down row from the datagridview (called dtgHashtagDescripteurs) only if the text of button (in the same form where the datagridview is) is equal to "Ajouter" or "Modifier".

Private Sub dtgHashtagDescripteurs_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs) Handles dtgHashtagDescripteurs.KeyDown

        Dim tblUpdatedDataSource As New System.Data.DataTable()

        If Me.btnHashtagValidate.Text = "Valider" Or Me.btnHashtagValidate.Text = "Ajouter" Then
            If e.KeyCode.Equals(Keys.Down) Or e.KeyCode.Equals(Keys.Up) Then
                Dim intSelectedRowIndex As Integer = dtgHashtagDescripteurs.CurrentCell.RowIndex
                If intSelectedRowIndex = dtgHashtagDescripteurs.Rows.Count Then
                    Exit Sub
                Else
                    If e.KeyCode.Equals(Keys.Down) Then
                        tblUpdatedDataSource = TryCast(MoveRowFromDataGridView(dtgHashtagDescripteurs, intSelectedRowIndex, "down"), System.Data.DataTable)
                    ElseIf e.KeyCode.Equals(Keys.Up) Then
                        tblUpdatedDataSource = TryCast(MoveRowFromDataGridView(dtgHashtagDescripteurs, intSelectedRowIndex, "up"), System.Data.DataTable)
                    End If
                    With dtgHashtagDescripteurs
                        .AutoGenerateColumns = False
                        .DataSource = Nothing
                        .Columns.Clear()
                        .Refresh()
                        .DataSource = tblUpdatedDataSource
                        .AutoGenerateColumns = True
                        .Columns(0).HeaderText = "Libellé"
                        .Columns(0).Name = "libelle"
                        .Columns(0).Width = CInt(.Width / 3)
                        .Columns(1).HeaderText = "Précision Indexation"
                        .Columns(1).Name = "precision_indexation"
                        .Columns(1).Width = CInt(.Width / 3)
                        .Columns(2).HeaderText = "Reference"
                        .Columns(2).Name = "reference"
                        .Columns(2).Width = CInt(.Width / 3)
                        .ReadOnly = False
                        .Refresh()
                    End With
                    For i = dtgHashtagDescripteurs.Columns.Count - 1 To 0 Step -1
                        If i = 1 Then
                            dtgHashtagDescripteurs.Columns(i).ReadOnly = False
                        Else
                            dtgHashtagDescripteurs.Columns(i).ReadOnly = True
                        End If
                    Next
                End If
            End If
        End If
        e.Handled = True
    End Sub

Public Function MoveRowFromDataGridView(dgvToReorder As DataGridView, intSelectedRowIndex As Integer, strDirection As String) As System.Data.DataTable

        Dim newIndex As Integer
        Dim tblToReorder As New DataTable
        Dim colDescripteursLibelle As New DataColumn("libelle", GetType(String))
        Dim colDescripteursReference As New DataColumn("precision_indexation", GetType(String))
        Dim colDescripteursPrecision As New DataColumn("reference", GetType(String))
        Dim lstDescripteursToReorder As List(Of Descripteur) = New List(Of Descripteur)()

        tblToReorder.Columns.Add(colDescripteursLibelle)
        tblToReorder.Columns.Add(colDescripteursReference)
        tblToReorder.Columns.Add(colDescripteursPrecision)


        If strDirection = "up" Then
            newIndex = intSelectedRowIndex - 1
        ElseIf strDirection = "down" Then
            newIndex = intSelectedRowIndex   1
        End If

        If dgvToReorder.DataSource IsNot Nothing Then
            tblToReorder = CType(dgvToReorder.DataSource, DataTable)
            tblToReorder.Columns(0).ColumnName = "libelle"
            tblToReorder.Columns(1).ColumnName = "precision_indexation"
            tblToReorder.Columns(2).ColumnName = "reference"
        Else
            tblToReorder = GetDataTableFromDataGridView(dgvToReorder)
        End If

        If strDirection = "up" And intSelectedRowIndex = 0 Then
            Return tblToReorder
        End If
        If strDirection = "down" And intSelectedRowIndex = dgvToReorder.Rows.Count - 1 Then
            Return tblToReorder
        End If

        For i As Integer = 0 To tblToReorder.Rows.Count - 1
            Dim descripteurToCopy As New Descripteur
            If tblToReorder.Rows(i)("precision_indexation").ToString Is Nothing Then
                descripteurToCopy.strPrecisionIndexation = Nothing
            Else
                descripteurToCopy.strPrecisionIndexation = CStr(tblToReorder.Rows(i)("precision_indexation").ToString)
            End If
            descripteurToCopy.intReference = CInt(tblToReorder.Rows(i)("reference"))
            descripteurToCopy.strLibelle = CStr(tblToReorder.Rows(i)("libelle"))
            lstDescripteursToReorder.Add(descripteurToCopy)
        Next

        Dim descripteurToMove As Descripteur = lstDescripteursToReorder(intSelectedRowIndex)
        Dim descripteurInTarget As Descripteur = lstDescripteursToReorder(newIndex)

        lstDescripteursToReorder.Remove(descripteurToMove)
        lstDescripteursToReorder.Insert(newIndex, descripteurToMove)
        lstDescripteursToReorder.Remove(descripteurInTarget)
        lstDescripteursToReorder.Insert(intSelectedRowIndex, descripteurInTarget)

        Return ListToDataTable(lstDescripteursToReorder)

    End Function

 Public Function ListToDataTable(Of T)(ByVal items As List(Of T)) As DataTable
        Dim dataTable As DataTable = New DataTable(GetType(T).Name)
        Dim Props As PropertyInfo() = GetType(T).GetProperties(BindingFlags.[Public] Or BindingFlags.Instance)

        For Each prop As PropertyInfo In Props
            Dim type = (If(prop.PropertyType.IsGenericType AndAlso prop.PropertyType.GetGenericTypeDefinition() = GetType(Nullable(Of)), Nullable.GetUnderlyingType(prop.PropertyType), prop.PropertyType))
            dataTable.Columns.Add(prop.Name, type)
        Next

        For Each item As T In items
            Dim values = New Object(Props.Length - 1) {}

            For i As Integer = 0 To Props.Length - 1
                values(i) = Props(i).GetValue(item, Nothing)
            Next

            dataTable.Rows.Add(values)
        Next

        Return dataTable
End Function
  • Related