Datagridview DataTable 一次编辑、更新和显示VB.net

Datagridview DataTable edit, update and show at a time VB.net

我做了一个这样的数据table :

    Dim DTCart As New DataTable

    DTCart.Columns.Add(New DataColumn With {.ColumnName = "Code", .DataType = GetType(String)})
    DTCart.Columns.Add(New DataColumn With {.ColumnName = "Name", .DataType = GetType(String)})
    DTCart.Columns.Add(New DataColumn With {.ColumnName = "Amount", .DataType = GetType(Double)})
    DTCart.Columns.Add(New DataColumn With {.ColumnName = "Price", .DataType = GetType(Long)})
    DTCart.Columns.Add(New DataColumn With {.ColumnName = "Total", .DataType = GetType(Long), .Expression = "Amount*Price"})

    DTCart.Columns("Code").ReadOnly = True
    DTCart.Columns("Name").ReadOnly = True
    DTCart.Columns("Amount").ReadOnly = False
    DTCart.Columns("Price").ReadOnly = True
    DTCart.Columns("Total").ReadOnly = True

然后我使用 DataGridView.DataSource = DTCart

将数据 table 显示到 Datagridview

我将 'Amount' 列设置为 editable 这样我就可以通过像这样编辑 Datagridview 中的单元格来更新它:

Private Sub DataGridViewCart_CellEndEdit(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridViewCart.CellEndEdit
    If DataGridViewCart.CurrentRow.Cells(2).Value.ToString = "" Then
        DataGridViewCart.CurrentRow.Cells(2).Value = 0
    End If

    Dim FindRow() As DataRow = DTCart.Select("Code='" & DataGridViewCart.CurrentRow.Cells(0).Value & "'")
    FindRow(0)("Amount") = DataGridViewCart.CurrentRow.Cells(2).Value

    Total()
End Sub

'Total()' 方法只是一种对 DataTable 上的 'Total' 列求和的方法,因此我可以将特定标签的文本设置为其值,如下所示:

Sub Total()
    Dim sum As Double = 0
    For Each row As DataRow In DTCart.Rows
        sum += row.Item("Total")
    Next

    LabelTotal.Text = sum
End Sub

现在,问题是,当我完成编辑单元格时,DataTable 已更新(我检查过),但 LabelTotal.Text 没有。

有趣的是这个问题只在我第一次编辑单元格时出现。 当我第二次尝试编辑同一个单元格时,它运行完美,所有内容都已更新。

求助..:'(

抱歉我的英语不好

我质疑你的评论......

”When i tried to edit the same cell a second time it runs perfectly, everything is updated.” … ?

在我的小测试中...“总计”列的总和始终反映“之前”的总计,而不是实际总计。换句话说,LabelTotal 总是错过最后一次更改。

这是因为当代码“求和”表的“Total”列时,它是在 Amount 列中的值发生变化时(……注意……当“表达式”列已更新)。因此,当用户更改网格中的 Amount 值时,网格的 CellEndEdit 事件将触发并对 Total 列求和并将该值放入标签中......但是自从 Total列是一个“表达式”列,它的值尚未更新,并且在网格的 CellEndEdit 退出后才会更新……因此最后的“金额”更改不会计算在总和中。

我建议您放弃循环遍历每一行并对值求和的 Total 方法,而是让 DataTable 使用它的 Compute 方法为您完成这项工作来求和Total 列。这可能会简化代码;但是并不能解决之前的问题

为了使用 Total 列的正确总和更新标签,我建议您在调用表计算方法之前调用表 AcceptChanges() 方法。像……

Private Sub DataGridView1_CellEndEdit(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridViewCart.CellEndEdit
  If DataGridViewCart.CurrentRow.Cells(2).Value.ToString = "" Then
    DataGridViewCart.CurrentRow.Cells(2).Value = 0
  End If
  DTCart.AcceptChanges()
  LabelTotal.Text = DTCart.Compute("SUM(Total)", "").ToString()
End Sub

最后,我同意 Mary 的意见,即您应该将 AmountPriceTotal 列更改为 Decimal。否则,您将丢失小数部分。

编辑…不调用数据表AcceptChanges()方法得到正确的总和…

经过进一步审查,您可能不想调用数据表 AcceptChanges 事件。除了您可能正在跟踪所做的更改的可能情况之外,还评论了一个示例。在这种情况下,您可以改为连接 DataTable.RowChanged 事件。它会在表达式列更新后触发,因此 SUM 应该是正确的。这可能看起来像……

AddHandler DTCart.RowChanged, AddressOf DTCart_RowChanged

将上面的行添加到 Forms Load 事件...和事件下面...

Private Sub DTCart_RowChanged(sender As Object, e As DataRowChangeEventArgs)
  LabelTotal.Text = DTCart.Compute("SUM(Total)", "").ToString()
End Sub