【问题标题】:Deleting a row in DataGridView on rowLeave在 rowLeave 上删除 DataGridView 中的一行
【发布时间】:2014-06-26 11:34:12
【问题描述】:

我有一个 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 中,然后在其他事件(如单击)中将其删除,但结果不是我所期望的。

有什么建议吗?

【问题讨论】:

    标签: vb.net datagridview


    【解决方案1】:

    这可能不是最好的解决方案,但至少我想出了一些可能对你有用的东西。基本上,您将该行设置为只读而不是删除它。而且由于在您离开行时会调用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
    

    【讨论】:

    • 谢谢,但我找到了更好的解决方案(满足我的需要)。
    【解决方案2】:

    您不能删除 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
    

    【讨论】:

    • 谢谢您,您的解决方案非常好。但我找到了不同的解决方案。
    【解决方案3】:

    这是我的最终解决方案。它对我有用,我希望它在概念上是正确的。我使用了委托和 Leave + 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
    

    【讨论】:

      【解决方案4】:

      实际上问题是你不能从下往上删除(1、2、3等)你必须像这样从上到下(3、2、1):

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-02-05
        • 2019-02-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-10-06
        相关资源
        最近更新 更多