Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net 在排序数据表集中上下移动行作为DataGridView的数据源不会更新视图_Vb.net_Winforms_Datatable_Datagridview_Dataview - Fatal编程技术网

Vb.net 在排序数据表集中上下移动行作为DataGridView的数据源不会更新视图

Vb.net 在排序数据表集中上下移动行作为DataGridView的数据源不会更新视图,vb.net,winforms,datatable,datagridview,dataview,Vb.net,Winforms,Datatable,Datagridview,Dataview,我在网上看过很多类似的帖子。我的代码正确地移动了行。 结果如下:我按下向上或向下按钮,所选行相应移动。 如果我单击刚刚移动的行并尝试将其移回,它将按照DataTable的DefaultView排序顺序移动它,但位置更改不会反映在DataGridView中 如果我选择一个从未移动过的行,它将移动该行,DataGridView将反映该行,但如果我再次选择同一行并尝试将其移回,该更改不会反映在视图中,但DataTable会更新 我尝试了重置绑定,数据网格视图。刷新,重置数据源:这些都不起作用 有人知道

我在网上看过很多类似的帖子。我的代码正确地移动了行。 结果如下:我按下向上或向下按钮,所选行相应移动。
如果我单击刚刚移动的行并尝试将其移回,它将按照DataTable的DefaultView排序顺序移动它,但位置更改不会反映在DataGridView中

如果我选择一个从未移动过的行,它将移动该行,DataGridView将反映该行,但如果我再次选择同一行并尝试将其移回,该更改不会反映在视图中,但DataTable会更新

我尝试了
重置绑定
数据网格视图。刷新
,重置数据源:这些都不起作用

有人知道为什么会发生这种情况,以及我如何修复它,使它每次都反映出变化吗

 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]

由于您有一个排序数据视图,使用相同的索引引用设置两个连续的值,可能(将)有未定义的结果,如果您向两个不同的方向移动,结果甚至更多

方法1:

从当前DataView中获取两个DataRow的引用,然后使用DataRow引用更改列的值更简单(而且更实用):即使排序DataView中的DataRow位置更改,DataRow引用也是相同的

您不需要开始编辑/结束编辑单元格值,这些更改会自动传播

► 在这里,我使用的是相同的
按钮。单击这两个按钮的
处理程序,并根据按钮名称确定方向(可以是任何其他适合的)

► 此行:
Dim dView=DirectCast(StepDGV.DataSource,DataTable)。如果存储了DataTable对象(如图所示),则不需要使用DefaultView

如果是这种情况,当然要使用已有的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单元格值的操作。
在这种情况下,您确实需要调用来通知更改,因此更改会立即发生。否则,值更改将在焦点离开后传播

此处的注释:在类似情况下(当您必须直接设置DataGridView单元格时)也可能有用

您还可以注意到,设置DataRow列的值也会更改DataGridView(不仅仅是
CurrentCell
),而在DataGridView中设置单元格的值不会导致
CurrentRow
更改,因此您必须自己进行设置:

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


什么是StepDGV?是DataTable还是DataGridView?这就是DataGridView
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