Overview

Practical LearningPractical Learning: Introducing the Application

  1. On the C: drive (or any drive of your choice) of your computer, create a folder or directory named College Park Auto-Parts (if you create it in another drive, make the changes wherever "C:\College Park Auto-Parts" is used in this project)
  2. Save the following icons to your computer: Plus, Minus, Clipper, Clipper, Ruler, Ruler, Graph, Graph, Tool, Tool
  3. Start Microsoft Visual Studio
  4. Create a new Windows Forms App named CollegeParkAutoParts1

Application Design

Practical LearningPractical Learning: Designing the Application

  1. In the Solution Explorer, right-click Form1.cs -> Rename
  2. Type StoreInventory (to get StoreInventory.cs) and press Enter three times to display the form
  3. From the Components section of the Toolbox, click ImageList and click the form
  4. In the Properties window, click (Name) and type AutoPartsImages
  5. Click the ellipsis button of the Images field
  6. In the Image Collection Editor, click Add
  7. Select the following icons you had saved in your computer: Sign1, Sign2, Cliper1, Cliper2, Rulers1, Rulers2, Graph1, Graph2, Tool1, and Tool2
  8. Click Open

    Image Collection Editor

  9. Click OK
  10. Design the form as follows:

    College Park Auto-Parts - Store Inventory

    Control (Name) Text Other Properties
    Label Label   College Park Auto-Parts Font: Times New Roman, 24pt, style=Bold
    ForeColor: Blue
    PictureBox     BackColor: Black
    Size -> Height: 5
    GroupBox Group Box   Part Identification  
    TreeView Tree View tvwAutoParts   ImageList: AutoPartsImages
    GroupBox Group Box   Available Parts  
    ListView List View lvwAvailableParts   View: Details
    FullRowSelect: True
    GridLines: True
    Columns
    (Name) Text TextAlign Width
    colAvailablePartNumber Part #   80
    colAvailablePartName Part Name/Description   650
    colAvailableUnitPrice Unit Price Right 100
    PictureBox pbxPartImage   BorderStyle: FixedSingle
    SizeMode: AutoSize
    GroupBox Group Box   Selected Parts  
    Label Label   Part #  
    Label Label   Part Name  
    Label Label   Unit Price  
    Label Label   Qty  
    Label Label   Sub-Total  
    Text Box Text Box   txtPartNumber  
    Text Box Text Box txtPartName    
    Text Box Text Box txtUnitPrice   TextAlign: Right
    Text Box Text Box txtQuantity   TextAlign: Right
    Text Box Text Box txtSubTotal   TextAlign: Right
    Button Button btnAdd Add/Select  
    ListView List View   lvwSelectedParts View: Details
    FullRowSelect: True
    GridLines: True
    Columns
    (Name) Text TextAlign Width
    colSelectedPartNumber Part #   80
    colSelectedPartName Part Name/Description   600
    colSelectedUnitPrice Unit Price Right 100
    colSelectedQuantity Qty Right 50
    colSelectedSubTotal Sub-Total Right 90
    GroupBox Group Box   Order Summary  
    Button Button btnNewAutoPart New Auto Part...  
    Button Button btnUpdateAutoPart Update Auto Part...  
    Label Label   Selected Parts Total:  
    Text Box Text Box txtSelectedPartsTotal   TextAlign: Right
    Label Label   Tax Rate:  
    Text Box Text Box txtTaxRate   TextAlign: Right
    Label Label   Tax Amount:  
    Text Box Text Box txtTaxAmount   TextAlign: Right
    Label Label   Order Total:  
    Text Box Text Box txtOrderTotal   TextAlign: Right
    Button Button btnDeleteAutoPart Delete Auto Part...  
    Button Button btnClose Close  
  11. Double-click an unoccupied area of the form

Parts Manufacturers

.

Practical LearningPractical Learning: Creating a Part Make

public void RemoveAt(int index);

To let you remove all items from a list, both the ArrayList and the List<> classes are equipped with a method named Clear. The syntax for the ArrayList class is:

This method deletes all items from its list. Here is an example of calling this method:

using System.Collections;

namespace Numerotation
{
    public partial class Exercise : Form
    {

            Show();
        }
    }
}

Practical LearningPractical Learning: Introducing .NET Collection Classes

  1. To create a dialog box, on the main menu, click Project -> Add Form (Windows Forms)...
  2. Set the name to Make
  3. Click Add
  4. Design the form as follows:

    Vehicle Make

    Control Text Name Other Properties
    Label Label &Make:    
    TextBox Text Box   txtMake Modifiers: Public
    Button Button &OK btnOK DialogResult: OK
    Button Button &Cancel btnCancel DialogResult: Cancel

    Form Characteristics

    Form Property Value
    FormBorderStyle FixedDialog
    Text Make
    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 Form (Windows Forms)...
  6. Set the name to Model
  7. Click Add
  8. Design the form as follows:

    Vehicle Model

    Control Text Name Other Properties
    Label Label &Model:    
    TextBox Text Box   txtModel Modifiers: Public
    Button Button &OK btnOK DialogResult: OK
    Button Button &Cancel btnCancel DialogResult: Cancel

    Form Characteristics

    Form Property Value
    FormBorderStyle FixedDialog
    Text Category Editor
    StartPosition CenterScreen
    AcceptButton btnOK
    CancelButton btnCancel
    MaximizeBox False
    MinimizeBox False
    ShowInTaskbar False
  9. To create a dialog box, on the main menu, click Project -> Add Form (Windows Forms)...
  10. Set the name to Category
  11. Click Add
  12. Design the form as follows:

    Item Category

    Control Text Name Other Properties
    Label Label C&ategory:    
    TextBox Text Box   txtCategory Modifiers: Public
    Button Button &OK btnOK DialogResult: OK
    Button Button &Cancel btnCancel DialogResult: Cancel

    Form Characteristics

    Form Property Value
    FormBorderStyle FixedDialog
    Text Category
    StartPosition CenterScreen
    AcceptButton btnOK
    CancelButton btnCancel
    MaximizeBox False
    MinimizeBox False
    ShowInTaskbar False
  13. To add a new form, on the main menu, click Project -> Add Form (Windows Forms)...
  14. Set the Name to StoreItemNew
  15. Click Add
  16. Complete the design of the form as follows:
     

    Solo Music: New Store Item

    Control (Name) Text Other Properties
    Label Label   &Part #:  
    Text Box Text Box txtPartNumber    
    Button Button btnSelectPicture &Select Picture...  
    Label Label lblPictureFile .  
    Label Label   &Year:  
    Combo Box Combo Box cbxYears    
    Picture Box Picture Box pbxPartImage   BorderStyle: FixedSingle:
    SizeMode: AutoSize
    Label Label   &Make:  
    Combo Box Combo Box cbxMakes    
    Button Button btnNewMake New M&ke...  
    Label Label   M&odel:  
    Combo Box Combo Box cbxModels    
    Button Button   New Mo&del  
    Label Label   Ca&tegory:  
    Combo Box Combo Box cbxCategories    
    Button Button btnNewCategory New Cat&egory...  
    Label Label   Part Na&me:  
    Text Box Text Box txtPartName   ScrollBars: Vertical
    Multiline: True
    Label Label   &Unit Price  
    Text Box Text Box txtUnitPrice    
    Label Label   _________________  
    Button Button btnSaveAutoPart Sa&ve Auto-Part  
    Button Button btnClose &Close  
    OpenFileDialog Text Box      
  17. Click an unoccupied area of the form and, in the Properties window, change the following characteristics:
    Text: College Park Auto-Parts - New Store Item
    MaximizeBox: False
    ShowInTaskbar: False
    StartPosition: CenterScreen
  18. Double-click an unoccupied area of the form to generate its Load event
  19. Return to the form and double-click the Select Picture button
  20. Return to the form and double-click the Makes combo box to generate its Selected Index event
  21. Return to the form and double-click the New Make button
  22. Return to the form and double-click the New Model button
  23. Return to the form and double-click the New Category button
  24. Return to the form and double-click the Save Auto Part button
  25. Return to the form and double-click the Close button
  26. Change the document as follows:
    using System.Xml.Serialization;
    
    namespace CollegeParkAutoParts
    {
        public partial class StoreItemNew : Form
        {
            /* This property is used to hold the list of auto-parts of our application.
             * (We didn't have to use a global variable. We could have used local variables.) */
            List<AutoPart> AutoParts { get; set; } = new List<AutoPart>();
    
            public StoreItemNew()
            {
                InitializeComponent();
            }
    
            /* This function is used to reset the form.
             * It can be called when necessary. */
            private void InitializeAutoParts()
            {
                // This file is the repository of our database
                string strFileName = @"C:\College Park Auto-Parts\AutoParts.xml";
                // We will use XML serialization to manage the records of our database
                XmlSerializer xsAutoParts = new XmlSerializer(typeof(List<AutoPart>));
    
                /* Show the years in the top combo box.
                 * We will consider only the cars made in the last 20 years. */
                for (int year = DateTime.Today.Year + 1; year >= DateTime.Today.Year - 20; year--)
                    cbxYears.Items.Add(year);
    
                // Check whether the file that holds the store inventory was created already
                if (File.Exists(strFileName))
                {
                    Random rndNumber = new();
    
                    cbxMakes.Items.Clear();
                    cbxModels.Items.Clear();
                    cbxCategories.Items.Clear();
                    txtPartName.Text = string.Empty;
                    txtUnitPrice.Text = string.Empty;
                    txtPartNumber.Text = rndNumber.Next(100000, 999999).ToString();
    
                    // If the inventory file exists, open it
                    using (FileStream fsAutoParts = new FileStream(strFileName,
                                                                    FileMode.Open,
                                                                    FileAccess.Read,
                                                                    FileShare.Read))
                    {
                        // Retrieve the list of items from file
                        AutoParts = (List<AutoPart>)xsAutoParts.Deserialize(fsAutoParts)!;
    
                        // Display the cars manufacturers in the combo box
                        for (int i = 0; i < AutoParts.Count; i++)
                        {
                            // Make sure the list box doesn't yet have the category being added
                            if (!cbxMakes.Items.Contains(AutoParts[i].Make))
                                cbxMakes.Items.Add(AutoParts[i].Make);
                        }
    
                        // Display the categories in the box
                        for (int i = 0; i < AutoParts.Count; i++)
                        {
                            // Make sure the list box doesn't yet have the category being added
                            if (!cbxCategories.Items.Contains(AutoParts[i].Category))
                                cbxCategories.Items.Add(AutoParts[i].Category);
                        }
                    }
                }
    
                lblPictureFile.Text = @"C:\College Park Auto-Parts\Generic.png";
                pbxPartImage.Image  = Image.FromFile(@"C:\College Park Auto-Parts\Generic.png");
    
                Width  = pbxPartImage.Right  + 40;
                Height = pbxPartImage.Bottom + 75;
            }
    
            private void StoreItemNew_Load(object sender, EventArgs e)
            {
                InitializeAutoParts();
            }
    
            private void btnSelectPicture_Click(object sender, EventArgs e)
            {
                if(ofdPictureFile.ShowDialog() == DialogResult.OK)
                {
                    lblPictureFile.Text = ofdPictureFile.FileName;
                    pbxPartImage.Image  = Image.FromFile(ofdPictureFile.FileName);
                }
                else
                    pbxPartImage.Image  = Image.FromFile(@"C:\College Park Auto-Parts\Generic.png");
    
                Width  = pbxPartImage.Right  + 40;
                Height = pbxPartImage.Bottom + 75;
            }
    
            private void cbxMakes_SelectedIndexChanged(object sender, EventArgs e)
            {
                cbxModels.Text = "";
                cbxModels.Items.Clear();
    
                foreach (AutoPart part in AutoParts)
                    if (part.Make == cbxMakes.Text)
                        if (!cbxModels.Items.Contains(part.Model))
                            cbxModels.Items.Add(part.Model);
            }
    
            private void btnNewMake_Click(object sender, EventArgs e)
            {
                Make editor = new Make();
    
                if (editor.ShowDialog() == DialogResult.OK)
                {
                    if (editor.txtMake.Text.Length > 0)
                    {
                        string strMake = editor.txtMake.Text;
    
                        // Make sure the category is not yet in the list
                        if (cbxMakes.Items.Contains(strMake))
                            MessageBox.Show(strMake + " is already in the list.",
                                            "College Park Auto-Parts",
                                            MessageBoxButtons.OK, MessageBoxIcon.Information);
                        else
                        {
                            // Since this is a new category, add it to the combo box
                            cbxMakes.Items.Add(strMake);
                        }
    
                        cbxMakes.Text = strMake;
                    }
                }
            }
    
            private void btnNewModel_Click(object sender, EventArgs e)
            {
                Model editor = new();
    
                if (editor.ShowDialog() == DialogResult.OK)
                {
                    if (editor.txtModel.Text.Length > 0)
                    {
                        string strModel = editor.txtModel.Text;
    
                        // Make sure the category is not yet in the list
                        if (cbxModels.Items.Contains(strModel))
                            MessageBox.Show(strModel + " is already in the list.",
                                            "College Park Auto-Parts",
                                            MessageBoxButtons.OK, MessageBoxIcon.Information);
                        else
                        {
                            // Since this is a new category, add it to the combo box
                            cbxModels.Items.Add(strModel);
                        }
    
                        cbxModels.Text = strModel;
                    }
                }
            }
    
            private void btnNewCategory_Click(object sender, EventArgs e)
            {
                var editor = new Category();
    
                if (editor.ShowDialog() == DialogResult.OK)
                {
                    if (editor.txtCategory.Text.Length > 0)
                    {
                        string strCategory = editor.txtCategory.Text;
    
                        // Make sure the category is not yet in the list
                        if (cbxCategories.Items.Contains(strCategory))
                            MessageBox.Show(strCategory + " is already in the list.",
                                            "College Park Auto-Parts",
                                         MessageBoxButtons.OK, MessageBoxIcon.Information);
                        else
                        {
                            // Since this is a new category, add it to the combo box
                            cbxCategories.Items.Add(strCategory);
                        }
    
                        cbxCategories.Text = strCategory;
                    }
                }
            }
    
            private void btnSaveAutoPart_Click(object sender, EventArgs e)
            {
                // Make sure the user had selected a year
                if( string.IsNullOrEmpty(cbxYears.Text) )
                {
                    MessageBox.Show("You must specify the year.",
                                    "College Park Auto-Parts",
                                    MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
    
                // Make sure the user had selected a make
                if(string.IsNullOrEmpty(cbxMakes.Text) )
                {
                    MessageBox.Show("You must specify the car name.",
                                    "College Park Auto-Parts",
                                    MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
    
                // Make sure the user had selected a model
                if (string.IsNullOrEmpty(cbxModels.Text) )
                {
                    MessageBox.Show("You must specify the model of the car.",
                                    "College Park Auto-Parts",
                                    MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
    
                // Make sure the user had entered a name/description
                if (string.IsNullOrEmpty(txtPartName.Text) )
                {
                    MessageBox.Show("You must enter the name (or a " +
                                    "short description) for the part.",
                                    "College Park Auto-Parts",
                                    MessageBoxButtons.OK, MessageBoxIcon.Information);
                    txtPartName.Focus();
                    return;
                }
    
                // Make sure the user had typed a price for the item
                if( string.IsNullOrEmpty(txtUnitPrice.Text) )
                {
                    MessageBox.Show("You must enter the price of the item.",
                                    "College Park Auto-Parts",
                                    MessageBoxButtons.OK, MessageBoxIcon.Information);
                    txtUnitPrice.Focus();
                    return;
                }
                
                string strFileName = @"C:\College Park Auto-Parts\AutoParts.xml";
                XmlSerializer xsAutoParts = new XmlSerializer(typeof(List<AutoPart>));
    
                if (File.Exists(strFileName))
                {
                    // If the inventory file exists, open it
                    using (FileStream fsAutoParts = new(strFileName, FileMode.Open,
                                                        FileAccess.Read, FileShare.Read))
                    {
                        // Retrieve the list of items from file
                        AutoParts = (List<AutoPart>)xsAutoParts.Deserialize(fsAutoParts)!;
                    }
                }
    
                AutoPart part = new AutoPart();
    
                part.PartNumber = long.Parse(txtPartNumber.Text);
                part.Year = int.Parse(cbxYears.Text);
                part.Make = cbxMakes.Text;
                part.Model = cbxModels.Text;
                part.Category = cbxCategories.Text;
                part.PartName = txtPartName.Text;
                part.UnitPrice = double.Parse(txtUnitPrice.Text);
                part.PictureFile = lblPictureFile.Text;
    
                // Call the Add method of our collection class to add the part
                AutoParts.Add(part);
    
                TextWriter twAutoParts = new StreamWriter(strFileName);
                xsAutoParts.Serialize(twAutoParts, AutoParts);
                twAutoParts.Close();
    
                InitializeAutoParts();
            }
    
            private void btnClose_Click(object sender, EventArgs e)
            {
                Close();
            }
        }
    }
  27. To create a new form, on the main menu, click Project -> Add Form (Windows Forms)...
  28. Set the name to StoreItemEditor
  29. Click Add
  30. Click an unoccupied area of the form and, in the Properties window, change the following characteristics:
    Text: College Park Auto-Parts - Store Item Editor
    MaximizeBox: False
    ShowInTaskbar: False
    StartPosition: CenterScreen
  31. Resize the form to have the same size as the Store Item New form
  32. Select and copy all controls from the Store Item New form
  33. Paste the copied controls on the Store Item Editor form
  34. Modify the design of the Store Item Editor form as follows:
     

    Musical Store Item Type

    Control (Name) Text
    Button Button btnFind &Find
    Button Button btnUpdateAutoPart Up&date Auto-Part
  35. Double-click an unoccupied area of the form
  36. Return to the Store Item Editor form and double-click the Find button
  37. Return to the Store Item Editor form and double-click the Select Picture button
  38. Return to the Store Item Editor form and double-click the Update Auto-Part button
  39. Return to the Store Item Editor form and double-click the Close button
  40. Change the document as follows:
    using System.Xml.Serialization;
    
    namespace CollegeParkAutoParts
    {
        public partial class StoreItemEditor : Form
        {
            List<AutoPart> AutoParts { get; set; } = new List<AutoPart>();
    
            public StoreItemEditor()
            {
                InitializeComponent();
            }
    
            private void InitializeAutoPart()
            {
                txtMake.Text        = string.Empty;
                txtModel.Text       = string.Empty;
                txtCategory.Text    = string.Empty;
                txtPartName.Text    = string.Empty;
                txtUnitPrice.Text   = string.Empty;
                txtPartNumber.Text  = string.Empty ;
    
                lblPictureFile.Text = @"C:\College Park Auto-Parts\Generic.png";
                pbxPartImage.Image  = Image.FromFile(@"C:\College Park Auto-Parts\Generic.png");
    
                Width               = pbxPartImage.Right  + 40;
                Height              = pbxPartImage.Bottom + 75;
            }
    
            private void StoreItemEditor_Load(object sender, EventArgs e)
            {
                InitializeAutoPart();
            }
    
            private void btnFind_Click(object sender, EventArgs e)
            {
                if( string.IsNullOrEmpty(txtPartNumber.Text))
                {
                    MessageBox.Show("You must enter a (valid) number for an auto-part.",
                                    "College Park Auto-Parts", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
    
                bool foundAutoPart        = false;
                string strFileName        = @"C:\College Park Auto-Parts\AutoParts.xml";
                XmlSerializer xsAutoParts = new XmlSerializer(typeof(List<AutoPart>));
    
                if (File.Exists(strFileName))
                {
                    using (FileStream fsAutoParts = new(strFileName, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        AutoParts = (List<AutoPart>)xsAutoParts.Deserialize(fsAutoParts)!;
    
                        for (int i = 0; i < AutoParts.Count; i++)
                        {
                            if (AutoParts[i].PartNumber.Equals(long.Parse(txtPartNumber.Text)))
                            {
                                foundAutoPart = true;
    
                                txtMake.Text        = AutoParts[i].Make;
                                txtModel.Text       = AutoParts[i].Model;
                                txtCategory.Text    = AutoParts[i].Category;
                                txtPartName.Text    = AutoParts[i].PartName;
                                cbxYears.Text       = AutoParts[i].Year.ToString();
                                txtUnitPrice.Text   = AutoParts[i].UnitPrice.ToString("F");
                                pbxPartImage.Image  = Image.FromFile(AutoParts[i].PictureFile!);
                                lblPictureFile.Text = AutoParts[i].PictureFile;
                                
                                break;
                            }
                        }
                    }
                }
    
                if(foundAutoPart == false)
                {
                    MessageBox.Show("There is no auto-part with that number in our records.",
                                    "College Park Auto-Parts", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    
                    lblPictureFile.Text = @"C:\College Park Auto-Parts\Generic.png";
                    pbxPartImage.Image  = Image.FromFile(@"C:\College Park Auto-Parts\Generic.png");
                }
    
                Width  = pbxPartImage.Right  + 40;
                Height = pbxPartImage.Bottom + 75;
            }
    
            private void btnSelectPicture_Click(object sender, EventArgs e)
            {
                if (ofdPictureFile.ShowDialog() == DialogResult.OK)
                {
                    lblPictureFile.Text = ofdPictureFile.FileName;
                    pbxPartImage.Image  = Image.FromFile(ofdPictureFile.FileName);
                }
                else
                    pbxPartImage.Image = Image.FromFile(@"C:\College Park Auto-Parts\Generic.png");
    
                Width  = pbxPartImage.Right  + 40;
                Height = pbxPartImage.Bottom + 75;
            }
    
            private void btnUpdateAutoPart_Click(object sender, EventArgs e)
            {
                string strFileName        = @"C:\College Park Auto-Parts\AutoParts.xml";
                XmlSerializer xsAutoParts = new XmlSerializer(typeof(List<AutoPart>));
    
                if (File.Exists(strFileName))
                {
                    using (FileStream fsAutoParts = new FileStream(strFileName,
                                                                    FileMode.Open,
                                                                    FileAccess.Read,
                                                                    FileShare.Read))
                    {
                        AutoParts = (List<AutoPart>)xsAutoParts.Deserialize(fsAutoParts)!;
                    }
                }
    
                for (int i = 0; i < AutoParts.Count; i++)
                {
                    if (AutoParts[i].PartNumber.Equals(long.Parse(txtPartNumber.Text)))
                    {
                        AutoParts[i].Year        = Convert.ToInt32(cbxYears.Text);
                        AutoParts[i].Make        =                 txtMake.Text;
                        AutoParts[i].Model       =                 txtModel.Text;
                        AutoParts[i].Category    =                 txtCategory.Text;
                        AutoParts[i].PartName    =                 txtPartName.Text;
                        AutoParts[i].UnitPrice   = Convert.ToDouble(txtUnitPrice.Text);
                        AutoParts[i].PictureFile =                 lblPictureFile.Text;
    
                        TextWriter twAutoParts = new StreamWriter(strFileName);
                        xsAutoParts.Serialize(twAutoParts, AutoParts);
                        twAutoParts.Close();
    
                        break;
                    }
                }
    
                InitializeAutoPart();
            }
    
            private void btnClose_Click(object sender, EventArgs e)
            {
                Close();
            }
        }
    }
  41. To add a new form, on the main menu, click Project -> Add Form (Windows Forms)...
  42. Type the Name as StoreItemDelete
  43. Click Add
  44. Click an unoccupied area of the form and, in the Properties window, change the following characteristics:
    Text: College Park Auto-Parts - Store Item Deletion
    MaximizeBox: False
    ShowInTaskbar: False
    StartPosition: CenterScreen
  45. Resize the Store Item Delete form to have approximately the same size as the Store Item Editor form
  46. Select and copy all controls on the Store Item Editor form
  47. Paste the copied controls to the Store Item Delete form
  48. Design the form as follows:
     

    College Park Auto-Parts - Store Inventory

    Control (Name) Text
    Text Box Text Box txtYear  
    Label Button btnDeleteAutoPart Delete Auto-Part
  49. Double-click an unoccupied area of the form to generate its Load event
  50. Return to the Store Item Delete form and double-click the Find button
  51. Return to the Store Item Delete form and double-click the Delete Auto-Part button
  52. Return to the Store Item Delete form and double-click the Close button
  53. Change the document as follows:
    using System.Xml.Serialization;
    
    namespace CollegeParkAutoParts
    {
        public partial class StoreItemDelete : Form
        {
            List<AutoPart> AutoParts { get; set; } = new List<AutoPart>();
    
            public StoreItemDelete()
            {
                InitializeComponent();
            }
    
            private void InitializeAutoPart()
            {
                txtMake.Text        = string.Empty;
                txtModel.Text       = string.Empty;
                txtCategory.Text    = string.Empty;
                txtPartName.Text    = string.Empty;
                txtUnitPrice.Text   = string.Empty;
                txtPartNumber.Text  = string.Empty;
    
                lblPictureFile.Text = @"C:\College Park Auto-Parts\Generic.png";
                pbxPartImage.Image  = Image.FromFile(@"C:\College Park Auto-Parts\Generic.png");
    
                Width               = pbxPartImage.Right + 40;
                Height              = pbxPartImage.Bottom + 75;
            }
    
            private void StoreItemDelete_Load(object sender, EventArgs e)
            {
                InitializeAutoPart();
            }
    
            private void btnFind_Click(object sender, EventArgs e)
            {
                if (string.IsNullOrEmpty(txtPartNumber.Text))
                {
                    MessageBox.Show("You must enter a (valid) number for an auto-part.",
                                    "College Park Auto-Parts", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
    
                bool foundAutoPart = false;
                XmlSerializer xsAutoParts = new(typeof(List<AutoPart>));
                string strFileName = @"C:\College Park Auto-Parts\AutoParts.xml";
    
                if (File.Exists(strFileName))
                {
                    using (FileStream fsAutoParts = new(strFileName, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        AutoParts = (List<AutoPart>)xsAutoParts.Deserialize(fsAutoParts)!;
    
                        for (int i = 0; i < AutoParts.Count; i++)
                        {
                            if (AutoParts[i].PartNumber.Equals(long.Parse(txtPartNumber.Text)))
                            {
                                foundAutoPart       = true;
    
                                txtMake.Text        =                AutoParts[i].Make;
                                txtModel.Text       =                AutoParts[i].Model;
                                txtCategory.Text    =                AutoParts[i].Category;
                                txtPartName.Text    =                AutoParts[i].PartName;
                                txtYear.Text        =                AutoParts[i].Year.ToString();
                                txtUnitPrice.Text   =                AutoParts[i].UnitPrice.ToString("F");
                                pbxPartImage.Image  = Image.FromFile(AutoParts[i].PictureFile!);
                                lblPictureFile.Text =                AutoParts[i].PictureFile;
    
                                break;
                            }
                        }
                    }
                }
    
                if (foundAutoPart == false)
                {
                    MessageBox.Show("There is no auto-part with that number in our records.",
                                    "College Park Auto-Parts", MessageBoxButtons.OK, MessageBoxIcon.Information);
    
                    lblPictureFile.Text = @"C:\College Park Auto-Parts\Generic.png";
                    pbxPartImage.Image  = Image.FromFile(@"C:\College Park Auto-Parts\Generic.png");
                }
    
                Width  = pbxPartImage.Right  + 40;
                Height = pbxPartImage.Bottom + 75;
            }
    
            private void btnDeleteAutoPart_Click(object sender, EventArgs e)
            {
                XmlSerializer xsAutoParts = new(typeof(List<AutoPart>));
                string strFileName        = @"C:\College Park Auto-Parts\AutoParts.xml";
    
                if (File.Exists(strFileName))
                {
                    using FileStream fsAutoParts = new(strFileName, FileMode.Open,
                                                       FileAccess.Read, FileShare.Read);
                    AutoParts = (List<AutoPart>)xsAutoParts.Deserialize(fsAutoParts)!;
                }
    
                for (int i = 0; i < AutoParts.Count; i++)
                {
                    if (AutoParts[i].PartNumber.Equals(long.Parse(txtPartNumber.Text)))
                    {
                        AutoParts.Remove(AutoParts[i]);
    
                        TextWriter twAutoParts = new StreamWriter(strFileName);
                        xsAutoParts.Serialize(twAutoParts, AutoParts);
                        twAutoParts.Close();
    
                        break;
                    }
                }
    
                InitializeAutoPart();
            }
    
            private void btnClose_Click(object sender, EventArgs e)
            {
                Close();
            }
        }
    }
  54. Return to the Store Inventory form and double-click the New Auto Part button
  55. Return to the Store Inventory form and click the Available Parts list view
  56. In the Properties window, click the Events button Events
  57. In the Events section of the Properties window for the Available Parts list view, double-click ItemSelectionChanged
  58. Return to the Store Inventory form and make sure the Available Parts list view is still selected
  59. In the Events section of the Properties window, double-click DoubleClick
  60. Return to the Store Inventory form and click the Unit Price text box
  61. In the Events section of the Properties window, double-click Leave
  62. Return to the Store Inventory form and click the Qty text box
  63. In the Properties window, click Leave, then click the arrow of that field and select txtUnitPrice_Leave
  64. Return to the Store Inventory form and click the Part # text box
  65. In the Events section of the Properties window, double-click Leave
  66. Return to the Store Inventory form and double-click the Add/Select button
  67. Return to the Store Inventory form and click the Selected Parts list view
  68. In the Events section of the Properties window, double-click DoubleClick
  69. Return to the Store Inventory form and click the Part Identification tree view
  70. In the Events section of the Properties window, double-click NodeMouseClick
  71. Return to the Store Inventory form and double-click the Update Auto Part button
  72. Return to the Store Inventory form and double-click the Delete Auto Part button
  73. Return to the Store Inventory form and double-click the Close button
  74. Change the document as follows:
    using System.Xml.Serialization;
    
    namespace CollegeParkAutoParts
    {
        public partial class StoreInvetory : Form
        {
            /* We will need a list of auto-parts.
             * For demonstration purpose, we are creating the list as a property
             * (but a global list is not necessary; we could have used local list variables).*/
            public List<AutoPart> AutoParts { get; set; } = new List<AutoPart>();
    
            public StoreInvetory()
            {
                InitializeComponent();
            }
    
            // This function is used to reset the form
            void InitializeAutoParts()
            {
                // When the form must be reset, removes all nodes from the tree view
                tvwAutoParts.Nodes.Clear();
                // Create the root node of the tree view
                TreeNode nodRoot = tvwAutoParts.Nodes.Add("College Park Auto-Parts",
                                                          "College Park Auto-Parts", 0, 1);
                /* Add the cars years to the tree view.
                 * Our application will deal only with the cars in the last 21 years. */
                for (int years = DateTime.Today.Year + 1; years >= DateTime.Today.Year - 20; years--)
                    nodRoot.Nodes.Add(years.ToString(), years.ToString(), 2, 3);
    
                // Select the root node
                tvwAutoParts.SelectedNode = nodRoot;
                // Expand the root node
                tvwAutoParts.ExpandAll();
    
                // AutoParts = new List<AutoPart>();
    
                // This is the file that holds the list of auto parts
                string strFileName = @"C:\College Park Auto-Parts\AutoParts.xml";
                XmlSerializer xsAutoParts = new(typeof(List<AutoPart>));
    
                if (File.Exists(strFileName))
                {
                    // If the inventory file exists, open it
                    using (FileStream fsAutoParts = new FileStream(strFileName,
                                                                    FileMode.Open,
                                                                    FileAccess.Read,
                                                                    FileShare.Read))
                    {
                        // Retrieve the list of items from file
                        AutoParts = (List<AutoPart>)xsAutoParts.Deserialize(fsAutoParts)!;
    
                        // Show the makes nodes
                        foreach (TreeNode nodYear in nodRoot.Nodes)
                        {
                            List<string> lstMakes = new List<string>();
    
                            foreach (AutoPart part in AutoParts)
                            {
                                if (nodYear.Text == part.Year.ToString())
                                {
                                    if (!lstMakes.Contains(part.Make!))
                                        lstMakes.Add(part.Make!);
                                }
                            }
    
                            foreach (string strMake in lstMakes)
                                nodYear.Nodes.Add(strMake, strMake, 4, 5);
                        }
    
                        // Showing the models nodes
                        foreach (TreeNode nodYear in nodRoot.Nodes)
                        {
                            foreach (TreeNode nodMake in nodYear.Nodes)
                            {
                                List<string> lstModels = new List<string>();
    
                                foreach (AutoPart part in AutoParts)
                                {
                                    if( (nodYear.Text == part.Year.ToString() ) &
                                        (nodMake.Text == part.Make))
                                    {
                                        if (!lstModels.Contains(part.Model!))
                                            lstModels.Add(part.Model!);
                                    }
                                }
    
                                foreach (string strModel in lstModels)
                                    nodMake.Nodes.Add(strModel, strModel, 6, 7);
                            }
                        }
    
                        // Showing the categories nodes
                        foreach (TreeNode nodYear in nodRoot.Nodes)
                        {
                            foreach (TreeNode nodMake in nodYear.Nodes)
                            {
                                foreach (TreeNode nodModel in nodMake.Nodes)
                                {
                                    List<string> lstCategories = new List<string>();
    
                                    foreach (AutoPart part in AutoParts)
                                    {
    
                                        if ((nodYear.Text  == part.Year.ToString()) &
                                            (nodMake.Text  == part.Make) &
                                            (nodModel.Text == part.Model))
                                        {
                                            if (!lstCategories.Contains(part.Category!))
                                                lstCategories.Add(part.Category!);
                                        }
                                    }
    
                                    foreach (string strCategory in lstCategories)
                                        nodModel.Nodes.Add(strCategory, strCategory, 8, 9);
                                }
                            }
                        }
                    }
                }
    
                lvwSelectedParts.Items.Clear();
                lvwAvailableParts.Items.Clear();
                txtTaxRate.Text            = string.Empty;
                txtPartName.Text           = string.Empty;
                txtQuantity.Text           = string.Empty;
                txtSubTotal.Text           = string.Empty;
                txtUnitPrice.Text          = string.Empty;
                txtTaxAmount.Text          = string.Empty;
                txtOrderTotal.Text         = string.Empty;
                txtPartNumber.Text         = string.Empty;
                txtSelectedPartsTotal.Text = string.Empty;
                pbxPartImage.Image         = Image.FromFile(@"C:\College Park Auto-Parts\Generic.png");
            }
    
            private void StoreInvetory_Load(object sender, EventArgs e)
            {
                InitializeAutoParts();
            }
    
            private void btnNewAutoPart_Click(object sender, EventArgs e)
            {
                StoreItemNew sin = new StoreItemNew();
    
                sin.ShowDialog();
    
                InitializeAutoParts();
            }
    
            private void lvwAvailableParts_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
            {
                bool pictureFound = false;
                string strFileName = @"C:\College Park Auto-Parts\AutoParts.xml";
                XmlSerializer xsAutoParts = new XmlSerializer(typeof(List<AutoPart>));
    
                if (File.Exists(strFileName))
                {
                    // If the inventory file exists, open it
                    using (FileStream fsAutoParts = new FileStream(strFileName,
                                                                   FileMode.Open,
                                                                   FileAccess.Read,
                                                                   FileShare.Read))
                    {
                        // Retrieve the list of items from file
                        AutoParts = (List<AutoPart>)xsAutoParts.Deserialize(fsAutoParts)!;
    
                        foreach (AutoPart part in AutoParts)
                        {
                            if( part.PartNumber == long.Parse(e.Item.SubItems[0].Text))
                            {
                                pictureFound       = true;
                                pbxPartImage.Image = Image.FromFile(part.PictureFile!);
                                break;
                            }
                        }
                    }
                }
    
                if(pictureFound == false)
                {
                    pbxPartImage.Image = Image.FromFile(@"C:\College Park Auto-Parts\Generic.png");
                }
                
                Width  = pbxPartImage.Right  + 40;
                Height = pbxPartImage.Bottom + 75;
            }
    
            private void lvwAvailableParts_DoubleClick(object sender, EventArgs e)
            {
                ListViewItem lviAutoPart = lvwAvailableParts.SelectedItems[0];
    
                if ((lvwAvailableParts.SelectedItems.Count == 0) ||
                    (lvwAvailableParts.SelectedItems.Count > 1))
                    return;
    
                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();
            }
    
            private void txtUnitPrice_Leave(object sender, EventArgs e)
            {
                double subTotal;
                double unitPrice = 0D;
                double quantity  = 0.00d;
    
                try
                {
                    unitPrice = double.Parse(txtUnitPrice.Text);
                }
                catch (FormatException)
                {
                    MessageBox.Show("Invalid Unit Price!",
                                    "College Park Auto-Parts",
                                    MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
    
                try
                {
                    quantity = int.Parse(txtQuantity.Text);
                }
                catch (FormatException)
                {
                    MessageBox.Show("Invalid Quandtity!",
                                    "College Park Auto-Parts",
                                    MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
    
                subTotal         = unitPrice * quantity;
                txtSubTotal.Text = subTotal.ToString("F");
            }
    
            internal void CalculateOrder()
            {
                // Calculate the current total order and update the order
                double partsTotal = 0.00D;
                double taxRate    = 0.00D;
                double taxAmount, orderTotal;
    
                if (string.IsNullOrEmpty(txtTaxRate.Text))
                    txtTaxRate.Text = "7.25";
    
                foreach (ListViewItem lvi in lvwSelectedParts.Items)
                {
                    ListViewItem.ListViewSubItem SubItem = lvi.SubItems[4];
                    partsTotal += double.Parse(SubItem.Text);
                }
    
                try
                {
                    taxRate = double.Parse(txtTaxRate.Text) / 100;
                }
                catch (FormatException)
                {
                    MessageBox.Show("Invalid Tax Rate",
                                    "College Park Auto-Parts",
                                    MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
    
                taxAmount                  = partsTotal * taxRate;
                orderTotal                 = partsTotal + taxAmount;
    
                txtSelectedPartsTotal.Text = partsTotal.ToString("F");
                txtTaxAmount.Text          = taxAmount.ToString("F");
                txtOrderTotal.Text         = orderTotal.ToString("F");
            }
    
            private void txtPartNumber_Leave(object sender, EventArgs e)
            {
                bool found = false;
    
                // After the user had entered a part number,
                // check the whole list of parts
                foreach (AutoPart part in AutoParts)
                {
                    // If you find a part that holds the number the user had entered
                    if (part.PartNumber == long.Parse(txtPartNumber.Text))
                    {
                        // Show the corresponding part name and unit price
                        txtPartName.Text = part.PartName;
                        txtUnitPrice.Text = part.UnitPrice.ToString("F");
                        
                        if(string.IsNullOrEmpty(txtQuantity.Text))
                            txtQuantity.Text = "1";
                        
                        txtSubTotal.Text = part.UnitPrice.ToString("F");
                    
                        // Give focus to the quantity in case the user was to increase it
                        txtQuantity.Focus();
    
                        // And update the flag that specifies that the part has been found
                        found = true;
                        break;
                    }
                    // If the part number was not found, check the next
                } // If no part has that number, the found flag is marked as false
    
                // If no part with that number was found...
                if (found == false)
                {
                    // 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
                    MessageBox.Show("There is no part with that number.",
                                "College Park Auto-Parts",
                                MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
    
            private void btnAdd_Click(object sender, EventArgs e)
            {
                if(string.IsNullOrEmpty(txtPartNumber.Text) )
                {
                    MessageBox.Show("There is no part to be added to the order.",
                                    "College Park Auto-Parts",
                                    MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
    
                foreach (AutoPart part in AutoParts)
                {
                    if (part.PartNumber == long.Parse(txtPartNumber.Text))
                    {
                        ListViewItem lviSelectedPart = new ListViewItem(part.PartNumber.ToString());
    
                        lviSelectedPart.SubItems.Add(part.PartName);
                        lviSelectedPart.SubItems.Add(part.UnitPrice.ToString());
                        lviSelectedPart.SubItems.Add(txtQuantity.Text);
                        lviSelectedPart.SubItems.Add(txtSubTotal.Text);
                        lvwSelectedParts.Items.Add(lviSelectedPart);
                    }
                }
    
                CalculateOrder();
            }
    
            private void lvwSelectedParts_DoubleClick(object sender, EventArgs e)
            {
                ListViewItem lviSelectedPart = lvwSelectedParts.SelectedItems[0];
    
                if ((lvwSelectedParts.SelectedItems.Count == 0) ||
                    (lvwSelectedParts.SelectedItems.Count > 1))
                    return;
    
                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();
            }
    
            private void tvwAutoParts_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
            {
                TreeNode nodClicked = e.Node;
    
                if (nodClicked.Level == 4)
                    lvwAvailableParts.Items.Clear();
    
                try
                {
                    foreach (AutoPart part in AutoParts)
                    {
                        if ((part.Category        == nodClicked.Text) &&
                            (part.Model           == nodClicked.Parent.Text) &&
                            (part.Make            == nodClicked.Parent.Parent.Text) &&
                            (part.Year.ToString() == nodClicked.Parent.Parent.Parent.Text))
                        {
                            ListViewItem lviAutoPart = new ListViewItem(part.PartNumber.ToString());
    
                            lviAutoPart.SubItems.Add(part.PartName);
                            lviAutoPart.SubItems.Add(part.UnitPrice.ToString("F"));
                            lvwAvailableParts.Items.Add(lviAutoPart);
                        }
                    }
                }
                catch (NullReferenceException)
                {
                }
            }
    
            private void btnUpdateAutoPart_Click(object sender, EventArgs e)
            {
                StoreItemEditor sie = new StoreItemEditor();
    
                sie.ShowDialog();
    
                InitializeAutoParts();
            }
    
            private void btnDeleteAutoPart_Click(object sender, EventArgs e)
            {
                StoreItemDelete sid = new StoreItemDelete();
    
                sid.ShowDialog();
    
                InitializeAutoParts();
            }
    
            private void btnClose_Click(object sender, EventArgs e)
            {
                Close();
            }
        }
    }
  75. To execute the application, on the main menu, click Debug and click Start Without Debugging

    College Park Auto-Parts - Store Inventory

  76. Click the New Auto Part button and create some auto-parts records with the following values:
     
    Part # Year Make Model Category Item Name Unit Price Picture File
    393795 2015 Buick Regal Alternators & Generators DB Electrical Alternator 218.74 928037
    928374 2018 Chevrolet Express 3500 Shocks, Struts & Suspension Suspension Kit (Front; with 3 Groove Pitman Arm) 142.44 304031
    730283 2020 Jeep Wrangler Unlimited Sahara Oil Filters Hydraulic Cylinder Timing Belt Tensioner 14.15 730283
    290741 2015 Ford F-150 XL 3.5L V6 Flex Regular Cab 2 Full-Size Doors Shocks, Struts & Suspension Front Strut and Coil Spring Assembly - Set of 2 245.68 290741
    740248 2013 Chevrolet Equinox Bearings & Seals Wheel hub bearing Assembly 99.95 740248
    283759 2012 Dodge Charger 3.6L Starters DB Electrical SND0787 Starter 212.58 283759
    799428 2012 Cadillac XTS Bearings & Seals Front/Rear Wheel Hub Bearing Assembly 5 Lugs w/ABS 79.97 799428
    648203 2018 Honda CRV Alternator Alternator 202.47 593804
    502853 2014 GMC Terrain Bearings & Seals Wheel Hub Bearing Assembly 48.85 927944
    520384 2020 Jeep Wrangler Unlimited Sahara Drum Brake Rear Dynamic Friction Company True-Arc Brake Shoes 42.22 520384
    727394 2018 Toyota Corolla SE 1.8L L4 Gas Alternators DB Electrical 400-40169 Alternator Compatible With/Replacement For 125 Internal Fan Type Decoupler Pulley Type Internal Regulator CW Rotation 215.84 727394
    927944 2017 Chevrolet Equinox Bearings & Seals Wheel Hub Bearing Assembly 48.85 927944
    749471 2019 Toyota Prius Shocks, Struts & Suspension 2-Piece Suspension Strut and Coil Spring Kit (593024) 299.97 593024
    927307 2014 Buick Regal Alternators & Generators DB Electrical Alternator 218.74 928037
    304031 2017 Chevrolet Express 2500 Shocks, Struts & Suspension Suspension Kit (Front; with 3 Groove Pitman Arm) 142.44 304031
    497249 2013 GMC Sierra 1500 Drum Brake ACDelco Gold 17960BF1 Bonded Rear Drum Brake Shoe Set 58.92 497249
    973947 2012 Honda Accord Brake Kits R1 Concepts Front Rear Brakes and Rotors Kit |Front Rear Brake Pads| Brake Rotors and Pads| Ceramic Brake Pads and Rotors 292.84 973947
    182694 2016 Chevrolet Impala Bearings & Seals Wheel Hub Bearing Assembly 48.85 927944
    497249 2013 Chevrolet Silverado 1500 Drum Brake ACDelco Gold 17960BF1 Bonded Rear Drum Brake Shoe Set 58.92 497249
    297149 2020 Jeep Wrangler Air Filters ACDelco Gold A3408C Air Filter 22.83 297149
    927397 2016 Chevrolet Impala Bearings & Seals Front/Rear Wheel Hub Bearing Assembly 5 Lugs w/ABS 79.97 799428
    392972 2020 Toyota Prius AWD-e Shocks, Struts & Suspension 2-Piece Suspension Strut and Coil Spring Kit (593024) 299.97 593024
    928037 2017 Buick Regal Alternators & Generators DB Electrical Alternator 218.74 928037
    502481 2016 Chevrolet Equinox Bearings & Seals Wheel hub bearing Assembly 99.95 740248
    593804 2019 Honda Accord LX 1.5L L4 Gas Alternator Alternator 202.47 593804
    293748 2014 Toyota Corolla SE 1.8L L4 Gas Alternators DB Electrical 400-40169 Alternator Compatible With/Replacement For 125 Internal Fan Type Decoupler Pulley Type Internal Regulator CW Rotation 215.84 727394
    639704 2021 Kia Sorento Brake Kits Rear Brakes and Rotors Kit |Rear Brake Pads| Brake Rotors and Pads| Optimum OEp Brake Pads and Rotors 125.15 639704
    829385 2020 Jeep Wrangler Unlimited Sahara Drum Brake Centric Brake Shoe 22.05 829385
    484695 2014 GMC Terrain Bearings & Seals Front/Rear Wheel Hub Bearing Assembly 5 Lugs w/ABS 79.97 799428
    807204 2016 Chevrolet Camaro Alternators & Generators DB Electrical Alternator 218.74 928037
    939283 2015 Chevrolet Equinox Bearings & Seals Wheel Hub Bearing Assembly 48.85 927944
    738628 2021 Toyota Prius AWD-e Shocks, Struts & Suspension 2-Piece Suspension Strut and Coil Spring Kit (593024) 299.97 593024
    186950 2017 Honda CRV Alternator Alternator 202.47 593804
    329573 2012 Chevrolet Equinox Bearings & Seals Front/Rear Wheel Hub Bearing Assembly 5 Lugs w/ABS 79.97 799428
    594085 2015 Buick Regal Bearings & Seals Front/Rear Wheel Hub Bearing Assembly 5 Lugs w/ABS 79.97 799428
    928405 2018 Chevrolet Camaro Alternators & Generators DB Electrical Alternator 218.74 928037
    927937 2012 Ford Focus SE Starters Duralast Starter 19481 188.88 927937
    283948 2018 GMC Savana 3500 Shocks, Struts & Suspension Suspension Kit (Front; with 3 Groove Pitman Arm) 142.44 304031
    495116 2020 Chrysler Voyager Brake Kits Power Stop K7845 Rear Z23 Carbon Fiber Brake Pads with Drilled & Slotted Brake Rotors Kit 269.75 293748
    180400 2012 Cadillac CTS FWD Bearings & Seals Front/Rear Wheel Hub Bearing Assembly 5 Lugs w/ABS 79.97 799428
    593024 2021 Toyota Prius Shocks, Struts & Suspension 2-Piece Suspension Strut and Coil Spring Kit (593024) 299.97 593024
    302839 2014 Chevrolet Equinox Bearings & Seals Wheel Hub Bearing Assembly 48.85 927944
    649394 2020 Jeep Wrangler Unlimited Sahara Brake Kits Power Stop K7940 Front Z23 Evolution Sport Brake Upgrade Kit 354.46 495116
    820684 2015 Buick LaCrosse Bearings & Seals Front/Rear Wheel Hub Bearing Assembly 5 Lugs w/ABS 79.97 799428
    602839 2017 GMC Savana 2500 Shocks, Struts & Suspension Suspension Kit (Front; with 3 Groove Pitman Arm) 142.44 304031
  77. Edit some of the records
  78. Delete some of the records
  79. Close the forms and return to your programming environment
  80. Close your programming environment

Example Application: Stellar Water Point


Previous Copyright © 2010-2023, FunctionX Last Update: Friday 02 December 2022 Next