在作为DataGridView的数据源的排序DataTable中上下移动Rows不会更新View。

问题描述 投票:1回答:1

我在网上看了一下,我看到很多不同的类似东西的帖子。 我的代码能正确移动行。事情是这样的。我按 "上 "或 "下 "按钮 选定的行就会相应移动 如果我点击我刚刚移动的行,然后我试图把它移回来,它就会按照数据表的DefaultView排序顺序移动它,但是位置的变化并没有反映在DataGridView中。

如果我选择了一个我从未移动过的Row,它将会移动它,DataGridView也会反映出来,但是如果我再次选择同一行并尝试将它移回来,这个变化并没有反映在View中,但是DataTable被更新了。

我已经尝试过 ResetBindings, DataGridView.Refresh重置DataSource:这些都没有用。

有谁知道为什么会发生这种情况,以及我怎样才能修复它,使它每次都能反映变化?

 Private Sub UpBtn_Click(sender As Object, e As EventArgs) Handles UpBtn.Click
    MoveUpDataRow(StepDGV.CurrentRow.Index)
End Sub

Private Sub MoveUpDataRow(RowIndex As Integer)
    Dim OriginalStepNumber As Integer
    Dim dv As DataView = StepsData.DefaultView

    OriginalStepNumber = CInt(StepDGV.Rows(RowIndex).Cells("StepIDLS").Value)

    If RowIndex = 0 Then
        'dv(RowIndex - 1)("StepIDLS") = OriginalStepNumber + 1
        'dv(RowIndex)("StepIDLS") = OriginalStepNumber - 1
        exit Sub
    Else

        dv(RowIndex - 1).BeginEdit()
        dv(RowIndex - 1)("StepIDLS") = OriginalStepNumber
        'dv(RowIndex)("StepIDLS") = RowIndex-1
        dv(RowIndex - 1).EndEdit()

        dv(RowIndex).BeginEdit()
        dv(RowIndex)("StepIDLS") = OriginalStepNumber - 1
        'dv(RowIndex)("StepIDLS") = RowIndex-1
        dv(RowIndex).EndEdit()

    End If
    dv.Sort = "StepIDLS ASC"
  '  StepDGV.Rows(RowIndex).Selected = true
    'StepDGV.DataSource = StepsData
    'StepDGV.Refresh()
    StepDGV.ResetBindings()
    StepDGV.Refresh()

End Sub


Private Sub downBtn_Click(sender As Object, e As EventArgs) Handles downBtn.Click
    MoveDownDataRow(StepDGV.CurrentRow.Index)
End Sub

Private Sub MoveDownDataRow(RowIndex As Integer)
    Dim OriginalStepNumber As Integer
    Dim dv As DataView = StepsData.DefaultView

    OriginalStepNumber = CInt(StepDGV.Rows(RowIndex).Cells("StepIDLS").Value)

    If RowIndex = dv.Count - 1 Then
        exit Sub
    Else

        dv(RowIndex + 1).BeginEdit()
        dv(RowIndex + 1)("StepIDLS") = OriginalStepNumber
        dv(RowIndex + 1).EndEdit()

        dv(RowIndex).BeginEdit()
        dv(RowIndex)("StepIDLS") = OriginalStepNumber + 1
        dv(RowIndex).EndEdit()

    End If
    dv.Sort = "StepIDLS ASC"
  '  StepDGV.Rows(RowIndex).Selected = true
    'StepDGV.Refresh()
    'StepDGV.DataSource = StepsData
    'StepDGV.Refresh()
    StepDGV.ResetBindings()
    StepDGV.Refresh()

End Sub[![screenshot of datagridview for visual aid when going through code][1]][1]
vb.net winforms datatable datagridview dataview
1个回答
1
投票

由于你有一个排序的DataView,使用相同的Index引用来设置两个连续的值,可能(将)会有未定义的结果,如果你在两个不同的位置上移动,结果会更多。方向.

方法1.从当前DataView中获取两个DataRow的引用,然后使用DataRow引用改变Column的值。

从当前DataView中获取两个DataRow的引用,然后使用DataRow引用改变一个Column的值,这样做更简单(也更实用):即使DataRow在排序DataView中的位置发生了变化,DataRow引用也是一样的。

你不需要BeginEditEndEdit一个Cell值,这些变化会自动传播。

► 在这里,我使用同样的 Button.Click 处理程序,并根据Button的名称确定方向(可以是其他任何适合的名称)。

► 这一行。Dim dView = DirectCast(StepDGV.DataSource, DataTable).DefaultView 如果你已经存储了一个DataTable对象(就像它看起来那样),那么这行:是不必要的。如果是这样,当然要使用你已经拥有的DataTable引用。

► 假设你已经设置了 StepsData.DefaultView.Sort = "StepIDLS ASC" 在这之前。

Private Sub btnMoveRowUpDown_Click(sender As Object, e As EventArgs) Handles UpBtn.Click, downBtn.Click
    If StepDGV.CurrentRow Is Nothing Then Return

    Dim moveUp As Boolean = DirectCast(sender, Button).Name.Equals("UpBtn")

    Dim currentRow As Integer = StepDGV.CurrentCell.RowIndex
    Dim dView = DirectCast(StepDGV.DataSource, DataTable).DefaultView
    Dim rowCurrent = dView(currentRow).Row
    Dim colCurrentValue As Integer = CType(rowCurrent("StepIDLS"), Integer)

    If moveUp Then
        If currentRow = 0 Then Return

        Dim rowPrevious = dView(currentRow - 1).Row
        Dim colPreviousValue As Integer = CType(rowPrevious("StepIDLS"), Integer)
        rowCurrent("StepIDLS") = colPreviousValue
        rowPrevious("StepIDLS") = colCurrentValue
    Else
        If currentRow = StepDGV.NewRowIndex - 1 Then Return

        Dim rowNext = dView(currentRow + 1).Row
        Dim colNextValue As Integer = CType(rowNext("StepIDLS"), Integer)
        rowCurrent("StepIDLS") = colNextValue
        rowNext("StepIDLS") = colCurrentValue
    End If
End Sub

方法2.设置DataGridView Cells值。

你可以做一些类似设置DataGridView Cells值的事情。在这种情况下,你确实需要调用 DataGridView.EndEdit() 来通知更改,因此更改会立即发生。否则,值的变化会在焦点离开了 CurrentCell.

这里的注意事项。Bound DataGridView没有更新显示信息+排序问题。 在类似的情况下也可能有用(当你必须直接设置DataGridView Cells时)。

你还可以注意到,设置DataRow Colums值也会改变DataGridView的 CurrentRow (不仅是 CurrentCell),而在DataGridView中设置单元格的值时,并不会造成 CurrentRow 要改变,所以你必须自己动手,设。

[DataGridView].CurrentCell = [DataGridView].Rows(currentRow + 1).Cells(currentColumn)

Private Sub btnMoveRowUpDown_Click(sender As Object, e As EventArgs) Handles UpBtn.Click, downBtn.Click
    If StepDGV.CurrentRow Is Nothing Then Return

    Dim moveUp As Boolean = DirectCast(sender, Button).Name.Equals("UpBtn")

    Dim currentRow As Integer = StepDGV.CurrentCell.RowIndex
    Dim currentColumn As Integer = StepDGV.CurrentCell.ColumnIndex
    Dim currentCellValue As Integer = CType(StepDGV("StepIDLS", currentRow).Value, Integer)

    If moveUp Then
        If currentRow = 0 Then Return 
        Dim previousCellValue As Integer = CType(StepDGV("StepIDLS", currentRow - 1).Value, Integer)

        StepDGV.Rows(currentRow).Cells("StepIDLS").Value = previousCellValue
        StepDGV.EndEdit()
        StepDGV.Rows(currentRow - 1).Cells("StepIDLS").Value = currentCellValue
        StepDGV.EndEdit()
        StepDGV.CurrentCell = StepDGV.Rows(currentRow - 1).Cells(currentColumn)
    Else
        If currentRow = StepDGV.NewRowIndex - 1 Then Return 
        Dim nextCellValue As Integer = CType(StepDGV("StepIDLS", currentRow + 1).Value, Integer)

        StepDGV.Rows(currentRow).Cells("StepIDLS").Value = nextCellValue
        StepDGV.EndEdit()
        StepDGV.Rows(currentRow + 1).Cells("StepIDLS").Value = currentCellValue
        StepDGV.EndEdit()
        StepDGV.CurrentCell = StepDGV.Rows(currentRow + 1).Cells(currentColumn)
    End If
End Sub
© www.soinside.com 2019 - 2024. All rights reserved.