Home

Microsoft Visual Basic Example Application: College Park Auto Parts

College Park Auto Parts: Part Selection  

Introduction

In our introduction to collections, we saw how to create a collection class. Rather than creating your own collection, in our review of built-in collection classes, we studied the ArrayList and the generic List<> classes. In this exercise, we apply these concepts to create an application.

This is an application used by a (fictitious, of course) company that sells auto parts. When using the application, the user can select the car year, the make, and the model. The user also has the ability to specify the category of the item the customer wants. This makes it easy to locate the part.

 

Practical Learning Practical Learning: Creating the Application

  1. Start Microsoft Visual Basic and create a new Windows Forms Application named CollegeParkAutoParts1
  2. To create a dialog box, on the main menu, click Project -> Add Windows Form...
  3. Set the name to MakeEditor and click Add
  4. Design the form as follows:
     
    Make Editor
    Control Text Name Other Properties
    Label &Make:    
    TextBox   txtMake Modifiers: Public
    Button OK btnOK DialogResult: OK
    Button Cancel btnCancel DialogResult: Cancel
    Form Property Value
    FormBorderStyle FixedDialog
    Text Make Editor
    StartPosition CenterScreen
    AcceptButton btnOK
    CancelButton btnCancel
    MaximizeBox False
    MinimizeBox False
    ShowInTaskbar False
  5. To create a dialog box, on the main menu, click Project -> Add Windows Form...
  6. Set the name to ModelEditor and click Add
  7. Design the form as follows:
     
    College Park Auto Parts: Model Editor
    Control Text Name Other Properties
    Label &Model:    
    TextBox   txtModel Modifiers: Public
    Button OK btnOK DialogResult: OK
    Button Cancel btnCancel DialogResult: Cancel
    Form Property Value
    FormBorderStyle FixedDialog
    Text Model Editor
    StartPosition CenterScreen
    AcceptButton btnOK
    CancelButton btnCancel
    MaximizeBox False
    MinimizeBox False
    ShowInTaskbar False
  8. To create a dialog box, in the Solution Explorer, right-click CollegeParkAutoParts2 -> Add -> Windows Form...
  9. Set the name to CategoryEditor and click Add
  10. Design the form as follows:
     
    College Park Auto Parts: Category Editor
    Control Text Name Other Properties
    Label &Category:    
    TextBox   txtCategory Modifiers: Public
    Button OK btnOK DialogResult: OK
    Button Cancel btnCancel DialogResult: Cancel
    Form Property Value
    FormBorderStyle FixedDialog
    Text Category Editor
    StartPosition CenterScreen
    AcceptButton btnOK
    CancelButton btnCancel
    MaximizeBox False
    MinimizeBox False
    ShowInTaskbar False
  11. On the main menu, click Project -> Add Windows Form...
  12. Set the Name to NewStoreItem and click Add
  13. Design the form as follows:
     
    College Park Auto-Part - Part Editor
     
    Control Text Name Other Properties
    Label &Year:    
    TextBox   txtItemNumber  
    Label &Make:    
    ComboBox   cbxMakes  
    Button New C&ategory... btnNewMake  
    Label M&odel:    
    ComboBox   cbxModels  
    Button New Mo &del... btnNewModel  
    Label &Category:    
    ComboBox   cbxCategories  
    Button New Ca&tegory btnNewCategory  
    Label &Unit Price:    
    TextBox 0.00 txtUnitPrice TextAlign: Right
    Label Part #:    
    TextBox   txtPartNumber  
    Label &Part Name:    
    TextBox   txtPartName  
    Button Submit btnSubmit  
    Button Close btnClose DialogResult: Cancel
    Form Property Value
    FormBorderStyle FixedDialog
    Text College Park Auto -Parts: Part Editor
    StartPosition CenterScreen
    MaximizeBox False
    MinimizeBox False
    ShowInTaskbar False
  14. Right-click the form and click View Code
  15. In the Class Name combo box, select btnNewMake
  16. In the Method Name combo box, select Click and implement the event as follows:
      
    Private Sub btnNewMakeClick(ByVal sender As Object, 
                                     ByVal e As System.EventArgs) 
                                     Handles btnNewMake.Click
            Dim Editor As MakeEditor = New MakeEditor
    
            If Editor.ShowDialog() = DialogResult.OK Then
                If Editor.txtMake.Text.Length > 0 Then
                    Dim strMake As String = Editor.txtMake.Text
    
                    ' Make sure the category is not yet in the list
                If cbxMakes.Items.Contains(strMake) Then
                        MsgBox(strMake & " is already in the list")
                    Else
                        ' Since this is a new category, add it to the combo box
                        cbxMakes.Items.Add(strMake)
                    End If
    
                    cbxMakes.Text = strMake
                End If
            End If
    End Sub
  17. In the Class Name combo box, select btnNewModel
  18. In the Method Name combo box, select Click and implement the event as follows:
      
    Private Sub btnNewModelClick(ByVal sender As Object, 
                                      ByVal e As System.EventArgs) 
                                      Handles btnNewModel.Click
            Dim Editor As ModelEditor = New ModelEditor
    
            If Editor.ShowDialog() = DialogResult.OK Then
    
                If Editor.txtModel.Text.Length > 0 Then
                    Dim strModel As String = Editor.txtModel.Text
    
                    ' Make sure the category is not yet in the list
                If cbxModels.Items.Contains(strModel) Then
                        MsgBox(strModel & " is already in the list")
                    Else
                        ' Since this is a new category, add it to the combo box
                        cbxModels.Items.Add(strModel)
                    End If
    
                    cbxModels.Text = strModel
                End If
            End If
    End Sub
  19. In the Class Name combo box, select btnNewCategory
  20. In the Method Name combo box, select Click and implement the event as follows:
      
    Private Sub btnNewCategoryClick(ByVal sender As Object, 
                                         ByVal e As System.EventArgs) 
                                         Handles btnNewCategory.Click
            Dim Editor As CategoryEditor = New CategoryEditor
    
            If Editor.ShowDialog() = DialogResult.OK Then
                If Editor.txtCategory.Text.Length > 0 Then
                    Dim strCategory As String = Editor.txtCategory.Text
    
                    ' Make sure the category is not yet in the list
                    If cbxCategories.Items.Contains(strCategory) Then
                        MsgBox(strCategory & " is already in the list")
                    Else
                        ' Since this is a new category, add it to the combo box
                        cbxCategories.Items.Add(strCategory)
                    End If
    
                    cbxCategories.Text = strCategory
                End If
            End If
    End Sub
  21. Save the file
  22. To create an icon, on the main menu, click Project -> Add New Item...
  23. In the Templates list, click Icon File
  24. Set the Name to cpap1 and click Add
  25. Right-click the white area and click Delete Image Type
  26. Design the 16x16, 16 colors version of the icon as follows:
     
    House
  27. On the main menu, click File -> Save cpap1.ico As
  28. Select the bin\Debug folder of the current folder and click Save
  29. On the main menu, click File -> Close
  30. In the Solution Explorer, expand bin and expand Debug
  31. In the Solution Explorer, right-click the Debug folder -> Add -> New Item...
  32. In the Templates list, make sure Icon File is selected.
    Set the Name to cpap2 and click Add
  33. Right-click the white area and click Delete Image Type
  34. Design the 16x16, 16 colors version of the icon as follows:
     
  35. Save the file and close the icon window
  36. In the Solution Explorer, right- click the Debug folder -> Add -> New Item...
  37. In the Templates list, make sure Icon File is selected.
    Set the Name to year1 and click Add
  38. Right-click the white area and click Delete Image Type
  39. Design the 16x16, 16 colors version of the icon as follows:
     
  40. Save the file and close the icon window
  41. In the Solution Explorer, right- click the Debug folder -> Add -> New Item...
  42. In the Templates list, make sure Icon File is selected.
    Set the Name to year2 and click Add
  43. Right-click the white area and click Delete Image Type
  44. Design the 16x16, 16 colors version of the icon as follows:
     
  45. Save the file and close the icon window
  46. In the Solution Explorer, right- click the Debug folder -> Add -> New Item...
  47. In the Templates list, make sure Icon File is selected.
    Set the Name to make1 and click Add
  48. Right-click the white area and click Delete Image Type
  49. Design the 16x16, 16 colors version of the icon as follows:
     
    Icon Design: Diamond
  50. Save the file and close the icon window
  51. In the Solution Explorer, right- click the Debug folder -> Add -> New Item...
  52. In the Templates list, make sure Icon File is selected.
    Set the Name to make2 and click Add
  53. Right-click the white area and click Delete Image Type
  54. Design the 16x16, 16 colors version of the icon as follows:
     
    Icon Design: Diamond
  55. Save the file and close the icon window
  56. In the Solution Explorer, right- click the Debug folder -> Add -> New Item...
  57. In the Templates list, make sure Icon File is selected.
    Set the Name to model1 and click Add
  58. Right-click the white area and click Delete Image Type
  59. Design the 16x16, 16 colors version of the icon as follows:
     
  60. Save the file and close the icon window
  61. In the Solution Explorer, right- click the Debug folder -> Add -> New Item...
  62. In the Templates list, make sure Icon File is selected.
    Set the Name to model2 and click Add
  63. Right-click the white area and click Delete Image Type
  64. Design the 16x16, 16 colors version of the icon as follows:
     
  65. Save the file and close the icon window
  66. In the Solution Explorer, right- click the Debug folder -> Add -> New Item...
  67. In the Templates list, make sure Icon File is selected.
    Set the Name to category1 and click Add
  68. Right-click the white area and click Delete Image Type
  69. Design the 16x16, 16 colors version of the icon as follows:
     
  70. Save the file and close the icon window
  71. In the Solution Explorer, right- click the Debug folder -> Add -> New Item...
  72. In the Templates list, make sure Icon File is selected.
    Set the Name to category2 and click Add
  73. Right-click the white area and click Delete Image Type
  74. Design the 16x16, 16 colors version of the icon as follows:
     
    Icon Design: Minus
  75. Save the file and close the icon window
  76. In the Solution Explorer, right-click Form1.cs and click Rename
  77. Type Central.vb and press Enter twice to display the Central form
  78. From the Components section of the Toolbox, click ImageList and click the form
  79. In the Properties window, click (Name) and type AutoPartsImages
  80. Click the ellipsis button of the Images field
  81. In the Image Collection Editor, click Add
  82. Locate the folder that contains the icons you created and display it in the Look In combo box
  83. Select cpap1.ico and click Open
  84. In the same way, add the other pictures in the following order: cpap2.ico, year1.ico, year2.ico, make1.ico, make2.ico, model1.ico, model2.ico, category1.ico, and category1.ico
     
    Image Collection Editor
  85. Click OK
  86. Design the form as follows:
     
    College Park Auto Parts - Form Design
    Control Text Name Other Properties
    Label Label College Park Auto-Parts   Font: Times New Roman, 20.25pt, style=Bold
    ForeColor: Blue
    Panel     Height: 2
    GroupBox GroupBox Part Identification    
    TreeView TreeView   tvwAutoParts ImageList: imgAutoParts
    GroupBox GroupBox Available Parts    
    ListView ListView   lvwAutoParts FullRowSelect: True
    GridLines: True
    View: Details
    Columns   (Name) Text TextAlign Width
    colPartNumber Part #    
    colPartName Part Name   300
    colUnitPrice Unit Price Right 80
    GroupBox GroupBox Customer Order - Selected Parts    
    Label Label Part #    
    Label Label Part Name    
    Label Label Unit Price    
    Label Label Qty    
    Label Label Sub Total    
    TextBox TextBox   txtPartNumber  
    TextBox TextBox   txtPartName  
    TextBox TextBox 0.00 txtUnitPrice TextAlign: Right
    TextBox TextBox 0 txtQuantity TextAlign: Right
    TextBox TextBox 0.00 txtSubTotal TextAlign: Right
    Button Button Add/Select btnAdd
    ListView ListView   lvwSelectedParts FullRowSelect: True
    GridLines: True
    View: Details
    Columns   (Name) Text TextAlign Width
    colPartNumberSelected Part #   45
    colPartNameSelected Part Name   274
    colUnitPriceSelected Unit Price Right 58
    colQuantitySelected Qty Right 28
    colSubTotalSelected Sub-Total Right 58
    GroupBox GroupBox Order Summary
    Button Button New Au&to Part... btnNewAutoPart  
    Label Label Receipt #:  
    TextBox TextBox txtSave
    Button Button Save btnSave
    Label Label Tax Rate:
    TextBox TextBox 7.75 txtTaxRate TextAlign: Right
    Label Label %
    Label Label Parts Total:
    TextBox TextBox 0.00 txtPartsTotal TextAlign: Right
    Button Button &New Customer Order btnNewCustomerOrder  
    Label Label Receipt #:  
    TextBox TextBox txtOpen
    Button Button Save btnSave
    Label Label Tax Amount:
    TextBox TextBox 0.00 txtTaxAmount TextAlign: Right
    Label Label Order Total:
    TextBox TextBox 0.00 txtOrderTotal TextAlign: Right
    Button Button Close btnClose  
  87. Right-click the table and click Form View
  88. In the Class Name combo box, select lvwAutoParts
  89. In the Method Name combo box, select DoubleClick and implement the event as follows:
     
    Private Sub lvwAutoPartsDoubleClick(ByVal sender As Object, 
                                             ByVal e As System.EventArgs) 
                                             Handles lvwAutoParts.DoubleClick
            Dim lviAutoPart As ListViewItem = lvwAutoParts.SelectedItems(0)
    
            If (lvwAutoParts.SelectedItems.Count = 0) Or 
               (lvwAutoParts.SelectedItems.Count > 1) Then
                Exit Sub
            End If
    
            txtPartNumber.Text = lviAutoPart.Text
            txtPartName.Text = lviAutoPart.SubItems(1).Text
            txtUnitPrice.Text = lviAutoPart.SubItems(2).Text
    
            txtQuantity.Text = "1"
            txtSubTotal.Text = lviAutoPart.SubItems(2).Text
    
            txtQuantity.Focus()
    End Sub
  90. In the Class Name combo box, select txtUnitPrice
  91. In the Method Name combo box, select Leave and implement the event as follows:
     
    Private Sub txtUnitPriceLeave(ByVal sender As Object, 
                                       ByVal e As System.EventArgs) 
                                       Handles txtUnitPrice.Leave, 
                                               txtQuantity.Leave
            Dim UnitPrice As Double
            Dim Quantity As Integer
            Dim SubTotal As Double
    
            Try
                UnitPrice = CDbl(txtUnitPrice.Text)
            Catch Exc As FormatException
                MsgBox("Invalid Unit Price!")
            End Try
    
            Try
                Quantity = CInt(txtQuantity.Text)
            Catch Exc As FormatException
                MsgBox("Invalid Quandtity!")
            End Try
    
            SubTotal = UnitPrice * Quantity
            txtSubTotal.Text = FormatNumber(SubTotal)
    End Sub
    
    Public Sub CalculateOrder()
            ' Calculate the current total order and update the order
            Dim PartsTotal As Double
            Dim TaxRate As Double
            Dim TaxAmount As Double
            Dim OrderTotal As Double
            Dim SubItem As ListViewItem.ListViewSubItem
            Dim lviAutoPart As ListViewItem
    
            For Each lviAutoPart In lvwSelectedParts.Items
                SubItem = lviAutoPart.SubItems(4)
                PartsTotal = PartsTotal + CDbl(SubItem.Text)
            Next
    
            Try
                TaxRate = CDbl(txtTaxRate.Text) / 100
            Catch Exc As FormatException
                MsgBox("Invalid Tax Rate")
            End Try
    
            TaxAmount = PartsTotal * TaxRate
            OrderTotal = PartsTotal + TaxAmount
    
            txtPartsTotal.Text = FormatNumber(PartsTotal)
            txtTaxAmount.Text = FormatNumber(TaxAmount)
            txtOrderTotal.Text = FormatNumber(OrderTotal)
    End Sub
  92. In the Class Name combo box, select lvwSelectedParts
  93. In the Method Name combo box, select DoubleClick and implement the event as follows:
     
    Private Sub lvwSelectedPartsDoubleClick(ByVal sender As Object, 
                                             ByVal e As System.EventArgs) 
                                             Handles lvwSelectedParts.DoubleClick
            Dim lviSelectedPart As ListViewItem = lvwSelectedParts.SelectedItems(0)
    
            If (lvwSelectedParts.SelectedItems.Count = 0) Or 
                (lvwSelectedParts.SelectedItems.Count > 1) Then
                Exit Sub
            End If
    
            txtPartNumber.Text = lviSelectedPart.Text
            txtPartName.Text = lviSelectedPart.SubItems(1).Text
            txtUnitPrice.Text = lviSelectedPart.SubItems(2).Text
            txtQuantity.Text = lviSelectedPart.SubItems(3).Text
            txtSubTotal.Text = lviSelectedPart.SubItems(4).Text
    
            lvwSelectedParts.Items.Remove(lviSelectedPart)
            CalculateOrder()
    End Sub
  94. In the Solution Explorer, right-click CollegeParkAutoParts1 -> Add -> Class...
  95. Set the name to PartDescription and press Enter
  96. To create a class that can hold a structured item of a list, change the class as follows:
     
    <Serializable()> Public Class PartDescription
        ' These members will be used to define a car part
        Private ID As Long
        Private yr As Integer
        Private mk As String
        Private mdl As String
        Private cat As String
        Private name As String
        Private price As Double
    
        Public Sub New()
            ID = 0
            yr = 1960
            mk = ""
            mdl = ""
            name = "Unknown"
            price = 0.0
        End Sub
    
        Public Sub New(ByVal code As Long, ByVal year As Integer, 
                       ByVal make As String, ByVal model As String, 
                       ByVal type As String, ByVal desc As String, 
                       ByVal UPrice As Double)
    
            ID = code
            yr = year
            mk = make
            mdl = model
            cat = type
            name = desc
            price = UPrice
        End Sub
    
        Public Property PartNumber() As Long
            Get
                Return ID
            End Get
            Set(ByVal value As Long)
                ID = value
            End Set
        End Property
    
        Public Property Year() As Integer
            Get
                Return yr
            End Get
            Set(ByVal value As Integer)
                yr = value
            End Set
        End Property
    
        Public Property Make() As String
            Get
                Return mk
            End Get
            Set(ByVal value As String)
                mk = value
            End Set
        End Property
    
        Public Property Model() As String
            Get
                Return mdl
            End Get
            Set(ByVal value As String)
                mdl = value
            End Set
        End Property
    
        Public Property Category() As String
            Get
                Return cat
            End Get
            Set(ByVal value As String)
                cat = value
            End Set
        End Property
    
        Public Property PartName() As String
            Get
                Return name
            End Get
            Set(ByVal value As String)
                name = value
            End Set
        End Property
    
        Public Property UnitPrice() As Double
            Get
                Return price
            End Get
            Set(ByVal value As Double)
                price = value
            End Set
        End Property
    
        Public Overrides Function ToString() As String
            Return PartNumber & " " & 
                   CStr(Year) & " " & 
                   Make & " " & 
                   Model & " " & 
                   Category & " " & 
                   PartName & " " & 
                   UnitPrice
        End Function
    End Class        
  97. In the Solution Explorer, right-click CollegeParkAutoParts3 -> Add -> Class...
  98. Set the name to PartOrdered and press Enter
  99. To create another class independent for a list, change the document as follows:
     
    <Serializable()> Public Class PartOrdered
        Public PartNumber As Long
        Public PartName As String
        Public UnitPrice As Double
        Public Quantity As Integer
        Public SubTotal As Double
    End Class
  100. Save all
  101. In the Solution Explorer, right-click NewStoreItem and click View Code
  102. Add the following lines:
     
    Imports System.IO
    Imports System.Runtime.Serialization.Formatters.Binary
    
    Public Class NewStoreItem
        Private ListOfAutoParts As List(Of PartDescription)
    
  103. In the Class Name combo box, select btnSubmit
  104. In the Method Name combo box, select Click and implement the event as follows:
     
    Private Sub btnSubmitClick(ByVal sender As Object, 
                                    ByVal e As System.EventArgs) 
                                    Handles btnSubmit.Click
            Dim stmAutoParts As FileStream
            Dim bfmAutoParts As BinaryFormatter = New BinaryFormatter
    
            ' If this directory doesn't exist, create it
            Directory.CreateDirectory("C:\College Park Auto Parts")
            ' This is the file that holds the list of items
            Dim FileName As String = "C:\College Park Auto Parts\Parts.prs"
    
            ' Create a random number that will be used to identify the item
            Dim RndNumber As Random = New Random()
            txtPartNumber.Text = RndNumber.Next(100000, 999999).ToString()
    
            ' Make sure the user had selected a make
            If cbxYears.Text.Length = 0 Then
                MsgBox("You must specify the year")
                cbxYears.Focus()
                Exit Sub
            End If
    
            ' Make sure the user had selected a make
            If cbxMakes.Text.Length = 0 Then
                MsgBox("You must specify the car name")
                cbxMakes.Focus()
                Exit Sub
            End If
    
            ' Make sure the user had selected a model
            If cbxModels.Text.Length = 0 Then
                MsgBox("You must specify the model of the car")
                cbxModels.Focus()
                Exit Sub
            End If
    
            ' Make sure the user had selected the part category
            If cbxCategories.Text.Length = 0 Then
                MsgBox("You must specify the part's category")
                cbxCategories.Focus()
                Exit Sub
            End If
    
            ' Make sure the user had entered a name/description
            If txtPartName.Text.Length = 0 Then
                MsgBox("You must enter the name (or a " & 
                                "short description) for the part")
                txtPartName.Focus()
                Exit Sub
            End If
    
            ' Make sure the user had typed a price for the item
            If txtUnitPrice.Text.Length = 0 Then
                MsgBox("You must enter the price of the item")
                txtUnitPrice.Focus()
                Exit Sub
            End If
    
            ' Before saving the new part, find out if there was
            ' already a file that holds the list of parts
            ' If that file exists, open it and store its parts 
            ' in our lstParts variable
            If File.Exists(FileName) Then
                stmAutoParts = New FileStream(FileName, 
                                              FileMode.Open, 
                                              FileAccess.Read, 
                                              FileShare.Read)
    
                Try
                    ' Retrieve the list of items from file
                    ListOfAutoParts = 
    			CType(bfmAutoParts.Deserialize(stmAutoParts),  
                                            List(Of PartDescription))
                Finally
    
                    stmAutoParts.Close()
                End Try
            End If
    
            ' Create the part
            Dim Part As PartDescription = New PartDescription
            Part.PartNumber = CLng(txtPartNumber.Text)
            Part.Year = CInt(cbxYears.Text)
            Part.Make = cbxMakes.Text
            Part.Model = cbxModels.Text
            Part.Category = cbxCategories.Text
            Part.PartName = txtPartName.Text
            Part.UnitPrice = CDbl(txtUnitPrice.Text)
    
            ' Call the Add method of our collection class to add the part
            ListOfAutoParts.Add(Part)
    
            ' Save the list
            stmAutoParts = New FileStream(FileName, 
                                          FileMode.Create, 
                                          FileAccess.Write, 
                                          FileShare.Write)
    
            Try
                bfmAutoParts.Serialize(stmAutoParts, ListOfAutoParts)
    
                ' After saving the item, reset the form
                cbxYears.Text = ""
                cbxMakes.Text = ""
                cbxModels.Text = ""
                cbxCategories.Text = ""
                txtPartName.Text = ""
                txtUnitPrice.Text = "0.00"
                txtPartNumber.Text = RndNumber.Next(100000, 999999).ToString()
            Finally
                stmAutoParts.Close()
            End Try
    End Sub
  105. In the Solution Explorer, right-click Central.vb and click View Code
  106. Add the following namespaces in the top section of the file and declare the two variables:
     
    Imports System.IO
    Imports System.Runtime.Serialization.Formatters.Binary
    
    Public Class Central
        Private iFileName As Integer
        Private ListOfAutoParts As List(Of PartDescription)
  107. In the Class Name combo box, select btnSaveCustomerOrder
  108. In the Method Name combo box, select Click and implement the event as follows:
     
    Private Sub btnSaveClick(ByVal sender As Object, 
                                  ByVal e As System.EventArgs) 
                                  Handles btnSave.Click
            Dim i As Integer
            Dim Part As PartsOrdered
            Dim bfmCustomerOrder As BinaryFormatter = New BinaryFormatter()
    
            ' We will store our files in the following folder    
            Dim strDirectory As String = "C:\College Park Auto Parts\Receipts"
            Dim DirInfo As DirectoryInfo = New DirectoryInfo(strDirectory)
    
            Dim strFilename As String = strDirectory & "\" & txtSave.Text & ".cap"
    
            Dim ListOfOrderedParts As List(Of PartsOrdered)
    
            If lvwSelectedParts.Items.Count = 0 Then
                Exit Sub
            Else
    
                ListOfOrderedParts = New List(Of PartsOrdered)
    
                For i = 0 To lvwSelectedParts.Items.Count - 1
    
                    Part = New PartsOrdered
    
                    Part.PartNumber = CLng(lvwSelectedParts.Items(i).Text)
                    Part.PartName = lvwSelectedParts.Items(i).SubItems(1).Text
                    Part.UnitPrice = 
    		    CDbl(lvwSelectedParts.Items(i).SubItems(2).Text)
                    Part.Quantity = 
    		    CInt(lvwSelectedParts.Items(i).SubItems(3).Text)
                    Part.SubTotal = CDbl(lvwSelectedParts.Items(i).SubItems(4).Text)
                    ListOfOrderedParts.Add(Part)
                Next
    
                Dim stmCustomerOrder As FileStream = New FileStream(strFilename, 
                                                                    FileMode.Create)
    
                Try
                    bfmCustomerOrder.Serialize(stmCustomerOrder, ListOfOrderedParts)
                Finally
                    stmCustomerOrder.Close()
                End Try
            End If
    End Sub
  109. Save all
  110. In the Solution Explorer, right-click NewStoreItem.vb and click View Code
  111. In the Class Name combo box, select cbxMakes
  112. In the Method Name combo box, select SelectedIndexChanged and implement its event as follows:
     
    Private Sub cbxMakesSelectedIndexChanged(ByVal sender As Object, 
                                              ByVal e As System.EventArgs) 
                                              Handles cbxMakes.SelectedIndexChanged
        cbxModels.Text = ""
        cbxModels.Items.Clear()
        Dim Part As PartDescription
    
        For Each Part In ListOfAutoParts
            If Part.Make = cbxMakes.Text Then
                If Not cbxModels.Items.Contains(Part.Model) Then
                    cbxModels.Items.Add(Part.Model)
                End If
            End If
        Next
    End Sub
  113. In the Solution Explorer, right-click Central.vb and click View Code
  114. In the Class Name, select btnAdd
  115. In the Method Name combo box, select Click and implement the event as follows:
     
    Private Sub btnAddClick(ByVal sender As Object, 
                                 ByVal e As System.EventArgs) 
                                 Handles btnAdd.Click
            Dim Part As PartDescription
            Dim lviSelectedPart As ListViewItem
    
            REM If the user didn't enter a part number, don't do anything
            If txtPartNumber.Text.Length = 0 Then
                MsgBox("There is no part to be added to the order")
                Exit Sub
            End If
    
            REM Since the user entered a part, check each item in the list of parts
            For Each Part In ListOfAutoParts
                REM If you find a part number that 
    	    REM corresponds to the user's entry ...
                If Part.PartNumber = CLng(txtPartNumber.Text) Then
                    REM ... display it in the Selected Parts list view
                    lviSelectedPart = New ListViewItem(Part.PartNumber)
    
                    lviSelectedPart.SubItems.Add(Part.PartName)
                    lviSelectedPart.SubItems.Add(Part.UnitPrice)
                    lviSelectedPart.SubItems.Add(txtQuantity.Text)
                    lviSelectedPart.SubItems.Add(txtSubTotal.Text)
                    lvwSelectedParts.Items.Add(lviSelectedPart)
                End If
            Next
    
            REM Update the order evaluation
            CalculateOrder()
    End Sub
  116. In the Class Name, select btnOpen
  117. In the Method Name combo box, select Click and implement its event as follows:
     
    Private Sub btnOpenClick(ByVal sender As Object, 
                                  ByVal e As System.EventArgs) 
                                  Handles btnOpen.Click
            Dim Part As PartOrdered
            Dim strFilename As String
            Dim lviReceiptPart As ListViewItem
            Dim ListOfReceipts As List(Of PartOrdered)
            Dim ReceiptsFormatter As BinaryFormatter = New BinaryFormatter()
            Dim StreamReceipts As FileStream = Nothing
    
            REM Identify the folder where the receipts are stored
            Dim strDirectory As String = "C:\College Park Auto Parts\Receipts"
    
            REM Get a reference to the receipts
            Dim dirReceipts As DirectoryInfo = New DirectoryInfo(strDirectory)
            REM Get the list of receipts in the folder
            Dim fleReceipts() As FileInfo = dirReceipts.GetFiles()
    
            REM Check that the user entered a receipt number
            REM If not, don't do anything
            If txtOpen.Text.Length = 0 Then
                MsgBox("You must enter a receipt number" & vbCrLf & 
                                "There is no receipt number to " & 
                                "open a customer's order")
                txtOpen.Focus()
                Exit Sub
            End If
    
            REM If no receipt was created before, let the user know
            If fleReceipts.Length = 0 Then
                MsgBox("There is no customer order to open")
                txtOpen.Focus()
                Exit Sub
            Else
                REM Since there is at least one receipt,
                REM get ready to use it/them
                lvwAutoParts.Items.Clear()
                lvwSelectedParts.Items.Clear()
    
                REM Create a file name using the path to the folder, 
                REM the receipt number, and the .cap extension
                strFilename = strDirectory & "\" & txtOpen.Text & ".cap"
    
                REM Check if there is a file with that receipt number
                If File.Exists(strFilename) Then
                    Try
                        REM If so, retrieve the contents of that file
                     StreamReceipts = New FileStream(strFilename, FileMode.Open)
                        ListOfReceipts = 
    		CType(ReceiptsFormatter.Deserialize(StreamReceipts),  
                                               List(Of PartOrdered))
    
                        REM And display the contents of that receipt number in 
                        REM the Selected Parts list view
                        For Each Part In ListOfReceipts
                            lviReceiptPart = New ListViewItem(Part.PartNumber)
    
                            lviReceiptPart.SubItems.Add(Part.PartName)
                          lviReceiptPart.SubItems.Add(FormatNumber(Part.UnitPrice))
                            lviReceiptPart.SubItems.Add(Part.Quantity)
                          lviReceiptPart.SubItems.Add(FormatNumber(Part.SubTotal))
                            lvwSelectedParts.Items.Add(lviReceiptPart)
                        Next
                    Finally
                        StreamReceipts.Close()
                    End Try
    
                    REM Just in case, update the calculation
                    CalculateOrder()
                    REM In case the user will modify the file that was opened,
                    REM put its receipt number in the Save text box
                    txtSave.Text = txtOpen.Text
                Else
                    REM Since it appears that the user 
    		REM entered an invalid receipt number
                    REM let him/her know
                    MsgBox("There is no customer order with that receipt number")
                End If
            End If
    End Sub
  118. Save the file
  119. In the Solution Explorer, right-click NewStoreItem.vb and click View Code
  120. In the Class Name combo box, select (NewStoreItem Events)
  121. In the Method Name combo box, select Load and implement the event as follows:
     
    Private Sub NewStoreItemLoad(ByVal sender As Object, 
                                      ByVal e As System.EventArgs) 
                                      Handles Me.Load
            REM Since all values seem ready, prepare to process the item
            Dim i As Integer
            Dim Part As PartDescription
            Dim RndNumber As Random = New Random
            Dim StreamAutoParts As FileStream = Nothing
            Dim bfmAutoParts As BinaryFormatter = New BinaryFormatter
    
            ListOfAutoParts = New List(Of PartDescription)
    
            For i = DateTime.Today.Year + 1 To 1960 Step -1
                cbxYears.Items.Add(i)
            Next
    
            REM Create a random number that will be used to identify the item
            txtPartNumber.Text = RndNumber.Next(100000, 999999)
    
            REM This is the file that holds the list of parts
            Dim FileName As String = "C:\College Park Auto Parts\Parts.prs"
    
            If File.Exists(FileName) Then
                StreamAutoParts = New FileStream(FileName, 
                                                        FileMode.Open, 
                                                        FileAccess.Read, 
                                                        FileShare.Read)
                Try
                    REM Retrieve the list of items from file
                    ListOfAutoParts = 
    		    CType(bfmAutoParts.Deserialize(StreamAutoParts),  
                                            List(Of PartDescription))
    
                    REM Display the car manufacturers in the Make combo box
                    For i = 0 To ListOfAutoParts.Count - 1
                        Part = CType(ListOfAutoParts(i), PartDescription)
    
                        If Not cbxMakes.Items.Contains(Part.Make) Then
                            cbxMakes.Items.Add(Part.Make)
                        End If
                    Next
    
                    REM Display the pats categories in the Category combo box
                    For i = 0 To ListOfAutoParts.Count - 1
                        Part = CType(ListOfAutoParts(i), PartDescription)
    
                        If Not cbxCategories.Items.Contains(Part.Category) Then
                            cbxCategories.Items.Add(Part.Category)
                        End If
                Next
                Finally
                    StreamAutoParts.Close()
                End Try
            End If
    End Sub
  122. In the Solution Explorer, right-click Central.vb and click View Code
  123. In the Class Name combo box, select txtPartNumber
  124. In the Method name combo box, select Leave and implement the event as follows:
     
    Private Sub txtPartNumberLeave(ByVal sender As Object, 
                                        ByVal e As System.EventArgs) 
                                        Handles txtPartNumber.Leave
            Dim Part As PartDescription
            ' We will allow the user to enter a part number
            ' In the beginning, we assume that the user 
            ' had entered an invalid number
            Dim Found As Boolean = False
            ' This will represent the part found, if any
            Dim PartFound As PartDescription = Nothing
    
            ' After the user had entered a part number,
            ' check the whole list of parts
            For Each Part In ListOfAutoParts
                ' If you find a part that holds the number the user had entered
                If Part.PartNumber = CLng(txtPartNumber.Text) Then
                    ' Mark that part
                    PartFound = Part
                    ' And update the flag that specifies 
    		REM that the part has been found
                    Found = True
                End If
                ' If the part number was not found, check the next
            Next ' If no part has that number, the found flag keeps marked as false
    
            ' If a part with that number was found...
            If Found = True Then
                ' Show the corresponding part name and unit price
                txtPartName.Text = PartFound.PartName
                txtUnitPrice.Text = FormatNumber(PartFound.UnitPrice)
                txtQuantity.Text = "1"
                txtSubTotal.Text = FormatNumber(PartFound.UnitPrice)
                ' Give focus to the quantity in case the user was to increase it
                txtQuantity.Focus()
            Else
                ' Since no part with that number was found,
                ' reset the text boxes
                txtPartName.Text = ""
                txtUnitPrice.Text = "0.00"
                txtQuantity.Text = "0"
                txtSubTotal.Text = "0.00"
    
                ' Let the user know that the part number that 
                ' was entered is not in the list
                MsgBox("There is no part with that number")
            End If
    End Sub
  125. Under the above End Sub line, create the following procedure:
     
    Public Sub ShowAutoParts()
            Dim Years As Integer
            Dim NodeYear
            Dim NodeMake As TreeNode
            Dim NodeModel As TreeNode
            Dim Part As PartDescription
            Dim StreamAutoParts As FileStream
            Dim bfmAutoParts As BinaryFormatter = New BinaryFormatter
    
            tvwAutoParts.Nodes.Clear()
    
            Dim nodRoot As TreeNode = 
              tvwAutoParts.Nodes.Add("College Park Auto-Parts", 
                                     "College Park Auto-Parts", 0, 1)
            ' Show the years nodes
            For Years = DateTime.Today.Year + 1 To 1960 Step -1
                nodRoot.Nodes.Add(CStr(Years), CStr(Years), 2, 3)
            Next
    
            tvwAutoParts.SelectedNode = nodRoot
            ' Expand the root node
            tvwAutoParts.ExpandAll()
    
            ListOfAutoParts = New List(Of PartDescription)
    
            ' This is the file that holds the list of auto parts
            Dim Filename As String = "C:\College Park Auto Parts\Parts.prs"
    
            If File.Exists(FileName) Then
                StreamAutoParts = New FileStream(Filename, 
                                                 FileMode.Open, 
                                                 FileAccess.Read, 
                                                 FileShare.Read)
                Try
                    ' Retrieve the list of parts from file
                    ListOfAutoParts = 
    			CType(bfmAutoParts.Deserialize(StreamAutoParts),  
                                            List(Of PartDescription))
    
                    ' Show the makes nodes
                    For Each NodeYear In nodRoot.Nodes
    
                        Dim ListOfMakes As List(Of String) = New List(Of String)
    
                        For Each Part In ListOfAutoParts
                            If NodeYear.Text = Part.Year.ToString() Then
                                If Not ListOfMakes.Contains(Part.Make) Then
                                    ListOfMakes.Add(Part.Make)
                                End If
                            End If
                        Next
    
                        For Each strMake As String In ListOfMakes
                            NodeYear.Nodes.Add(strMake, strMake, 4, 5)
                        Next
                    Next
    
                    ' Showing the models nodes
                    For Each NodeYear In nodRoot.Nodes
    
                        For Each NodeMake In NodeYear.Nodes
    
                            Dim ListOfModels As List(Of String) = 
    				New List(Of String)
    
                            For Each Part In ListOfAutoParts
                                If (NodeYear.Text = CStr(Part.Year)) And 
                                    (NodeMake.Text = Part.Make) Then
    
                                    If Not ListOfModels.Contains(Part.Model) Then
                                        ListOfModels.Add(Part.Model)
                                    End If
    
                                End If
                            Next
    
                            For Each strModel As String In ListOfModels
                                NodeMake.Nodes.Add(strModel, strModel, 6, 7)
                            Next
                        Next
                    Next
    
                    ' Showing the categories nodes
                    For Each NodeYear In nodRoot.Nodes
                        For Each NodeMake In NodeYear.Nodes
                            For Each NodeModel In NodeMake.Nodes
                                Dim ListOfCategories As 
    				List(Of String) = New List(Of String)
    
                                For Each Part In ListOfAutoParts
                                    If (NodeYear.Text = CStr(Part.Year)) And 
                                        (NodeMake.Text = Part.Make) And 
                                        (NodeModel.Text = Part.Model) Then
    
                               If Not ListOfCategories.Contains(Part.Category) Then
                                            ListOfCategories.Add(Part.Category)
                                        End If
                                    End If
                                Next
    
                                For Each strCategory As String In ListOfCategories
                              NodeModel.Nodes.Add(strCategory, strCategory, 8, 9)
                                Next
                            Next
                        Next
                    Next
                Finally
                    StreamAutoParts.Close()
                End Try
            End If
    End Sub
  126. In the Class Name combo box, select btnNewAutoPart
  127. In the Method Name combo box, select Click and implement the event as follows:
     
    Private Sub btnNewAutoPartClick(ByVal sender As Object, 
                                         ByVal e As System.EventArgs) 
                                         Handles btnNewAutoPart.Click
            Dim Editor As NewStoreItem = New NewStoreItem
    
            If Editor.ShowDialog() = DialogResult.Cancel Then
                ShowAutoParts()
            End If
    End Sub
  128. In the Class Name combo box, select btnNewCustomerOrder
  129. In the Method Name combo box, select Click and implement the event as follows:
     
    Private Sub btnNewCustomerOrderClick(ByVal sender As Object, 
                                              ByVal e As System.EventArgs) 
                                              Handles btnNewCustomerOrder.Click
            ' We will store our files in the following folder    
            Dim strDirectory As String = "C:\College Park Auto Parts\Receipts"
            Dim dirInfo As DirectoryInfo = Directory.CreateDirectory(strDirectory)
    
            ' Get the list of files, if any, from our directory
            Dim ListOfFiles() As FileInfo = dirInfo.GetFiles()
    
            ' If there is no file in the directory,
            ' then we will use 1000 as the first file name
            If ListOfFiles.Length = 0 Then
                iFileName = 1000
            Else ' If there was at least one file in the directory
                ' Get a reference to the last file
                Dim LastFile As FileInfo = ListOfFiles(ListOfFiles.Length - 1)
                ' Get the name of the last file without its extension
                Dim fwe As String = 
    		Path.GetFileNameWithoutExtension(LastFile.FullName)
                ' Increment the name of the file by 1
                iFileName = CInt(fwe) + 1
            End If
    
            txtSave.Text = iFileName.ToString()
    
            lvwAutoParts.Items.Clear()
            lvwSelectedParts.Items.Clear()
    End Sub
  130. In the Class Name combo box, select (Central Events)
  131. In the Method Name combo box, select Load and implement the event as follows:
     
    Private Sub CentralLoad(ByVal sender As Object, 
                                 ByVal e As System.EventArgs) 
                                 Handles Me.Load
            ShowAutoParts()
            btnNewCustomerOrderClick(sender, e)
    End Sub
  132. In the Class Name combo box, select tvwAutoParts
  133. In the Method Name combo box, select NodeMouseClick and implement the event as follows:
     
    Private Sub tvwAutoPartsNodeMouseClick(ByVal sender As Object, 
                  ByVal e As System.Windows.Forms.TreeNodeMouseClickEventArgs) 
                                            Handles tvwAutoParts.NodeMouseClick
        Dim Part As PartDescription
        Dim lviAutoPart As ListViewItem
        Dim NodeClicked As TreeNode = e.Node
    
        If NodeClicked.Level = 4 Then
            lvwAutoParts.Items.Clear()
        End If
    
        Try
            For Each Part In ListOfAutoParts
                If (Part.Category = NodeClicked.Text) And 
                    (Part.Model = NodeClicked.Parent.Text) And 
                    (Part.Make = NodeClicked.Parent.Parent.Text) And 
                    (CStr(Part.Year) = NodeClicked.Parent.Parent.Parent.Text) Then
                    lviAutoPart = New ListViewItem(Part.PartNumber)
    
                    lviAutoPart.SubItems.Add(Part.PartName)
                    lviAutoPart.SubItems.Add(FormatNumber(Part.UnitPrice))
                    lvwAutoParts.Items.Add(lviAutoPart)
                End If
            Next
        Catch Exc As NullReferenceException
    
        End Try
    End Sub
  134. In the Class Name combo box, select btnClose
  135. In the Method Name combo box, select Click and implement the event as follows:
     
    Private Sub btnCloseClick(ByVal sender As Object, 
                                   ByVal e As System.EventArgs) 
                                   Handles btnClose.Click
            End
    End Sub
  136. Execute the application
  137. Click the New Auto Part button and use the Part Editor to create a few parts (let the computer generate the part numbers)
     
    Auto Part
  138. Close the Part Editor
  139. Create a few customer part orders and save them:
     
    College Park Auto Parts: Customer Order
     
    College Park Auto Parts: Part Selection
  140. Close the forms and return to your programming environment
  141. Execute the application again and open a previously saved order
  142. Close the forms and return to your programming environment

Exercises

 

College Park Auto Parts

  1. Open the CollegeParkAutoParts5 application from this lesson
  2. Add a context menu for the Available Parts list view with the items: Select, Edit..., and Delete
     
    AutoParts
  3. Configure the context menu so that
    1. If the user clicks Select, the behavior would be the same as if the user had double-clicked the item
    2. If the user clicks Edit..., the Part Editor dialog box would display with the part in it. The user can then edit any part (year, make, model, category, part name, or unit price) except the part number. Then the user can save the changed part
    3. If the user clicks Delete, a message box would warn the user and ask for confirmation with Yes/No answers. If the user clicks Yes, the part would be deleted from the list of auto parts
  4. Configure the application so that the user can open an order, add new parts to it, or delete parts from it, then save the order
  5. Extend the application so that the store can also sell items that are, or are not, car-related, such as books, t-shirts, cleaning items, maintenance items (steering oils, brake oils, etc), license plates, etc. Every item in the store should have an item number. The user can enter that item number in the Part # text box and press Tab or Enter. The corresponding item would then be retrieved from the database and displayed on the form. If there is no item with that number, a message box should let the user know
 

Home Copyright © 2008-2016, FunctionX, Inc.