在rowLeave上删除DataGridView中的行

时间:2012-10-12 10:00:44

标签: vb.net datagridview

我有一个vb.net形式的DataGridView,没有连接到任何源。我想在用户传递到另一行或聚焦DGV时删除一行。如果其中有一个空单元格,则应删除该行。

这是我的代码:

Private Sub dgvSpSettings_RowLeave(sender As Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvSpSettings.RowLeave
    If e.RowIndex < (dgvSpSettings.Rows.Count - 1) Then 'Esclude l'ultima riga dal controllo sulle righe vuote
        If Me.dgvSpSettings.Rows(e.RowIndex).Cells(0).Value Is Nothing OrElse Me.dgvSpSettings.Rows(e.RowIndex).Cells(0).Value.ToString() = "" OrElse Me.dgvSpSettings.Rows(e.RowIndex).Cells(1).Value Is Nothing OrElse Me.dgvSpSettings.Rows(e.RowIndex).Cells(1).Value.ToString() = "" Then
            Me.dgvSpSettings.Rows.RemoveAt(e.RowIndex)
        End If
    End If
End Sub

这不起作用,因为我无法在此事件中执行方法Me.dgvSpSettings.Rows.RemoveAt(e.RowIndex)。我试图将行存储在私有var中,然后在其他事件中删除它(如click),但结果不是我所期望的。

有什么建议吗?

4 个答案:

答案 0 :(得分:2)

这可能不是最好的解决方案,但至少我想出了一些可能对你有用的东西。基本上,您将行设置为只读而不是删除它。因为当你离开行时调用paint,你可以将删除代码放在paint中。

Private Sub DataGridView1_RowLeave(sender As System.Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.RowLeave
    DataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit)
    If e.RowIndex < (DataGridView1.Rows.Count - 1) Then
        If Me.DataGridView1.Rows(e.RowIndex).Cells(0).Value Is Nothing OrElse _
            Me.DataGridView1.Rows(e.RowIndex).Cells(0).Value.ToString() = "" OrElse _
            Me.DataGridView1.Rows(e.RowIndex).Cells(1).Value Is Nothing OrElse _
            Me.DataGridView1.Rows(e.RowIndex).Cells(1).Value.ToString() = "" Then
            Me.DataGridView1.Rows(e.RowIndex).ReadOnly = True
        End If
    End If
End Sub

Private Sub DataGridView1_Paint(sender As System.Object, e As System.Windows.Forms.PaintEventArgs) Handles DataGridView1.Paint
    Dim i As Integer = 0
    While i <> DataGridView1.Rows.Count - 1
        If DataGridView1.Rows(i).ReadOnly Then
            DataGridView1.Rows.RemoveAt(i)
            If i = DataGridView1.Rows.Count - 1 Then
                Exit While
            End If
        Else
            i += 1
        End If
    End While
End Sub

答案 1 :(得分:1)

您无法删除RowLeave事件处理中的行,因为它处于“忙碌状态”。 我有时应用的这类案例的解决方案是调用application.Idle事件(我真的不喜欢它,因为它感觉很笨,但效果很好):

  Private Sub dgvSpSettings_RowLeave(sender As Object, e As DataGridViewCellEventArgs) Handles dgvSpSettings.RowLeave
    Dim row As DataGridViewRow = dgvSpSettings.Rows(e.RowIndex)
    If Me.dgvSpSettings.Rows(e.RowIndex).Cells(0).Value Is Nothing OrElse
      e.dgvSpSettings.Rows(e.RowIndex).Cells(0).Value.ToString() = "" OrElse   
      Me.dgvSpSettings.Rows(e.RowIndex).Cells(1).Value Is Nothing OrElse 
      Me.dgvSpSettings.Rows(e.RowIndex).Cells(1).Value.ToString() = "" Then

      Me._rowToDelete = row
      AddHandler Application.Idle, AddressOf AppIdle
    End If
  End Sub

  Private _rowToDelete As DataGridViewRow

  Private Sub AppIdle(sender As Object, e As EventArgs)
    If Me._rowToDelete IsNot Nothing Then
      dgvSpSettings.Rows.Remove(Me._rowToDelete)
      Me._rowToDelete = Nothing
    End If
    RemoveHandler Application.Idle, AddressOf AppIdle
  End Sub

答案 2 :(得分:0)

这是我的最终解决方案。它适用于我,我希望它在概念上是正确的。我使用了代理和离开 + LostFocus 事件。

'**********
'* Controllo righe da eliminare
'**********
Private Sub dgvSpSettings_RowLeave(sender As Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvSpSettings.RowLeave
    Me.dgvSpSettings.CommitEdit(0)

    Dim row As DataGridViewRow = Me.dgvSpSettings.Rows(e.RowIndex)

    For Each cell In row.Cells
        cell.Style.BackColor = Color.White
    Next

    If Not row.IsNewRow() Then 'Esclude l'ultima riga dal controllo sulle righe vuote
        If String.IsNullOrEmpty(row.Cells(0).Value) OrElse String.IsNullOrEmpty(row.Cells(1).Value) Then
            _rowBlank = row
        End If
    End If

End Sub

Private Delegate Sub setCurrentCellDelegate()

Private Sub setCurrentCell()
    For Each cell In _rowBlank.Cells
        cell.Style.BackColor = Color.LightSalmon
    Next

    Me.dgvSpSettings.CurrentCell = _rowBlank.Cells(0)
    Me.dgvSpSettings.BeginEdit(True)
    _rowBlank = Nothing
End Sub

Private Delegate Sub removeRowDelegate()

Private Sub removeRow()
    Me.dgvSpSettings.Rows.Remove(_rowBlank)
    _rowBlank = Nothing
    _rowBlankDeleting = False
End Sub

'**********
'* Controllo righe da eliminare
'**********
Private Sub dgvSpSettings_Leave(sender As Object, e As System.EventArgs) Handles dgvSpSettings.Leave
    If _rowBlank IsNot Nothing AndAlso _rowBlankDeleting = False Then
        If MsgBox("Alcuni campi della riga non sono stati valorizzati. Eliminare la riga?", vbYesNo + vbInformation, "Eliminare") = MsgBoxResult.Yes Then
            _rowBlankDeleting = True
            Me.dgvSpSettings.BeginInvoke(New removeRowDelegate(AddressOf removeRow))
        Else
            Me.dgvSpSettings.BeginInvoke(New setCurrentCellDelegate(AddressOf setCurrentCell))
        End If
    End If
End Sub

'**********
'* Controllo righe da eliminare
'**********
Private Sub dgvSpSettings_LostFocus(sender As Object, e As System.EventArgs) Handles dgvSpSettings.LostFocus
    If _rowBlank IsNot Nothing AndAlso _rowBlank IsNot Me.dgvSpSettings.CurrentRow AndAlso _rowBlankDeleting = False Then
        If MsgBox("Alcuni campi della riga non sono stati valorizzati. Eliminare la riga?", vbYesNo + vbInformation, "Eliminare") = MsgBoxResult.Yes Then
            _rowBlankDeleting = True
            Me.dgvSpSettings.BeginInvoke(New removeRowDelegate(AddressOf removeRow))
        Else
            Me.dgvSpSettings.BeginInvoke(New setCurrentCellDelegate(AddressOf setCurrentCell))
        End If
    End If
End Sub

答案 3 :(得分:0)

实际上问题是你不能自下而上(1,2,3等)从上到下删除(3,2,1),如下所示:

For j = DataGrid1.Rows.Count - 2 To 0 Step -1
   DataGrid1.Rows.RemoveAt(j)
Next

问题是VB认为第一行是不包含任何数据的行(可以输入信息的空行。)这个对我有用。