VB.net 中的 DataGridView 不允许我更新

Posted

技术标签:

【中文标题】VB.net 中的 DataGridView 不允许我更新【英文标题】:DataGridView in VB.net will not allow me to update 【发布时间】:2009-06-17 23:25:53 【问题描述】:

我有一个数据网格视图,其中数据表作为数据源。用户可以向 datagridview 添加新行,但我不显示主键列(出于显而易见的原因)并将其设置为.visible = false。当我需要将datagridview中的信息更新到数据库时,我使用sqlClient.SqlCommandBuilder来更新底层数据源(上面提到的dataTable)。

现在,因为隐藏列是主键,所以我循环遍历 datagridview 并以编程方式将所需的主键字段添加到尚未包含主键的每个新行(用户添加的行)。这在 95% 的时间里都很好用......

问题在于,当用户以某种方式将焦点集中在 datagridview 上的底行(在其添加的行下方)用于添加新行时。更新命令给了我一个错误,指出它不能在主键字段中插入 null,即使在检查每一行中的所有值时,它们中的任何一个都绝对不是 null。

我试图捕获row.isNewRow(因为该字段从不显示空值)并删除该行,但我收到一条错误消息,指出我无法删除未提交的行。如果焦点从未放在现有行和用户添加的行下方的空行上,则更新工作正常。

这是怎么回事?!

【问题讨论】:

【参考方案1】:

听起来您的代码正试图从数据库中删除空白的新行——但它还没有在数据库中;它是“分离的”,并且只是在 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。)

【讨论】:

【参考方案2】:
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

【讨论】:

描述一下这段代码如何回答这个问题会很有帮助。

以上是关于VB.net 中的 DataGridView 不允许我更新的主要内容,如果未能解决你的问题,请参考以下文章

需要一些关于将数据放入 vb.Net 中的 DataGridView 的建议

VB.NET 无法更新 datagridview 中的 SQL 数据

Vb.net 编辑 DatagridView

VB.NET中的DATAGRIDVIEW怎样只能在表格中输入数字呢

如何使 datagridview 实时连接到本地存储在 VB.NET 中的访问数据库?

Datagridview 中的更改未保存在表 SQLite vb.net 中