XtraGrid 上下移动网格行

XtraGrid Move Grid Row Up and Down

如本 DevExpress thread 中所述,我能够上下移动网格行。但是,一旦我使用 Primary Key 约束从数据库中添加 table,它就停止工作了。抛出异常:

Column 'Id' is constrained to be unique. Value '101' is already present

这是我的 MoveDown 代码:

Private Sub BtnMveDwn_Click(sender As Object, e As EventArgs) Handles BtnMveDwn.Click

    Dim lObjGrdVew As GridView
    Dim lObjDtaTbl As DataTable
    Dim lIntIndex As Integer
    Dim lObjTmpRow As Object
    Try
        lObjGrdVew = CType(GrdCntrlMain.FocusedView, GridView)
        lObjDtaTbl = TryCast(GrdCntrlMain.DataSource, DataTable)
        lIntIndex = lObjGrdVew.FocusedRowHandle

        lObjGrdVew.GridControl.Focus()

        If lIntIndex >= lObjGrdVew.DataRowCount - 1 Then
            Return
        End If

        lObjTmpRow = lObjDtaTbl(lObjGrdVew.ViewRowHandleToDataSourceIndex(lIntIndex + 1)).ItemArray

        lObjDtaTbl(lObjGrdVew.ViewRowHandleToDataSourceIndex(lIntIndex + 1)).ItemArray = lObjDtaTbl(lObjGrdVew.ViewRowHandleToDataSourceIndex(lIntIndex)).ItemArray

        lObjDtaTbl(lObjGrdVew.ViewRowHandleToDataSourceIndex(lIntIndex)).ItemArray = lObjTmpRow

        lObjGrdVew.FocusedRowHandle += 1
        lObjGrdVew.UnselectRow(lObjGrdVew.FocusedRowHandle - 1)
        lObjGrdVew.SelectRow(lObjGrdVew.FocusedRowHandle)

    Catch ex As Exception
        MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try

End Sub

至于这个thread,我没试过,但当然如果列数更高,我必须遍历所有列。即,循环。

谢谢

编辑 1 请不要 drag/drop 代码。我是在点击按钮时做的。


编辑 2 有一个问题!我有带有暗淡可见 Expand 按钮的行。就像,如果存在子行,则展开按钮将正确可见,否则会变暗,就像正常的网格行为一样。但是当交换行时,展开按钮不会改变它们的状态,这是错误和不可取的。你能解决这个问题吗?

您需要使用DataTable.BeginLoadData method and DataTable.EndLoadData方法。 DataTable.BeginLoadData 方法在加载数据时关闭通知、索引维护和约束,DataTable.EndLoadData 打开它。
这是示例:

Private Sub BtnMveDwn_Click(sender As Object, e As EventArgs) Handles BtnMveDwn.Click

    Dim lObjGrdVew As GridView
    Dim lObjDtaTbl As DataTable
    Dim lIntIndex As Integer
    Dim lObjTmpRow As Object
    Try
        lObjGrdVew = CType(GrdCntrlMain.FocusedView, GridView)
        lObjDtaTbl = TryCast(GrdCntrlMain.DataSource, DataTable)
        lIntIndex = lObjGrdVew.FocusedRowHandle

        lObjGrdVew.GridControl.Focus()

        If lIntIndex >= lObjGrdVew.DataRowCount - 1 Then
            Return
        End If

        lObjTmpRow = lObjDtaTbl(lObjGrdVew.ViewRowHandleToDataSourceIndex(lIntIndex + 1)).ItemArray

        lObjDtaTbl.BeginLoadData '<= turn off constraints

        lObjDtaTbl(lObjGrdVew.ViewRowHandleToDataSourceIndex(lIntIndex + 1)).ItemArray = lObjDtaTbl(lObjGrdVew.ViewRowHandleToDataSourceIndex(lIntIndex)).ItemArray

        lObjDtaTbl(lObjGrdVew.ViewRowHandleToDataSourceIndex(lIntIndex)).ItemArray = lObjTmpRow

        lObjDtaTbl.EndLoadData '<= turn on constraints

        GrdCntrlMain.RefreshDataSource() '<= update GridControl to reflect the changes

        lObjGrdVew.FocusedRowHandle += 1
        lObjGrdVew.UnselectRow(lObjGrdVew.FocusedRowHandle - 1)
        lObjGrdVew.SelectRow(lObjGrdVew.FocusedRowHandle)

    Catch ex As Exception
        MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try

End Sub

编辑 2 您需要使用 GrdCntrlMain.RefreshDataSource 更新您的 GridControl,这样基础数据源中的更改将正确反映在您的 DataControl.