如何将DataGridView单元格数据与DataSet单元格数据进行比较

时间:2014-12-01 17:10:13

标签: vb.net winforms datagridview visual-studio-2013 dataset

在我在VS2013中工作的VB.NET WinForms项目中,我正在检测用户何时在CellValueChanged事件的单元格中更改某些内容。当发现DataGridView中的一行与DataSet不同时,我突出显示粉红色的行。

在我的代码中,我只知道如何遍历所有行,而不是仅仅将触发CellValueChanged事件的行与DataSet进行比较。

这是我目前的代码:

Private Sub dgvEmployees_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles dgvEmployees.CellValueChanged
    ' Pass the row and cell indexes to the method so we can change the color of the edited row
    CompareDgvToDataSource(e.RowIndex, e.ColumnIndex)
End Sub

Private Sub CompareDgvToDataSource(ByVal rowIndex As Integer, ByVal columnIndex As Integer)

    ' Force ending Edit mode so the last edited value is committed
    EmployeesBindingSource.EndEdit()

    Dim dsChanged As DataSet = EmployeesDataSet.GetChanges()

    If Not dsChanged Is Nothing Then
        For Each dt As DataTable In dsChanged.Tables
            For Each row As DataRow In dt.Rows
                For i As Integer = 0 To dt.Columns.Count - 1
                    Dim currentColor As System.Drawing.Color = dgvEmployees.AlternatingRowsDefaultCellStyle.BackColor

                    If Not row(i, DataRowVersion.Current).Equals(row(i, DataRowVersion.Original)) Then
                        Console.WriteLine("Row index: " & dt.Rows.IndexOf(row))
                        ' This works
                        dgvEmployees.Rows(rowIndex).DefaultCellStyle.BackColor = Color.LightPink
                    Else
                        ' Need to change the BackColor back to what it should be based on its original alternating row color
                    End If
                Next
            Next
        Next
    End If
End Sub

如您所见,我传递了已更改单元格的行和列索引,那么如何将其与未更改的DataSet中的特定行和/或单元格进行比较?

更新

Nocturnal提醒我,我需要允许对DGV进行排序,因此使用行索引不会起作用。他提出这个解决方案(略微改变以适应我的对象):

If Not dsChanged Is Nothing Then
    For Each dtrow As DataRow In dsChanged.Tables("employees").Rows
        If DirectCast(dtrow, EmployeesDataSet.employeesRow).employeeID.ToString = dgvEmployees.Rows(rowIndex).Cells("employeeID").Value.ToString Then
            For i As Integer = 0 To dsChanged.Tables("employees").Columns.Count - 1
                If Not dtrow(i, DataRowVersion.Current).Equals(dtrow(i, DataRowVersion.Original)) Then
                    Console.WriteLine("Employees ID: " & DirectCast(dtrow, EmployeesDataSet.employeesRow).employeeID)
                    dgvEmployees.Rows(rowIndex).Cells(columnIndex).Style.BackColor = Color.LightPink
                Else
                    ' Need to change the BackColor back to what it should be based on its original alternating row color
                End If
            Next
        End If
    Next
End If

但是,我在If DirectCast...行上收到错误说"列名为" employeeID"无法找到。"我不确定错误是在DataSet上还是在DGV上,但数据库和DataSet中有一个employeeID列。 一个employeeID作为DataGridView的绑定列,但它设置为Visible = False。这是我能想到的唯一可能导致错误的事情,但如果它是一个绑定列,我认为可以将其与这种情况进行比较。

最终工作版

Private Sub dgvEmployees_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles dgvEmployees.CellValueChanged
    ' Pass the row and cell indexes to the method so we can change the color of the edited row
    CompareDgvToDataSource("employees", e.RowIndex, e.ColumnIndex)
End Sub

Private Sub CompareDgvToDataSource(ByVal dataSetName As String, ByVal rowIndex As Integer, ByVal columnIndex As Integer)
    ' Takes a dataset and the row and column indexes, checks if the row is different from the DataSet and colors the row appropriately

    EmployeesBindingSource.EndEdit()

    Dim dsChanges As DataSet = EmployeesDataSet.GetChanges()

    If Not dsChanges Is Nothing Then
        For Each dtrow As DataRow In dsChanges.Tables("employees").Rows
            If DirectCast(dtrow, EmployeesDataSet.employeesRow).employeeID.ToString = dgvEmployees.Rows(rowIndex).Cells("employeeID").Value.ToString Then
                For i As Integer = 0 To dsChanges.Tables("employees").Columns.Count - 1

                    If dtrow.RowState.ToString = DataRowState.Added.ToString Then
                        ' TODO: Color entire new row
                    ElseIf dsChanges.Tables(dataSetName).Rows(0).HasVersion(DataRowVersion.Original) Then
                        If Not dtrow(i, DataRowVersion.Current).Equals(dtrow(i, DataRowVersion.Original)) Then
                            Console.WriteLine("Employees ID: " & DirectCast(dtrow, EmployeesDataSet.employeesRow).employeeID)
                            dgvEmployees.Rows(rowIndex).Cells(columnIndex).Style.BackColor = Color.LightPink
                        Else
                            ' TODO: Need to change the BackColor back to what it should be based on its original alternating row color
                        End If
                    End If
                Next
            End If
        Next
    End If
End Sub

我的项目中有四个DGV,因此最终会扩展到允许检查所有四个DGV的变化。

1 个答案:

答案 0 :(得分:1)

看看这种方法它是模拟的,但只迭代特定的表

Private Sub dgvEmployees_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles dgvEmployees.CellValueChanged ' Pass the row and cell indexes to the method so we can change the color of the edited row CompareDgvToDataSource(e.RowIndex, e.ColumnIndex, sender.DataSource.datamember.ToString) End Sub

并比较给定表的ID

    Private Sub CompareDgvToDataSource(ByVal rowIndex As Integer, ByVal columnIndex As Integer, tablename As String)

    EmployeesBindingSource.EndEdit()

    Dim dsChanged As DataSet = EmployeesDataSet.GetChanges()

    If Not dsChanged Is Nothing Then
        For Each dtrow As DataRow In dsChanged.Tables(tablename).Rows

            If DirectCast(dtrow, EmployeesDataSet.EmployeeRow).EmployeeID = dgvEmployees.Rows(rowIndex).Cells("EmployeeID").Value Then
                Dim currentColor As System.Drawing.Color = dgvEmployees.AlternatingRowsDefaultCellStyle.BackColor

                For i As Integer = 0 To dsChanged.Tables(tablename).Columns.Count - 1
                    If Not dtrow(i, DataRowVersion.Current).Equals(dtrow(i, DataRowVersion.Original)) Then
                        Console.WriteLine("Employees ID: " & DirectCast(dtrow, EmployeesDataSet.EmployeeRow).EmployeeID)
                        ' This works
                        dgvEmployees.Rows(rowIndex).Cells(columnIndex).Style.BackColor = Color.LightPink
                    Else
                        ' Need to change the BackColor back to what it should be based on its original alternating row color
                    End If
                Next
            End If
        Next
    End If
End Sub

我只是改变了改变了整个行的单元格的背景颜色....但取决于你将如何使用这些信息

编辑:

Console.WriteLine(EmployeesDataSet.Employee(rowIndex)(columnIndex, DataRowVersion.Original).ToString())
Console.WriteLine(EmployeesDataSet.Employee(rowIndex)(columnIndex, DataRowVersion.Current).ToString())

您可以看到当前值和原始值 123456