0

どのソースにも接続されていない、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)このイベントでメソッドを実行できないため、これは機能しません。行をプライベート変数に保存してから、他のイベント (クリックなど) で削除しようとしましたが、結果は期待したものではありません。

助言がありますか?

4

4 に答える 4

2

これはおそらく最善の解決策ではありませんが、少なくとも私はあなたのために働くかもしれない何かを考え出しました。基本的に、行を削除するのではなく、読み取り専用に設定します。また、行を離れるとペイントが呼び出されるため、代わりに削除コードをペイントに入れることができます。

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
于 2012-10-12T14:20:29.677 に答える
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
于 2012-10-13T11:09:53.673 に答える
0

それが私の最終的な解決策です。それは私にとってはうまくいき、概念的に正しいことを願っています。デリゲートと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
于 2012-10-15T07:42:43.237 に答える