我有一个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),但结果不是我所期望的。
有什么建议吗?
答案 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认为第一行是不包含任何数据的行(可以输入信息的空行。)这个对我有用。