我有一个带有dataTable的datagridview作为dataSource。用户可以向datagridview添加新行,但是我没有显示主键列(出于显而易见的原因)并将其设置为.visible = false
。当我需要将datagridview中的信息更新到数据库时,我使用sqlClient.SqlCommandBuilder
然后更新基础数据源(上面提到的dataTable)。
现在,因为隐藏列是主键,所以我遍历datagridview并以编程方式将所需的主键字段添加到每个尚未包含主键的新行(用户添加的行)。这种方法在95%的时间内都很有用......
问题在于,当用户以某种方式在某个点(任何点)将焦点放在datagridview的底部行上时,在其添加的行下方,用于添加新行。 update命令给出了一个错误,指出它不能将null插入主键字段,即使在检查每一行中的所有值时,它们对于它们中的任何一个肯定都不为空。
我试图捕获row.isNewRow
(因为该字段从不显示null)并删除该行,但是我收到一条错误消息,指出我无法删除未提交的行。如果永远不会将焦点放在现有行和用户添加的行下方的空行中,则更新可以正常工作。
发生什么事了?!
答案 0 :(得分:0)
听起来你的代码试图从数据库中删除空白的新行 - 但它还没有在数据库中;它是“分离的”,只是在DataGridView的内存中...所以你需要将它删除。您可以在验证事件中使用一行来执行此操作,当然,在您保存之前将(或应该)调用该行。
处理此问题的一种方法是提示用户完全填写新行:
Private Sub dataGridView1_RowValidating(ByVal sender As Object, ByVal e As DataGridViewCellCancelEventArgs)
If dataGridView1.Rows(e.RowIndex) IsNot Nothing AndAlso Not dataGridView1.Rows(e.RowIndex).IsNewRow Then
Dim [error] As String = ""
If dataGridView1.Rows(e.RowIndex).Cells("Field1").Value Is Nothing OrElse dataGridView1.Rows(e.RowIndex).Cells("Field1").Value.ToString().Trim() = "" Then
[error] += " * Field #1" & vbLf
End If
If dataGridView1.Rows(e.RowIndex).Cells("Field2").Value Is Nothing OrElse dataGridView1.Rows(e.RowIndex).Cells("Field2").Value.ToString().Trim() = "" Then
[error] += " * Field #2" & vbLf
End If
If [error] <> "" Then
MessageBox.Show("The following required fields were left blank:" & vbLf & vbLf & [error], "Row Validation Error", MessageBoxButtons.OK, MessageBoxIcon.[Error])
e.Cancel = True
End If
End If
End Sub
另一种处理方法是从DataGridView中删除(空)行:
Private Sub dataGridView1_RowValidating(ByVal sender As Object, ByVal e As DataGridViewCellCancelEventArgs)
If dataGridView1.Rows(e.RowIndex) IsNot Nothing AndAlso Not dataGridView1.Rows(e.RowIndex).IsNewRow Then
dataGridView1.Rows.Remove(e.RowIndex)
End If
End Sub
可以处理的第三种流行方式是让您的验证在没有任何操作时取消编辑当前行:
Private Sub dataGridView1_RowValidating(ByVal sender As Object, ByVal e As DataGridViewCellCancelEventArgs)
Dim drv As DataRowView = TryCast(dataGridView1.CurrentRow.DataBoundItem, DataRowView)
If drv IsNot Nothing AndAlso drv(0) = DBNull.Value Then
drv.CancelEdit()
e.Cancel = True
End If
End Sub
(另外,另请注意:如果您的主键(a / k / a标识)字段设置为自动编号,您可能会发现ADO.NET能够更好地处理获取下一个ID的详细信息在保存期间如此。有关详细信息,请查看MSDN article on "Retrieving Identity of Autonumber Values"和this great set of examples for both SQL Server and MS Access。)
答案 1 :(得分:0)
Private Sub dataGridView1_RowValidating(ByVal sender As Object, ByVal e As DataGridViewCellCancelEventArgs)
If dataGridView1.Rows(e.RowIndex) IsNot Nothing AndAlso Not dataGridView1.Rows(e.RowIndex).IsNewRow Then
Dim [error] As String = ""
If dataGridView1.Rows(e.RowIndex).Cells("Field1").Value Is Nothing OrElse dataGridView1.Rows(e.RowIndex).Cells("Field1").Value.ToString().Trim() = "" Then
[error] += " * Field #1" & vbLf
End If
If dataGridView1.Rows(e.RowIndex).Cells("Field2").Value Is Nothing OrElse dataGridView1.Rows(e.RowIndex).Cells("Field2").Value.ToString().Trim() = "" Then
[error] += " * Field #2" & vbLf
End If
If [error] <> "" Then
MessageBox.Show("The following required fields were left blank:" & vbLf & vbLf & [error], "Row Validation Error", MessageBoxButtons.OK, MessageBoxIcon.[Error])
e.Cancel = True
End If
End If
End Sub