You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在VB.Net的ObjectListView中实现行内列值联动计算

解决ObjectListView行内值变更后自动计算同行列的问题

核心问题分析

你当前代码的主要问题是没有获取到当前编辑行的实际ClientTask对象,反而新建了空对象,导致计算逻辑基于空值执行,同时没有将计算结果更新回原数据模型。另外BuildList()会刷新整个列表,效率低下,应该只刷新当前行。

正确实现步骤

  1. 通过CellEditFinished事件(比CellEditFinishing更适合,确保编辑值已提交到模型)获取当前行的ClientTask实例
  2. 根据修改的列类型,重新计算Qty和Amount
  3. 通知ObjectListView刷新当前行,而非全量刷新

修正后的代码

Private Sub dlvEstimateTemplate_CellEditFinished(sender As Object, e As CellEditEventArgs) Handles dlvEstimateTemplate.CellEditFinished
    ' 获取当前编辑行的ClientTask对象,用TryCast避免类型转换异常
    Dim currentTask As Entities.ClientTask = TryCast(e.RowObject, Entities.ClientTask)
    If currentTask Is Nothing Then Return ' 转换失败直接退出

    ' 确保数值类型转换安全,避免输入非数字导致异常
    Dim inputVal As Single = 0
    If Not Single.TryParse(e.NewValue.ToString(), inputVal) Then Return

    Select Case e.Column.AspectName
        Case "Length"
            currentTask.Length = inputVal
            ' 重新计算Qty和Amount
            currentTask.Qty = currentTask.Length * currentTask.Height
            currentTask.Amt = currentTask.Qty * currentTask.Rate
        Case "Height"
            currentTask.Height = inputVal
            currentTask.Qty = currentTask.Length * currentTask.Height
            currentTask.Amt = currentTask.Qty * currentTask.Rate
        Case "Rate"
            currentTask.Rate = inputVal
            currentTask.Amt = currentTask.Qty * currentTask.Rate
    End Select

    ' 只刷新当前行,比BuildList()效率更高
    DirectCast(sender, BrightIdeasSoftware.ObjectListView).RefreshObject(currentTask)
End Sub

关键说明

  • 获取行对象:TryCast(e.RowObject, Entities.ClientTask)是安全获取当前行数据模型的方式,避免强制转换的异常
  • 数值安全转换:用Single.TryParse处理用户输入,防止非数字内容导致程序崩溃
  • 局部刷新:RefreshObject(currentTask)只会更新当前行的显示,远优于全量刷新的BuildList()
  • 覆盖所有触发列:处理Length、Height和Rate列的变更,完整覆盖Qty和Amount的计算逻辑

额外优化建议

如果希望计算逻辑更内聚,可以把Qty和Amount的计算逻辑封装到ClientTask类的属性中,这样属性变更时自动触发计算:

Public Class ClientTask
    Private _length As Single
    Private _height As Single
    Private _rate As Single

    Public Property Length As Single
        Get
            Return _length
        End Get
        Set(value As Single)
            _length = value
            RecalculateValues()
        End Set
    End Property

    Public Property Height As Single
        Get
            Return _height
        End Get
        Set(value As Single)
            _height = value
            RecalculateValues()
        End Set
    End Property

    Public Property Rate As Single
        Get
            Return _rate
        End Get
        Set(value As Single)
            _rate = value
            RecalculateValues()
        End Set
    End Property

    Public Property Qty As Single
    Public Property Amt As Single

    Private Sub RecalculateValues()
        Qty = Length * Height
        Amt = Qty * Rate
    End Sub
End Class

此时事件代码可简化为:

Private Sub dlvEstimateTemplate_CellEditFinished(sender As Object, e As CellEditEventArgs) Handles dlvEstimateTemplate.CellEditFinished
    Dim currentTask As Entities.ClientTask = TryCast(e.RowObject, Entities.ClientTask)
    If currentTask Is Nothing Then Return

    Dim inputVal As Single = 0
    If Single.TryParse(e.NewValue.ToString(), inputVal) Then
        Select Case e.Column.AspectName
            Case "Length" : currentTask.Length = inputVal
            Case "Height" : currentTask.Height = inputVal
            Case "Rate" : currentTask.Rate = inputVal
        End Select
        DirectCast(sender, BrightIdeasSoftware.ObjectListView).RefreshObject(currentTask)
    End If
End Sub

内容的提问来源于stack exchange,提问作者Pankaj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 18:54:54