VB.NET DataGridView编辑后DataTable已更新但首次合计标签未刷新问题
VB.NET购物车金额同步问题解决方案
问题根因
首次编辑Amount列时,你手动给DataRow的Amount字段赋值后,DataRow仍处于编辑状态,带Expression规则的Total列不会即时触发重计算,导致第一次调用Total()方法统计的是修改前的旧值。第一次编辑流程结束后,DataRow的编辑状态会在UI消息循环中自动提交,所以第二次编辑时取值正常。
此外你现有代码中手动同步DataGridView值到DataTable的操作是冗余的,绑定模式下控件编辑完成后会自动同步值到数据源,重复赋值反而容易引发时序异常。
修复方案
方案1:优化CellEndEdit事件逻辑(最小改动)
直接删除冗余的手动赋值代码,添加强制提交数据源编辑的逻辑即可:
Private Sub DataGridViewCart_CellEndEdit(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridViewCart.CellEndEdit ' 仅处理Amount列编辑 If e.ColumnIndex <> 2 Then Exit Sub Dim editCell = DataGridViewCart.Rows(e.RowIndex).Cells(2) If String.IsNullOrWhiteSpace(editCell.Value?.ToString()) Then editCell.Value = 0 End If ' 强制提交当前编辑,触发表达式列即时计算 Me.BindingContext(DTCart).EndCurrentEdit() Total() End Sub
方案2:绑定数据源事件自动同步(推荐)
解耦总和计算逻辑和UI编辑事件,不管从哪里修改购物车数据都能自动更新总金额:
- 在DTCart初始化完成后添加列变更事件监听
' DTCart初始化代码后添加 AddHandler DTCart.ColumnChanged, Sub(sender, e) If e.Column.ColumnName = "Amount" Then Total() End Sub
- 可以简化Total方法,直接使用DataTable内置计算能力:
Sub Total() Dim sum = DTCart.Compute("SUM(Total)", "") LabelTotal.Text = If(sum Is DBNull.Value, "0", sum.ToString()) End Sub
- 原CellEndEdit事件可以简化为仅做空值校验:
Private Sub DataGridViewCart_CellEndEdit(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridViewCart.CellEndEdit If e.ColumnIndex <> 2 Then Exit Sub Dim editCell = DataGridViewCart.Rows(e.RowIndex).Cells(2) If String.IsNullOrWhiteSpace(editCell.Value?.ToString()) Then editCell.Value = 0 End If End Sub
内容的提问来源于stack exchange,提问作者Ryan OEI
相关产品推荐
相关产品推荐

