如何修复这种奇怪的 DataGridview 行为

How do I Fix this Bizarre DataGridview Behavior

好的,我会尽力解释发生了什么。我有一个 Windows 表单,上面有两个数据网格视图。当用户在第一个 datagridview 中选择一行时,第二个 datagridview 的绑定源将根据第一个 datagridview 中所选行的主键进行过滤。这几乎一直都很完美。但是,如果用户在退出(enter/tab)他们在第二个 datagridview 中所在的单元格之前单击第一个 datagridview,则会导致第二个 datagridview 上的行卡在那里,并且在新过滤器时不会被过滤掉在第一个数据网格视图上的选择更改后应用。我已经检查过,它正在过滤的列具有应该被过滤掉的值,但它只是停留在那里。我不知道这是在哪里发生的。这是一些代码。如果有人有任何见解,那将是惊人的。

Dim CurrSpecLine As Integer = -2
Dim CurrTreatLine As Integer = -2
Dim SelSpecLine As Integer = 0
Dim SelSpecIdx As Integer = 0
Dim SpecCellEnd As String = ""
Dim SpecCellStart As String = ""
Dim PCell_Treat As DataGridViewCell
Dim CCell_Treat As DataGridViewCell

Private Sub Itm_Spec_DetDGV_DefaultValuesNeeded(sender As System.Object, e As System.Windows.Forms.DataGridViewRowEventArgs) Handles Itm_Spec_DetDGV.DefaultValuesNeeded

    Dim MaxRow As Integer = 0

    For Each rws As DataGridViewRow In Me.Itm_Spec_DetDGV.Rows
        If MaxRow < rws.Cells(0).Value Then MaxRow = rws.Cells(0).Value
    Next

    MaxRow = MaxRow + 1

    With e.Row
        .Cells("Itm_ItmKeyCol_Spec").Value = ItmKey
        .Cells("Itm_ItmSpecKeyCol_Spec").Value = CurrSpecLine
        .Cells("Itm_LoadDateCol_Spec").Value = Now()
        .Cells("Itm_LoadUserCol_Spec").Value = User
        .Cells("Itm_SpecDetLineCol_Spec").Value = MaxRow
    End With
    CurrSpecLine = CurrSpecLine - 1

End Sub

Private Sub Itm_Spec_DetDGV_SelectionChanged(sender As System.Object, e As System.EventArgs) Handles Itm_Spec_DetDGV.SelectionChanged

    Dim DGV As DataGridView = Itm_Spec_DetDGV
    If DGV.SelectedCells.Count > 0 Then
        Me.SelSpecLine = DGV.Rows(DGV.SelectedCells(0).RowIndex).Cells("Itm_ItmSpecKeyCol_Spec").Value
        Me.SelSpecIdx = DGV.SelectedCells(0).RowIndex
    Else
        Me.SelSpecLine = 0
        Me.SelSpecIdx = 0
    End If
    Dim Filt As String = "ItmSpecKey = " & CStr(Me.SelSpecLine)
    UseCode = False
    'Me.StgItemSpecTreatmentBindingSource.RemoveFilter()
    Me.StgItemSpecTreatmentBindingSource.Filter = Filt
    UseCode = True

End Sub

Private Sub Itm_Spec_DetDGV_CellEnter(sender As System.Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles Itm_Spec_DetDGV.CellEnter

    Dim DGV As DataGridView = sender
    Dim RIdx As Integer = e.RowIndex
    Dim CIdx As Integer = e.ColumnIndex

    If IsDBNull(DGV.Rows(RIdx).Cells(CIdx).Value) = False Then
        SpecCellStart = DGV.Rows(RIdx).Cells(CIdx).Value
    Else
        SpecCellStart = ""
    End If


End Sub

Private Sub Itm_Spec_DetDGV_CellLeave(sender As System.Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles Itm_Spec_DetDGV.CellLeave

    Dim DGV As DataGridView = sender
    Dim RIdx As Integer = e.RowIndex
    Dim CIdx As Integer = e.ColumnIndex

    DGV.EndEdit()
    If IsDBNull(DGV.Rows(RIdx).Cells(CIdx).Value) = False Then
        SpecCellEnd = DGV.Rows(RIdx).Cells(CIdx).Value
    Else
        SpecCellEnd = ""
    End If

    If CIdx = DGV.Columns("Itm_SpecDetLineCol_Spec").Index Then
        If SpecCellEnd <> SpecCellStart Then
            If SpecCellStart > SpecCellEnd Then
                For Each PRow As DataGridViewRow In DGV.Rows
                    If PRow.Index <> RIdx Then
                        Dim RVal As Integer = PRow.Cells("Itm_SpecDetLineCol_Spec").Value
                        If RVal >= SpecCellEnd And RVal < SpecCellStart Then
                            PRow.Cells("Itm_SpecDetLineCol_Spec").Value = RVal + 1
                        End If
                    End If
                Next
            Else
                For Each NRow As DataGridViewRow In DGV.Rows
                    If NRow.Index <> RIdx Then
                        Dim RVal As Integer = NRow.Cells("Itm_SpecDetLineCol_Spec").Value
                        If RVal > SpecCellStart And RVal <= SpecCellEnd Then
                            NRow.Cells("Itm_SpecDetLineCol_Spec").Value = RVal - 1
                        End If
                    End If
                Next
            End If
        End If
    End If

End Sub

Private Sub Itm_Spec_DetDGV_CellValueChanged(sender As System.Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles Itm_Spec_DetDGV.CellValueChanged

    Dim DGV As DataGridView = sender
    Dim RIdx As Integer = e.RowIndex
    Dim CIdx As Integer = e.ColumnIndex

    If UseCode = True Then
        If RIdx > -1 Then
            ItmSpecChg = True
        End If
    End If

End Sub

Private Sub Itm_Spec_DetDGV_KeyDown(sender As System.Object, e As System.Windows.Forms.KeyEventArgs) Handles Itm_Spec_DetDGV.KeyDown

    'Dim DGV As DataGridView = sender

    'If DGV.SelectedRows.Count > 0 And e.KeyCode = 46 Then

    '    Dim LineKey As Integer = DGV.CurrentRow.Cells("Itm_ItmSpecKeyCol_Spec").Value
    '    For Each GRow As DataGridViewRow In Me.Itm_Spec_TreatTypDGV.Rows
    '        If GRow.Cells("Itm_ItmSpecKeyCol_Treat").Value = LineKey Then
    '            Me.Itm_Spec_TreatTypDGV.Rows.RemoveAt(GRow.Index)
    '        End If
    '    Next

    'End If



End Sub

Private Sub Itm_Spec_DetDGV_EditingControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles Itm_Spec_DetDGV.EditingControlShowing

    'If Me.Itm_Spec_DetDGV.CurrentCell.ColumnIndex = Me.Itm_Spec_DetDGV.Columns("Itm_SpecLineNotesCol_Spec").Index Then
    '    Dim TB As TextBox = DirectCast(e.Control, TextBox)
    '    TB.Multiline = True
    'End If

End Sub

Private Sub Itm_Spec_TreatTypDGV_DefaultValuesNeeded(sender As System.Object, e As System.Windows.Forms.DataGridViewRowEventArgs) Handles Itm_Spec_TreatTypDGV.DefaultValuesNeeded

    With e.Row
        .Cells("Itm_ItmKeyCol_Treat").Value = ItmKey
        .Cells("Itm_ItmSpecKeyCol_Treat").Value = SelSpecLine
        .Cells("Itm_SpecTreatmentKeyCol_Treat").Value = CurrTreatLine
        .Cells("Itm_LoadDateCol_Treat").Value = Now()
        .Cells("Itm_LoadUserCol_Treat").Value = User
    End With
    CurrTreatLine = CurrTreatLine - 1

End Sub

Private Sub Itm_Spec_TreatTypDGV_CellEnter(sender As System.Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles Itm_Spec_TreatTypDGV.CellEnter

    Dim DGV As DataGridView = sender
    Dim RIdx As Integer = e.RowIndex
    Dim CIdx As Integer = e.ColumnIndex
    CCell_Treat = DGV.Rows(RIdx).Cells(CIdx)

    If UseCode = True Then
        Dim DDGV As DataGridView = Me.Itm_Spec_DetDGV
        If DDGV.SelectedCells.Count <= 0 Then

            MsgBox("You MUST select a line from the detail grid to edit it's treatments", MsgBoxStyle.OkOnly)
            Me.Itm_Spec_TreatTypDGV.ClearSelection()
            DDGV.Focus()

        End If
    End If


End Sub

Private Sub Itm_Spec_TreatTypDGV_CellLeave(sender As System.Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles Itm_Spec_TreatTypDGV.CellLeave

    Dim DGV As DataGridView = sender
    Dim RIdx As Integer = e.RowIndex
    Dim CIdx As Integer = e.ColumnIndex

    DGV.EndEdit()
    PCell_Treat = DGV.Rows(RIdx).Cells(CIdx)

End Sub

Private Sub Itm_Spec_TreatTypDGV_CellValueChanged(sender As System.Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles Itm_Spec_TreatTypDGV.CellValueChanged

    Dim DGV As DataGridView = sender
    Dim RIdx As Integer = e.RowIndex
    Dim CIdx As Integer = e.ColumnIndex

    If UseCode = True Then
        If RIdx > -1 Then
            If CIdx = DGV.Columns("Itm_SpecCoverPctCol_Treat").Index Then
                DGV.EndEdit()
                Dim DCell As DataGridViewTextBoxCell = DGV.Rows(RIdx).Cells(CIdx)
                If IsDBNull(DCell.Value) = True Then
                    Exit Sub
                Else
                    Dim UsrVal As Double = DCell.Value
                    Dim NewVal As Double = UsrVal / 100
                    UseCode = False
                    DGV.Rows(RIdx).Cells(CIdx).Value = NewVal
                    UseCode = True
                End If
            End If
            ItmSpecChg = True
        End If
    End If


End Sub

Private Sub Itm_Spec_TreatTypDGV_DataError(sender As System.Object, e As System.Windows.Forms.DataGridViewDataErrorEventArgs) Handles Itm_Spec_TreatTypDGV.DataError

    Dim DGV As DataGridView = sender

    If e.Exception.Message = "Input string was not in a correct format." Then
        MsgBox("The value entered is not valid for this field", vbOKOnly, "Treatment Type Error!")
        CCell_Treat.Selected = False
        PCell_Treat.Selected = True
        e.Cancel = True
    End If
End Sub

我仍然不清楚为什么会这样,但是从 TreatTypeDGV.CellLeave 中删除 DGV.EndEdit 解决了问题