AddNew(),删除此行的问题

时间:2016-04-30 23:31:03

标签: vb.net datagridview bindingsource

我有一个绑定到BindingSource的DataGridView。然后我有一个按钮来添加新记录:

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

这会创建一个新行,也会跟随“next next / blank”行。这工作正常,除非我立即按下删除按钮尝试删除这个新添加的行:

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

这会删除新行,也会删除之前的行!

我尝试在RemoveCurrent,_bsStaff.EndEdit()If _bsStaff.Position + 1 = _bsStaff.Count Then之前添加一行,但行为仍然存在。

有人可以解释这种行为并提供解决方案吗?

已添加:我认为我已尝试使用此代码,检查行状态:

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

然而,看截图,

enter image description here

当我单击进入新行,然后单击我的按钮时,它处于Unchanged状态,但它是前一行有当前记录指针(并且Unchanged状态可能指的是),就是这个将被删除的行。

基本上,我认为我需要一种方法来检测新行刚刚被点击,但没有输入任何内容,因此我可以放弃删除的尝试。

2 个答案:

答案 0 :(得分:0)

我会将我目前的解决方案发布为一个建议的,但不情愿的答案,希望能鼓励有人用更专业的解决方案来打扰我。

我现在采取实用的方法,明确告诉用户他们要删除哪条记录:

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

有人会认为,如果有人刚刚点击了新行,他们只需点击它,但因为它会立即插入一个增量值并选择一个部门,就会明白为什么会鼓励他们点击删除按钮。

(必须有某种方法可以检测到行处于这种不寻常的倾向状态。)

答案 1 :(得分:0)

与此同时,为了进行比较和评论(以及批评),我将在这里发布我的第二个改进的解决方案。

这是我目前删除方法的完整代码块:

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

关键部分在这里:

        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

查看我的问题中的屏幕截图,虽然当前行是新行的正上方,但新行中仍然有一个SelectedCell。使用dgvStaff.SelectedCells(0).RowIndex = dgvStaff.NewRowIndex我确认此单元格位于新(空白)行中。现在,如果用户点击了这个新行,那么就是这种情况,因此它处于Unchanged状态,并立即按下删除按钮,这就是我的确切情况试图检测。如果他们在这个新行中键入了任何内容,那么它将不再是新行(不会满足测试条件),也不会处于未更改状态。在这种情况下,早期的案例已经导致该行被放弃。

这有点笨拙(我仍然希望对此有所改进),但这也是我想要捕捉的非常具体的情况。