ObjectListView
编写桌面应用程序。如果行中的任何列值发生变化,我需要重新计算同一行中其他列的值。
下面是
ObjectListView
当前如何显示行的示例:
单位名称 | 长度 | 高度 | 数量 | 价格 | 金额 |
---|---|---|---|---|---|
MM | 10 | 15 | 150 | 10.00 | 1500 |
内容管理系统 | 15 | 5 | 75 | 8.00 | 600 |
在 | 12 | 5 | 60 | 24.00 | 1440 |
港铁 | 11 | 6 | 66 | 18.00 | 1188 |
Qty
列的计算方式为 Length
* Height
。当用户在 Length
列中输入 10 并在 Height
列中输入 15 时,Qty
列将显示该值 150 (10*15)。
类似地,
Amount
的计算方式为 Rate
* Qty
。当用户输入 10.00 Rate
时,金额列将显示该值为 1500 (150*10.00)。
我的困难是我无法找到合适的
ObjectListView
事件来用于在行更改时计算单元格值。
我对各种事件进行了多次尝试,但最新的如下。我尝试获取用户输入值的单元格的整个行对象,但失败了。然后,我尝试将
e.RowObject
转换为我的类 ClientTask
,希望 e.RowObject
能够返回整行,但转换引发了异常。我也尝试过处理 e.Column.AspectName
但我不确定如何将新值提交回模型。
我该怎么做?我感谢您提供的任何帮助。
Private Sub dlvEstimateTemplate_CellEditFinishing(sender As Object, e As CellEditEventArgs) Handles dlvEstimateTemplate.CellEditFinishing
Dim lngth As Single = 0 'Length
Dim ht As Single = 0 'Height
Dim qty As Single = 0 'Quantity (Length * Height = Qty)
Dim rt As Single = 0
Dim amt As Single = 0
Dim myObj As Entities.ClientTask
Dim myTsk As Entities.ClientTask
'tmpVal = DirectCast(sender, BrightIdeasSoftware.DataListView).HotRowIndex
'DirectCast(sender, BrightIdeasSoftware.DataListView).GetItemAt(e.x
'myObj = e.RowObject
If e.Column.AspectName = "Length" Then
myTsk = New Entities.ClientTask
myTsk.Qty = e.NewValue * myTsk.Height
myTsk.Amt = myTsk.Qty * myTsk.Rate
'lngth = e.NewValue
ElseIf e.Column.AspectName = "Height" Then
myTsk = New Entities.ClientTask
myTsk.Qty = e.NewValue * myTsk.Length
myTsk.Amt = myTsk.Qty * myTsk.Rate
End If
DirectCast(sender, BrightIdeasSoftware.DataListView).BuildList()
'myObj = TryCast(e.RowObject, Entities.ClientTask)
End Sub
我终于找到了一个解决方案,尽管我觉得它可以进一步优化,因为它使用多个 for 循环,我觉得这不是一个理想的解决方案。如果有人可以帮助进一步完善,尤其是没有 for 循环,那真的会有帮助:
Private Sub dlvEstimateTemplate_CellEditFinishing(sender As Object, e As CellEditEventArgs) 处理 dlvEstimateTemplate.CellEditFinishing UpdateRowCalc03(发件人,e) 结束子
Private Sub UpdateRowCalc03(ByVal mySender As Object, ByVal myE As CellEditEventArgs)
Dim rowId As Integer
Dim lngth As Single = 0 'Length
Dim ht As Single = 0 'Height
Dim qty As Single = 0 'Quantity (Length * Height = Qty)
Dim rt As Single = 0 'Rate
Dim amt As Single = 0 'Amount (Qty * Rate)
rowId = myE.ListViewItem.SubItems(0).Text
For Each itm As ListViewItem In dlvEstimateTemplate.Items
If Convert.ToInt32(itm.SubItems(0).Text) = rowId Then
If myE.Column.AspectName = olvColLength.AspectName Then 'Length
lngth = myE.NewValue
ht = Convert.ToSingle(myE.ListViewItem.SubItems(5).Text) 'Height
qty = lngth * ht 'Qty
rt = Convert.ToSingle(myE.ListViewItem.SubItems(7).Text) 'Rate
CommitToDataTable(rowId, rt, qty)
ElseIf myE.Column.AspectName = olvColHeight.AspectName Then 'Height
ht = myE.NewValue 'Height
lngth = Convert.ToSingle(myE.ListViewItem.SubItems(4).Text) 'Length
qty = lngth * ht 'Qty
rt = Convert.ToSingle(myE.ListViewItem.SubItems(7).Text) 'Rate
CommitToDataTable(rowId, rt, qty)
ElseIf myE.Column.AspectName = olvColRate.AspectName Then 'Rate
lngth = Convert.ToSingle(myE.ListViewItem.SubItems(4).Text)
ht = Convert.ToSingle(myE.ListViewItem.SubItems(5).Text) 'Height
qty = lngth * ht 'Qty
rt = myE.NewValue 'Rate
CommitToDataTable(rowId, rt, qty)
End If
End If
Next
End Sub
Private Sub CommitToDataTable(ByVal rowId As Integer, ByVal myRt As Single, ByVal myQty As Single)
For Each row As DataRow In dtTable.Rows 'dtTable is a form scoped data table object
For Each myRow As DataRow In dtTable.Rows
If myRow("UniqueId") = rowId Then
myRow("Qty") = myQty
myRow("Amt") = myRt * myQty
End If
Next myRow
Next row
End Sub