AddNew(),删除此行时出现问题
AddNew(), problems deleting this row
我有一个绑定到 BindingSource 的 DataGridView。然后我有一个按钮来添加新记录:
Private Sub btnNew_Click(sender As Object, e As EventArgs) Handles btnNew.Click
_bsStaff.AddNew()
End Sub
这确实创建了一个新行,其后还有 "next new/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
不过,看截图,
当我点击进入新行,然后点击我的按钮时,它处于未更改状态,但它是具有当前记录指针的前一行(未更改状态可能指的是),它是否要删除这一行。
本质上,我想我需要一种方法来检测新行刚刚被点击进入,但没有输入任何内容,这样我就可以放弃删除的尝试。
我将 post 我目前的解决方案作为一个提议但不太情愿的答案,希望它能鼓励有人用更专业的解决方案来打败我。
我目前采取务实的方法,明确告诉用户他们将要删除哪条记录:
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
人们会认为,如果有人只是点击进入新行,他们就会点击离开它,但因为它会立即插入一个增量值并选择一个部门,所以可以理解为什么他们会被鼓励去单击删除按钮。
(一定有某种方法可以检测行是否处于这种异常的、容易发生的状态。)
同时,为了进行比较和评论(和批评),我将 post 我的第二个改进的解决方案放在这里。
这是我当前的 Delete 方法的完整代码块:
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
状态,并立即按下删除按钮,这是准确的我正在尝试检测的情况。如果他们在这个新行中输入了任何内容,那么它将不再是新行(不满足测试条件),也不会处于未更改的状态。在这些情况下,较早的情况已经导致该行被放弃。
它有点笨拙(我仍然希望对此有所改进)但这也是我试图捕捉的一个非常具体的情况。
我有一个绑定到 BindingSource 的 DataGridView。然后我有一个按钮来添加新记录:
Private Sub btnNew_Click(sender As Object, e As EventArgs) Handles btnNew.Click
_bsStaff.AddNew()
End Sub
这确实创建了一个新行,其后还有 "next new/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
不过,看截图,
当我点击进入新行,然后点击我的按钮时,它处于未更改状态,但它是具有当前记录指针的前一行(未更改状态可能指的是),它是否要删除这一行。
本质上,我想我需要一种方法来检测新行刚刚被点击进入,但没有输入任何内容,这样我就可以放弃删除的尝试。
我将 post 我目前的解决方案作为一个提议但不太情愿的答案,希望它能鼓励有人用更专业的解决方案来打败我。
我目前采取务实的方法,明确告诉用户他们将要删除哪条记录:
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
人们会认为,如果有人只是点击进入新行,他们就会点击离开它,但因为它会立即插入一个增量值并选择一个部门,所以可以理解为什么他们会被鼓励去单击删除按钮。
(一定有某种方法可以检测行是否处于这种异常的、容易发生的状态。)
同时,为了进行比较和评论(和批评),我将 post 我的第二个改进的解决方案放在这里。
这是我当前的 Delete 方法的完整代码块:
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
状态,并立即按下删除按钮,这是准确的我正在尝试检测的情况。如果他们在这个新行中输入了任何内容,那么它将不再是新行(不满足测试条件),也不会处于未更改的状态。在这些情况下,较早的情况已经导致该行被放弃。
它有点笨拙(我仍然希望对此有所改进)但这也是我试图捕捉的一个非常具体的情况。