2016-04-30 10 views
0

Ich habe eine DataGridView an eine BindingSource gebunden. Ich habe dann eine Taste, um einen neuen Datensatz hinzuzufügen:AddNew(), Probleme beim Löschen dieser Zeile

Private Sub btnNew_Click(sender As Object, e As EventArgs) Handles btnNew.Click 
    _bsStaff.AddNew() 
End Sub 

Dies hat eine neue Zeile erstellen, auch mit der „nächsten neuen/leeren“ Zeile danach. Dies funktioniert gut, außer wenn ich drücken Sie sofort meine Delete-Taste Mit dieser neu hinzugefügte Zeile zu versuchen und zu entfernen:

Private Sub btnDelete_Click(sender As Object, e As EventArgs) Handles btnDelete.Click 
    If MessageBox.Show("Delete staff member record?", "Confirm", MessageBoxButtons.YesNo, _ 
         MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then 
     _bsStaff.RemoveCurrent() 
    End If 
End Sub 

Dies entfernt die neue Zeile, sondern auch die ein, bevor es!

Ich habe versucht, eine Zeile vor RemoveCurrent, _bsStaff.EndEdit() und auch If _bsStaff.Position + 1 = _bsStaff.Count Then hinzuzufügen, aber das Verhalten bleibt bestehen.

Kann jemand dieses Verhalten erklären und eine Lösung anbieten?


Added: Ich dachte, ich hätte es mit diesem Code zu schlagen, die Überprüfung des Zeilenstatus:

Private Sub btnDelete_Click(sender As Object, e As EventArgs) Handles btnDelete.Click 

    Dim state = CType(_bsStaff.Current, DataRowView).Row.RowState 
    Select Case state 
     Case DataRowState.Added 
      _bsStaff.RemoveCurrent() 
     Case DataRowState.Deleted 
      MessageBox.Show("Row already deleted.", "Delete") 
     Case DataRowState.Detached 
      _bsStaff.CancelEdit() 
     Case DataRowState.Modified 
      If MessageBox.Show("Delete staff member record?", "Confirm", MessageBoxButtons.YesNo, _ 
           MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then 
       _bsStaff.RemoveCurrent() 
      End If 
     Case DataRowState.Unchanged 
      If _bsStaff.Position + 1 > _bsStaff.Count Then 
       'do nothing, the new row 
      ElseIf MessageBox.Show("Delete staff member record?", "Confirm", MessageBoxButtons.YesNo, _ 
           MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then 
       _bsStaff.RemoveCurrent() 
      End If 
     Case Else 
      'do nothing 
    End Select 
End Sub 

jedoch auf dem Screenshot suchen,

enter image description here

wenn Ich klicke in die neue Zeile und klicke dann auf meine Schaltfläche, sie befindet sich im Status Unverändert, aber in der vorherigen Zeile befindet sich die Zeile Mietdatensatzzeiger (und auf den sich der Zustand Unverändert wahrscheinlich bezieht), wird diese Zeile gelöscht.

Im Wesentlichen denke ich, ich brauche einen Weg zu erkennen, dass die neue Zeile gerade angeklickt wurde, aber nichts eingegeben wurde, so dass ich den Versuch löschen kann.

+0

Stellen Sie sicher, dass Sie keinen Ereigniscode irgendwo in diesem Prozess gefeuert haben. Was ist das eigentliche Daten-Repository? – Plutonix

+0

'DefaultValuesNeeded' wird verwendet, um ein Element aus einer Abteilungs-Combobox auszuwählen. Die Daten sind SQL Server mit zwei Tabellen, Staff und Department. Ach ja, es ist dieser Code, der ihn beeinflusst - aber ich brauche diesen Code immer noch, um eine Abteilung auszuwählen. Ohne diesen Code und durch Klicken in die neue Zeile und Löschen löscht er auch die vorherige Zeile. Aber vielleicht ist das ein etwas anderes Thema? –

+0

Wenn Sie in eine neue Zeile klicken, wird sofort ein Inkrementwert von -1, -2 usw. erzeugt, der relevant sein kann. –

Antwort

0

In der Zwischenzeit und für den Vergleich und Kommentar (und Kritik), ich werde nach meine zweite, verbesserte, Lösung hier.

Hier ist mein aktueller vollständige Code-Block für die Delete-Methode:

Private Sub btnDelete_Click(sender As Object, e As EventArgs) Handles btnDelete.Click 
    If _bsStaff.Current Is Nothing Then 
     Exit Sub  'nothing to consider deleting 
    End If 
    Dim currentRow = CType(_bsStaff.Current, DataRowView).Row 
    Dim sMemberMessage As String 

    Dim state = currentRow.RowState 
    Select Case state 
     Case DataRowState.Added 
      'newly added, just remove it 
      _bsStaff.RemoveCurrent() 
     Case DataRowState.Deleted 
      MessageBox.Show("Row already deleted.", "Delete") 
     Case DataRowState.Detached 
      _bsStaff.CancelEdit() 
     Case DataRowState.Modified, DataRowState.Unchanged 
      If dgvStaff.SelectedCells.Count > 0 AndAlso _ 
        dgvStaff.SelectedCells(0).RowIndex = dgvStaff.NewRowIndex Then 
       'a new, blank, row, is attempted to be deleted 
       '(the current row is the one before this) 
       _bsStaff.CancelEdit() 
       Exit Sub 
      End If 
      sMemberMessage = String.Format("Delete record ({0} {1} {2}) ?", _ 
        _bsStaff.Current("StaffID"), _bsStaff.Current("FirstName"), _bsStaff.Current("LastName")) 
      If MessageBox.Show(sMemberMessage, "Confirm", MessageBoxButtons.YesNo, _ 
           MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then 
       _bsStaff.RemoveCurrent() 
      End If 
     Case Else 
      'do nothing 
    End Select 
End Sub 

Die Schlüsselkomponente ist hier:

 Case DataRowState.Modified, DataRowState.Unchanged 
      If dgvStaff.SelectedCells.Count > 0 AndAlso _ 
        dgvStaff.SelectedCells(0).RowIndex = dgvStaff.NewRowIndex Then 
       'a new, blank, row, is attempted to be deleted 
       '(the current row is the one before this) 
       _bsStaff.CancelEdit() 
       Exit Sub 
      End If 

auf dem Screenshot in meiner Frage der Suche, auch wenn die aktuelle Zeile die ist Direkt über der neuen Zeile befindet sich noch eine SelectedCell in der neuen Zeile.Mit dgvStaff.SelectedCells(0).RowIndex = dgvStaff.NewRowIndex bestätige ich, dass diese Zelle in der neuen (leeren) Reihe ist. Jetzt wird dies nur der Fall sein, wenn der Benutzer in diese neue Zeile geklickt hat, so ist es in einem Unchanged Zustand, und sofort drückte die Schaltfläche Löschen, die die genaue Situation ist, die ich versuche zu erkennen. Wenn sie etwas in diese neue Zeile eingegeben hätten, wäre es nicht mehr die neue Zeile (die Testbedingung wäre nicht erfüllt), noch wäre sie in einem unveränderten Zustand. Unter diesen Umständen hätten die früheren Fälle bereits dazu geführt, dass die Reihe aufgegeben wurde.

Es ist ein wenig ungeschickt (ich hoffe immer noch auf eine Verbesserung dieser), aber es ist auch ein sehr spezifischer Umstand, den ich zu erfassen versuche.

0

Ich werde meine derzeitige Lösung als eine vorgeschlagene, aber widerwillige Antwort posten, in der Hoffnung, dass es jemanden ermutigt, mich mit einer professionelleren Lösung zu übertreffen.

Ich bin ein pragmatischer Ansatz zur Zeit nehmen, ausdrücklich erklärt dem Benutzer, die Aufzeichnung sie im Begriff sind, zu löschen:

Private Sub btnDelete_Click(sender As Object, e As EventArgs) Handles btnDelete.Click 
    Dim currentRow = CType(_bsStaff.Current, DataRowView).Row 
    Dim sMemberMessage As String 

    Dim state = currentRow.RowState 
    Select Case state 
     Case DataRowState.Added 
      _bsStaff.RemoveCurrent() 
     Case DataRowState.Deleted 
      MessageBox.Show("Row already deleted.", "Delete") 
     Case DataRowState.Detached 
      _bsStaff.CancelEdit() 
     Case DataRowState.Modified, DataRowState.Unchanged 
      sMemberMessage = String.Format("Delete record ({0} {1} {2}) ?", _ 
        _bsStaff.Current("StaffID"), _bsStaff.Current("FirstName"), _bsStaff.Current("LastName")) 
      If MessageBox.Show(sMemberMessage, "Confirm", MessageBoxButtons.YesNo, _ 
           MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then 
       _bsStaff.RemoveCurrent() 
      End If 
     Case Else 
      'do nothing 
    End Select 
End Sub 

Man würde denken, dass, wenn jemand hat gerade erst in die neue Zeile angeklickt, dass sie würde nur wegklicken, aber weil es sofort einen Inkrementwert einfügt und eine Abteilung auswählt, kann man sehen, warum sie dazu ermutigt werden sollten, auf die Löschen-Schaltfläche zu klicken.

(Es muss eine gewisse Art und Weise des Erfassens, dass die Zeile (n) ist in diesem ungewöhnlichen, anfällig, Staat.)