none
RowStatus beim Verlassen einer DataGridView-Zeile ermitteln RRS feed

  • Frage

  • Hallo,

    die User sollen über eine DataGrigView neue Datensätze erfassen (Option DataGridView.AllowUserToAddRows = True). Nachdem ein User auf eine neue, leere Zeile geklickt hat und diese Zeile dann verlässt, muss ich zwischen folgenden Situationen unterscheiden:

    1.  11. User hat auf die neue Zeile geklickt aber keine Änderung vorgenommen

    2.  22. User hat auf die neue Zeile geklickt und dann einen Wert über die Tastatur eingegeben.

    Nur im 2. Fall muss ich vor Verlassen der neunen Zeile per Programm mehre Werte in andere, im DataGridview nicht sichtbaren Zellen der neunen Zeile eintragen.

    Ich habe versucht über diverse Events wie .CellEndEdit, .RowLeave etc  den DataRowState bzw. DataRowVersion zu ermitteln um die im Punkt 2 geschilderte Situation eindeutig zu ermitteln, komme da aber nicht weiter.

    Könnte mir jemand einen Tipp geben?

    Grüße

    Christoph

    Montag, 3. Juni 2019 06:47

Antworten

  • Hallo,

    der Beitrag ist zwar schon etwas älter, aber vielleicht hilft es trotzdem noch weiter.

    In diesem Beispiel wird eine DataTable an das DataGridView gebunden und nur Änderungen an der DataTable überwacht. 

    Da hier keine Events des DataGridViews ausgewertet werden, eignet sich das also auch für andere Szenarien oder Controls und das "Binden" an irgendwas verursacht demnach keine Probleme.

    Public Class Form1
      Dim dt As DataTable
      Dim InProgress As Boolean = False
    
      Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        dt = SeedData()
        DataGridView1.DataSource = dt
        AddHandler dt.RowChanged, AddressOf DtRowChanged
      End Sub
    
      Private Sub DtRowChanged(sender As Object, e As DataRowChangeEventArgs)
        ' Vermeidung eines StackOverflows...
        If InProgress Then Return
    
        ' Nur auf bestimmte Aktionen reagieren...
        If Not (e.Action = DataRowAction.Change OrElse e.Action = DataRowAction.Add) Then
          Return
        End If
    
        ' Es wird zum Vergleich die alte Version benötigt, die hier geholt wird...
        Dim dtChanged = dt.GetChanges(DataRowState.Modified Or DataRowState.Added)
        If dtChanged Is Nothing Then Return
        dtChanged.RejectChanges()
        dtChanged.AcceptChanges()
        Dim dataOld = If(e.Action = DataRowAction.Add,
          dtChanged.NewRow.ItemArray,
          dtChanged.Rows(0).ItemArray)
    
        ' Die neuen Daten sind in e.Row abgelegt...
        Dim dataNew = e.Row.ItemArray
    
        ' Ein Vergleich kann auch anders gemacht werden...
        For c = 0 To dataOld.Length - 1
          If Not dataOld(c).Equals(dataNew(c)) Then
            InProgress = True
            ' TODO: Hier kannst du deine "Verarbeitung" programmieren, z.B.:
            If c < 2 Then
              e.Row.Item(2) = $"{e.Row.Item(0)} {e.Row.Item(1)} {Now}"
            End If
          End If
        Next
        dt.AcceptChanges()
        InProgress = False
      End Sub
    
      Public Function SeedData() As DataTable
        Dim dt As New DataTable
        dt.Columns.Add("S1", GetType(Integer))
        dt.Columns.Add("S2", GetType(String))
        dt.Columns.Add("S3", GetType(String))
    
        dt.Rows.Add(New Object() {1, "Hallo", Nothing})
        dt.Rows.Add(New Object() {2, "Welt", Nothing})
        dt.Rows.Add(New Object() {3, "Lorem", Nothing})
        dt.AcceptChanges()
        Return dt
      End Function
    End Class
    

    Gruß

    Montag, 17. Juni 2019 08:18

Alle Antworten

  • Hallo Christoph,

    Hast Du versucht, das DataGridView.CellValueChanged-Ereignis zu verwenden, wie in diesem Thread beschrieben:
    Make row invisible at runtime ( datagridview) in vb net

    Gruß,

    Ivan Dragov


    Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „IT-Pros helfen IT-Pros“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

    Dienstag, 4. Juni 2019 06:09
    Administrator
  • Hallo Ivan,

    ja, das habe ich auch versucht! Das Problem ist aber, dass dieses Event auch beim Binden einer DataTable an das Datagridview ausgelöst wird! Mir geht es aber konkret um die Situation, dass der User eine Änderung in einer Zelle über die Tastatur vornimmt!!!

    Gruß

    Christoph

    Dienstag, 4. Juni 2019 07:09
  • Hallo,

    der Beitrag ist zwar schon etwas älter, aber vielleicht hilft es trotzdem noch weiter.

    In diesem Beispiel wird eine DataTable an das DataGridView gebunden und nur Änderungen an der DataTable überwacht. 

    Da hier keine Events des DataGridViews ausgewertet werden, eignet sich das also auch für andere Szenarien oder Controls und das "Binden" an irgendwas verursacht demnach keine Probleme.

    Public Class Form1
      Dim dt As DataTable
      Dim InProgress As Boolean = False
    
      Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        dt = SeedData()
        DataGridView1.DataSource = dt
        AddHandler dt.RowChanged, AddressOf DtRowChanged
      End Sub
    
      Private Sub DtRowChanged(sender As Object, e As DataRowChangeEventArgs)
        ' Vermeidung eines StackOverflows...
        If InProgress Then Return
    
        ' Nur auf bestimmte Aktionen reagieren...
        If Not (e.Action = DataRowAction.Change OrElse e.Action = DataRowAction.Add) Then
          Return
        End If
    
        ' Es wird zum Vergleich die alte Version benötigt, die hier geholt wird...
        Dim dtChanged = dt.GetChanges(DataRowState.Modified Or DataRowState.Added)
        If dtChanged Is Nothing Then Return
        dtChanged.RejectChanges()
        dtChanged.AcceptChanges()
        Dim dataOld = If(e.Action = DataRowAction.Add,
          dtChanged.NewRow.ItemArray,
          dtChanged.Rows(0).ItemArray)
    
        ' Die neuen Daten sind in e.Row abgelegt...
        Dim dataNew = e.Row.ItemArray
    
        ' Ein Vergleich kann auch anders gemacht werden...
        For c = 0 To dataOld.Length - 1
          If Not dataOld(c).Equals(dataNew(c)) Then
            InProgress = True
            ' TODO: Hier kannst du deine "Verarbeitung" programmieren, z.B.:
            If c < 2 Then
              e.Row.Item(2) = $"{e.Row.Item(0)} {e.Row.Item(1)} {Now}"
            End If
          End If
        Next
        dt.AcceptChanges()
        InProgress = False
      End Sub
    
      Public Function SeedData() As DataTable
        Dim dt As New DataTable
        dt.Columns.Add("S1", GetType(Integer))
        dt.Columns.Add("S2", GetType(String))
        dt.Columns.Add("S3", GetType(String))
    
        dt.Rows.Add(New Object() {1, "Hallo", Nothing})
        dt.Rows.Add(New Object() {2, "Welt", Nothing})
        dt.Rows.Add(New Object() {3, "Lorem", Nothing})
        dt.AcceptChanges()
        Return dt
      End Function
    End Class
    

    Gruß

    Montag, 17. Juni 2019 08:18