I'm writing a desktop application in VB.Net using an ObjectListView . I have a requirement to recalculate the values of other columns in the same row if any column value in the row changes.
Below is an example on how the ObjectListView displays rows currently:
| Unit Name | Length | Height | Qty | Rate | Amount |
|---|---|---|---|---|---|
| MM | 10 | 15 | 150 | 10.00 | 1500 |
| CMS | 15 | 5 | 75 | 8.00 | 600 |
| IN | 12 | 5 | 60 | 24.00 | 1440 |
| MTR | 11 | 6 | 66 | 18.00 | 1188 |
The Qty column is calculated as Length * Height. When the user enters 10 in the Length column and 15 in the Height column, the Qty column will show the value as 150 (10*15).
Similarly, Amount is calculated as Rate * Qty. When the user enters 10.00 Rate, the Amount column will show the value as 1500 (150*10.00).
My difficulty is I'm unable to find a suitable ObjectListView event to use for calculating cell values when a row changes.
I've done multiple attempts on various events, but the latest one is below. I tried getting an entire row object for the cell where the user is entering value, but failed. I then tried casting e.RowObject to my class ClientTask, hoping the e.RowObject would return the entire row, but the cast threw an exception. I also tried working on e.Column.AspectName but I'm not sure how to commit the new values back to the model.
How can I do this? I appreciate any help you can give.
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
I finally managed to find a solution, though I feel it can be optimized further as it's using multiuple for-loops which I feel is not an ideal solution. If anyone can assist refining further, especially without for-loops, it would really help: