Calculate SUM of cost from object instances VB.Net

Hobbyist_programmer 621 Reputation points
2021-01-29T08:21:31.953+00:00

Hallo i have a BindingList of Work and i want to make one of the object instance is a total of all other object instances.

for example i have property "ID" , ID from 1 - 99 are reserved for calculating cost and instance with ID 100 is a sum of all. I would like to know how it is normally done or is there any alternative?

Public Class Work

    Public Property ID As Integer
    Public Property Description As String
    Public Property Quantity As Integer
    Public Property UnitCost As Integer
    Public ReadOnly Property Cost As Integer
        Get
            Return GetCost()
        End Get
    End Property
    Public Function GetCost() As Integer

        Dim CalCost As Integer

        Select Case ID

            Case 1 To 99
                CalCost = UnitCost * Quantity

            Case 100 ''100 is the ID for Total
                CalCost = Sum() Of Cost  "totalcost"???  SUM of all Object In this collection 

        End Select

        Return CalCost

    End Function

End Class

Thanks

Developer technologies | VB
0 comments No comments
{count} votes

Accepted answer
  1. Karen Payne MVP 35,586 Reputation points Volunteer Moderator
    2021-01-30T14:02:10.45+00:00

    Hello,

    It's best to keep the total logic outside of the Work class e.g.

    • PopulateButton loads mocked data
    • TotalButton gets totals from 1-99 identifiers
    • ChangeButton to change quantity property of the current item
    • Changes in the DataGridView are reflected via INotifyPropertyChanged

      Revised Work class

      Public Class Work
      Implements INotifyPropertyChanged
      Private _id As Integer  
      Private _description As String  
      Private _quantity As Integer  
      Private _unitCost As Integer  
      
      Public Property Id As Integer  
          Get  
              Return _id  
          End Get  
          Set  
              _id = Value  
          End Set  
      End Property  
      
      Public Property Description As String  
          Get  
              Return _description  
          End Get  
          Set  
              _description = Value  
          End Set  
      End Property  
      
      Public Property Quantity As Integer  
          Get  
              Return _quantity  
          End Get  
          Set  
              _quantity = Value  
          End Set  
      End Property  
      
      Public Property UnitCost As Integer  
          Get  
              Return _unitCost  
          End Get  
          Set  
              _unitCost = Value  
          End Set  
      End Property  
      
      Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged  
      Protected Overridable Sub OnPropertyChanged(<CallerMemberName> Optional memberName As String = Nothing)  
          RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(memberName))  
      End Sub  
      
      Public Overrides Function ToString() As String  
          Return $"Id: {Id} Description: {Description}"  
      End Function  
      
      End Class

    Extensions

    For obtaining totals

    Public Module Extensions  
        <Extension>  
        Public Function ToList(Of T)(collection As IEnumerable(Of T)) As List(Of T)  
            Return New List(Of T)(collection)  
        End Function  
        <Extension>  
        Public Function Total(sender As List(Of Work)) As Integer  
            Return sender.Where(Function(work) work.Id <= 99).Sum(Function(work) work.Quantity * work.UnitCost)  
        End Function  
    End Module  
    

    Form code

    Public Class Form1  
    
        WithEvents mBindingSource As New BindingSource  
        Private mBindingList As New BindingList(Of Work)  
    
    
        Private Sub PopulateButton_Click(sender As Object, e As EventArgs) Handles PopulateButton.Click  
    
            Dim list As New List(Of Work) From {  
                New Work With {.Id = 1, .Description = "First", .UnitCost = 100, .Quantity = 2},  
                New Work With {.Id = 2, .Description = "Second", .UnitCost = 10, .Quantity = 1},  
                New Work With {.Id = 99, .Description = "Ninety nine", .UnitCost = 200, .Quantity = 1},  
                New Work With {.Id = 100, .Description = "One hundred", .UnitCost = 100, .Quantity = 5}  
            }  
    
            mBindingList = New BindingList(Of Work)(list)  
            mBindingSource.DataSource = mBindingList  
            DataGridView1.DataSource = mBindingSource  
    
        End Sub  
    
        Private Sub TotalButton_Click(sender As Object, e As EventArgs) Handles TotalButton.Click  
            If mBindingSource.DataSource IsNot Nothing Then  
                Dim total = mBindingList.ToList().Total()  
                TotalLabel.Text = $"Total: {total}"  
            Else  
                MessageBox.Show("No work items")  
            End If  
        End Sub  
    
        Private Sub ChangeButton_Click(sender As Object, e As EventArgs) Handles ChangeButton.Click  
    
            If mBindingSource.DataSource IsNot Nothing Then  
    
                Dim quantity As Integer  
    
                If Integer.TryParse(QuantityTextBox.Text, quantity) Then  
                    mBindingList(mBindingSource.Position).Quantity = quantity  
                    mBindingSource.ResetCurrentItem()  
                End If  
    
            Else  
                MessageBox.Show("No work items")  
            End If  
    
        End Sub  
    End Class  
    

    Screen shot

    62106-11111111111.png

    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.