首页 文章

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

提问于
浏览
0

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

在我的代码中,我只知道如何遍历行的 all ,而不是仅仅将触发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中的特定行和/或单元格进行比较?

UPDATE

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... 行上收到错误说"Column named " employeeID " cannot be found."我不确定错误是在DataSet上还是在DGV上,但数据库和DataSet中有一个employeeID列 . employeeID作为DataGridView的绑定列,但它设置为Visible = False . 那个's the only thing I can think of that could possibly cause that error, but if it'是一个绑定列,我认为它可以在这种情况下进行比较 .

FINAL WORKING VERSION

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 回答

  • 1

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

    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

相关问题