Application Setup

Introduction

A text-based database is an application used to create, keep, and manage records. You have many options. One way to store the records of a database is as text. Even then, you still have many option. One solution is to create and manage records using a collection class.

Besides using a collection class to create and manage records, you also have to decide in what format you would keep the record. For this example, we will save the records in XML.

Practical LearningPractical Learning: Introducing MDI Applications

  1. Start Microsoft Visual Studio
  2. In the Visual Studio 2022 dialog box, click Create a New Project
  3. In the Create a New Project dialog box, in the Languages combo box, select C#
  4. In the list of projects templates, click Windows Forms App
  5. Click Next
  6. Change the Project Name to StellarWaterPoint5
  7. In the Framework combo box, select the highest version: .NET 9.0 (Standard Term Suppot)
  8. Click Create
  9. In the Solution Explorer, right-click StellarWaterPoint5 -> Add -> New Folder
  10. Type Models as the name of the folder
  11. In the Solution Explorer, right-click Form1.cs and click Rename
  12. Change the name to WaterDistribution.cs
  13. Press Enter twice to accept the name and dismiss the message box
  14. Double-click an unoccupied of the form to generate its Load event
  15. Implement the event as follows:
    namespace StellarWaterPoint5
    {
        public partial class WaterDistribution : Form
        {
            public WaterDistribution()
            {
                InitializeComponent();
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
        }
    }
  16. Return to the form and click its body to select it
  17. In the Properties window, change the following characteristics:
    IsMdiContainer: True
    StartPosition: CenterScreen
    Text: Stellar Water Point

    Stellar Water Point - Multiple Document Interface

  18. To create a form, on the main menu, click Project -> Add Form (Windows Forms)...
  19. In the middle list, click About Box (Windows Forms)
  20. Change the file Name to AboutSWP
  21. In the Toolbox, expand Menus & Toolbars
  22. In the Menus & Toolbars section of the Toolbox, click MenuStrip and click the form
  23. In the Properties window, click (Name) and type msMainMenu
  24. Still in the Properties window, click Items and click its button
  25. Using the Add button, create some menu items as follows:
    Text (Name)
    &File miFile
    Water &Bills miWaterBills
    &Customers miCustomers
    Water &Meters miWaterMeters
    &Window miWindow
    &Help miHelp
  26. In the Members list of the Items Collection Editor, click miFile
  27. In the right list, click DropDownItems and click its button
  28. Using the Add button, create an item as follows:
    Text (Name) Shortcuts
    E&xit miFileExit Alt + F4
  29. On the Items Collection Editor (miFile.DropDownItems) dialog box, click OK
  30. In the Members list of the Items Collection Editor, click miWaterBills
  31. In the right list, click DropDownItems and click its button
  32. Using the Add button, create two items as follows:
    Text (Name) Shortcuts
    &Process Water Bill... miWaterBillsCreate Ctrl+Shift+B
    Water Bill &Details... miWaterBillsDetails Ctrl+Shift+D
    Water Bill &Editor... miWaterBillsEditor Ctrl+Shift+E
    &Delete Water Bill... miWaterBillsDeletion Ctrl+Shift+D
    tsWaterBillsSeparator
    &View Water Bills... miWaterBillsView Ctrl+Shift+V
  33. On the Items Collection Editor (miWaterBills.DropDownItems) dialog box, click OK
  34. In the Members list of the Items Collection Editor, click miCustomers
  35. In the right list, click DropDownItems and click its button
  36. Using the Add button, create two items as follows:
    Text (Name) Shortcuts
    &Create Customer Account... miCustomersCreate Ctrl+Shift+C
    Customer Account &Details... miCustomersDetails Ctrl+Shift+U
    Customer Account &Editor... miCustomersEditor Ctrl+Shift+T
    &Delete Customer Account... miCustomersDelete Ctrl+Shift+O
    tsCustomersSeparator
    &View Customers Accounts... miViewCustomers Ctrl+Shift+R
  37. On the Items Collection Editor (miCustomers.DropDownItems) dialog box, click OK
  38. In the Members list of the Items Collection Editor, click miWaterMeters
  39. In the right list, click DropDownItems and click its button
  40. Using the Add button, create two items as follows:
    Text (Name) Shortcuts
    &Setup Water Meter... miWaterMetersCreate Ctrl+Shift+W
    Water Meter &Details... miWaterMetersDetails Ctrl+Shift+I
    &Update Water Meter... miWaterMetersEditor Ctrl+Shift+A
    De&lete Water Meter... miWaterMetersDelete Ctrl+Shift+R
    tsWaterMetersSeparator
    View Wate&r Meters... miViewWaterMeters Ctrl+Shift+E
  41. On the Items Collection Editor (miWaterMeters.DropDownItems) dialog box, click OK
  42. In the Members list of the Items Collection Editor, click miWindow
  43. In the right list, click DropDownItems and click its button
  44. Using the Add button, create two items as follows:
    Text (Name)
    &Arrange miWindowArrange
    &Cascade miWindowCascade
    Tile &Horizontal miWindowTileHorizontal
    Tile &Vertical miWindowTileVertical
  45. On the Items Collection Editor (miWindow.DropDownItems) dialog box, click OK
  46. In the Members list of the Items Collection Editor, click miHelp
  47. In the right list, click DropDownItems and click its button
  48. Using the Add button, create an item as follows:
    Text (Name) Shortcuts
    &About Stellar Water Point... miHelpAbout Ctrl+F1
  49. On the Items Collection Editor (miHelp.DropDownItems) dialog box, click OK
  50. On the Items Collection Editor dialog box, click OK
  51. On the form, click the Window menu item and double-click Arrange
  52. Implement the event as follows:
    namespace StellarWaterPoint5
    {
        public partial class WaterDistribution : Form
        {
            public WaterDistribution()
            {
                InitializeComponent();
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            private void miWindowArrange_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.ArrangeIcons);
            }
        }
    }
  53. Return to the Stellar Water Point form and, below Arrange, double-click Cascade
  54. Implement the event as follows:
    namespace StellarWaterPoint5
    {
        public partial class WaterDistribution : Form
        {
            public WaterDistribution()
            {
                InitializeComponent();
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            private void miWindowArrange_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.ArrangeIcons);
            }
    
            private void miWindowCascade_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.Cascade);
            }
        }
    }
  55. Return to the Stellar Water Point form and, below Cascade, double-click Tile Horizontal
  56. Implement the event as follows:
    namespace StellarWaterPoint5
    {
        public partial class WaterDistribution : Form
        {
            public WaterDistribution()
            {
                InitializeComponent();
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            private void miWindowArrange_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.ArrangeIcons);
            }
    
            private void miWindowCascade_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.Cascade);
            }
    
            private void miWindowTileHorizontal_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.TileHorizontal);
            }
        }
    }
  57. Return to the Stellar Water Point form and, below Tile Horizontal, double-click Tile Vertical
  58. Implement the event as follows:
    namespace StellarWaterPoint5
    {
        public partial class WaterDistribution : Form
        {
            public WaterDistribution()
            {
                InitializeComponent();
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            private void miWindowArrange_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.ArrangeIcons);
            }
    
            private void miWindowCascade_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.Cascade);
            }
    
            private void miWindowTileHorizontal_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.TileHorizontal);
            }
    
            private void miWindowTileVertical_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.TileVertical);
            }
        }
    }
  59. Return to the Stellar Water Point form

Water Meters

Introduction

.

Practical LearningPractical Learning: Starting Water Meters Issues

  1. To create a class, in the Solution Explorer, right-click Models -> Add -> Class...
  2. On the main menu, click Project -> Add Class...
  3. Replace the name with WaterMeter
  4. Click Add
  5. Change the code as follows:
    namespace StellarWaterPoint5.Models
    {
        public record WaterMeter
        {
            public string? MeterNumber { get; set; }
            public string? Make        { get; set; }
            public string? Model       { get; set; }
            public string? MeterSize   { get; set; }
        }
    }
  6. In the Solution Explorer, right-click StellarWaterPoint1 -> Add -> New Folder
  7. Type WaterMeters as the name of the folder

Displaying Water Meters

To let the user see a list of the water meters in the database, we will use a form equipped with a list view.

Practical LearningPractical Learning: Displaying Water Meters

  1. To create a form, in the Solution Explorer, right-click WaterMeters -> Add -> Form (Windows Forms)...
  2. For the Name of the form, type Central
  3. Click Add
  4. In the Toolbox, click the ListView button and click the form
  5. On the form, right-click the list view and click Edit Columns...
  6. Create the columns as follows:
    (Name) Text Width TextAlign
    colWaterMeterId Id 40  
    colMeterNumber Meter # 150 Center
    colMake Make 300  
    colModel Model 150  
    colMeterSize Meter Size 150  
  7. Click OK
  8. Position and resize the list view on the form as follows:

    Stellar Water Point - Water Meters

    Control (Name) Other Properties
    ListView List View lvwWaterMeters FullRowSelect: True
    GridLines: True
    View: Details
  9. Click an unoccupied area of the form to select it
  10. In the Solution Explorer, click the Events button Events
  11. In the Events section of the Properties window, double-click Activated
  12. Change the document as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint5.Models;
    
    namespace StellarWaterPoint5.WaterMeters
    {
        public partial class Central : Form
        {
            public Central()
            {
                InitializeComponent();
            }
    
            private void ShowWaterMeters()
            {
                string strWaterMeters = @"E:\Stellar Water Point\WaterMeters.xml";
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        int counter = 1;
    
                        lvwWaterMeters.Items.Clear();
    
                        foreach (WaterMeter wm in waterMeters)
                        {
                            ListViewItem lviWaterMeter = new ListViewItem(counter++.ToString());
    
                            lviWaterMeter.SubItems.Add(wm.MeterNumber);
                            lviWaterMeter.SubItems.Add(wm.Make);
                            lviWaterMeter.SubItems.Add(wm.Model);
                            lviWaterMeter.SubItems.Add(wm.MeterSize);
    
                            lvwWaterMeters.Items.Add(lviWaterMeter);
                        }
                    }
                }
            }
    
            private void Central_Activated(object sender, EventArgs e)
            {
                ShowWaterMeters();
            }
        }
    }
  13. In the Solution Explorer, right-click WaterDistribution.cs and click View Code
  14. Change the document as follows:
    namespace StellarWaterPoint5
    {
        public partial class WaterDistribution : Form
        {
            public  static bool WaterMetersDisplaying;
            private WaterMeters.Central waterMeters;
    
            public WaterDistribution()
            {
                InitializeComponent();
    
                WaterMetersDisplaying = false;
    
                waterMeters = new WaterMeters.Central();
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            private void miWindowArrange_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.ArrangeIcons);
            }
    
            private void miWindowCascade_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.Cascade);
            }
    
            private void miWindowTileHorizontal_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.TileHorizontal);
            }
    
            private void miWindowTileVertical_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.TileVertical);
            }
        }
    }
  15. In the Solution Explorer, in the WaterMeters folder, double-click Central (make sure the form is selected)
  16. In the Events section of the Properties window, double-click FormClosing
  17. Implement the event as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint5.Models;
    
    namespace StellarWaterPoint5.WaterMeters
    {
        public partial class Central : Form
        {
            public Central()
            {
                InitializeComponent();
            }
    
            private void ShowWaterMeters()
            {
                string strWaterMeters = @"E:\Stellar Water Point\WaterMeters.xml";
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        int counter = 1;
    
                        lvwWaterMeters.Items.Clear();
    
                        foreach (WaterMeter wm in waterMeters)
                        {
                            ListViewItem lviWaterMeter = new ListViewItem(counter++.ToString());
    
                            lviWaterMeter.SubItems.Add(wm.MeterNumber);
                            lviWaterMeter.SubItems.Add(wm.Make);
                            lviWaterMeter.SubItems.Add(wm.Model);
                            lviWaterMeter.SubItems.Add(wm.MeterSize);
    
                            lvwWaterMeters.Items.Add(lviWaterMeter);
                        }
                    }
                }
            }
    
            private void Central_Activated(object sender, EventArgs e)
            {
                ShowWaterMeters();
            }
    
            private void Central_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (WaterDistribution.WaterMetersDisplaying == true)
                {
                    WaterDistribution.WaterMetersDisplaying = false;
                    Close();
                }
            }
        }
    }
  18. In the Solution Explorer, double-click WaterDistribution.cs to display the form
  19. On the menu that was designed on the form, click Water Meters and, below it, double-click View Water Meters...
  20. Implement the event as follows:
    namespace StellarWaterPoint5
    {
        public partial class WaterDistribution : Form
        {
            public static bool WaterMetersDisplaying;
            private WaterMeters.Central waterMeters;
    
            public WaterDistribution()
            {
                InitializeComponent();
    
                WaterMetersDisplaying = false;
    
                waterMeters = new WaterMeters.Central();
    
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            private void miWindowArrange_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.ArrangeIcons);
            }
    
            private void miWindowCascade_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.Cascade);
            }
    
            private void miWindowTileHorizontal_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.TileHorizontal);
            }
    
            private void miWindowTileVertical_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.TileVertical);
            }
    
            private void miWaterMetersViews_Click(object sender, EventArgs e)
            {
                if (WaterMetersDisplaying == false)
                {
                    waterMeters = new WaterMeters.Central();
    
                    waterMeters.MdiParent = this;
                    waterMeters.Show();
    
                    WaterMetersDisplaying = true;
                }
                else
                {
                    waterMeters.BringToFront();
                }
            }
        }
    }

A Water Meter Record

.

Practical LearningPractical Learning: Creating a Water Meter Record

  1. To create a form, in the Solution Explorer, right-click WaterMeters -> Add -> Form(Windows Forms)...
  2. Type Create
  3. Press Enter
  4. Design the form as follows:

    Stellar Water Point - New Water Meter

    Control (Name) Text Other Properties
    Label Label   &Meter #:  
    MaskedTextBox Masked Text Box mtbMeterNumber   Masked: 000-00-000
    Label Label   M&ake:  
    TextBox Text Box txtMake  
    Label Label   M&odel:  
    TextBox Text Box txtModel    
    Label Label   Me&ter Size:  
    TextBox Text Box txtMeterSize  
    Button Button btnSaveWateMeter S&ave Water Meter DialogResult: OK
    Button Button btnClose &Close  
  5. Click an unoccupied area of the form to select it and, in the Properties window, change the following characteristics:
    Text:         Stellar Water Point - Water Meter Setup
    AcceptButton: btnSaveWateMeter
  6. On the form, double-click the S&ave Water Meter button
  7. Return to the form and double-click the &Close button
  8. Change the document as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint5.Models;
    
    namespace StellarWaterPoint5.WaterMeters
    {
        public partial class Create : Form
        {
            public Create()
            {
                InitializeComponent();
            }
    
            private void btnSaveWateMeter_Click(object sender, EventArgs e)
            {
                string strActual = mtbMeterNumber.Text.Replace(" ", "").Replace("-", "");
    
                if(string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a meter number. " +
                                    "Otherwise, the water meter cannot be set up.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                List<WaterMeter> waterMeters = new List<WaterMeter> ();
                string strWaterMeters        = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters  = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters       = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists     == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
                    }
                }
    
                WaterMeter wm   = new WaterMeter()
                {
                    MeterNumber = mtbMeterNumber.Text,
                    Make        = txtMake.Text,
                    Model       = txtModel.Text,
                    MeterSize   = txtMeterSize.Text
                };
                waterMeters.Add(wm);
    
                using (TextWriter twWaterMeters = new StreamWriter(fiWaterMeters.FullName))
                {
                    xsWaterMeters.Serialize(twWaterMeters, waterMeters);
                }
    
                Close();
            }
    
            private void btnClose_Click(object sender, EventArgs e)
            {
                Close();
            }
        }
    }
  9. In the Solution Explorer, right-click WaterDistribution.cs and click View Code
  10. Change the document as follows:
    namespace StellarWaterPoint5
    {
        public partial class WaterDistribution : Form
        {
            public static bool WaterMetersDisplaying;
            public static bool WaterMeterCreateDisplaying;
    
            private WaterMeters.Central waterMeters;
            private WaterMeters.Create  waterMeterCreate;
    
            public WaterDistribution()
            {
                InitializeComponent();
    
                WaterMetersDisplaying      = false;
                WaterMeterCreateDisplaying = false;
    
                waterMeters                = new WaterMeters.Central();
                waterMeterCreate           = new WaterMeters.Create();
    
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            private void miWindowArrange_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.ArrangeIcons);
            }
    
            private void miWindowCascade_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.Cascade);
            }
    
            private void miWindowTileHorizontal_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.TileHorizontal);
            }
    
            private void miWindowTileVertical_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.TileVertical);
            }
    
            private void miWaterMetersViews_Click(object sender, EventArgs e)
            {
                if (WaterMetersDisplaying == false)
                {
                    waterMeters = new WaterMeters.Central();
    
                    waterMeters.MdiParent = this;
                    waterMeters.Show();
    
                    WaterMetersDisplaying = true;
                }
                else
                {
                    waterMeters.BringToFront();
                }
            }
        }
    }
  11. In the Solution Explorer, in the WaterMeters folder, double-click Create
  12. Click an unoccupied area of the form to select it
  13. In the Solution Explorer, click the Events button Events
  14. In the Events section of the Properties window, double-click FormClosing
  15. Implement the event as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint5.Models;
    
    namespace StellarWaterPoint5.WaterMeters
    {
        public partial class Create : Form
        {
            public Create()
            {
                InitializeComponent();
            }
    
            private void btnSaveWateMeter_Click(object sender, EventArgs e)
            {
                string strActual = mtbMeterNumber.Text.Replace(" ", "").Replace("-", "");
    
                if(string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a meter number. " +
                                    "Otherwise, the water meter cannot be set up.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
                    }
                }
    
                WaterMeter wm = new WaterMeter()
                {
                    MeterNumber = mtbMeterNumber.Text,
                    Make = txtMake.Text,
                    Model = txtModel.Text,
                    MeterSize = txtMeterSize.Text
                };
                waterMeters.Add(wm);
    
                using (TextWriter twWaterMeters = new StreamWriter(fiWaterMeters.FullName))
                {
                    xsWaterMeters.Serialize(twWaterMeters, waterMeters);
                }
    
                Close();
            }
    
            private void Create_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (WaterDistribution.WaterMeterCreateDisplaying == true)
                {
                    WaterDistribution.WaterMeterCreateDisplaying = false;
                    Close();
                }
            }
        }
    }
  16. In the Solution Explorer, double-click WaterDistribution.cs to select the main form of the application
  17. On the menu that was designed on the form, click Water Meters and, below it, double-click Setup Water Meter...
  18. Implement the event as follows:
    namespace StellarWaterPoint5
    {
        public partial class WaterDistribution : Form
        {
            public static bool WaterMetersDisplaying;
            public static bool WaterMeterCreateDisplaying;
    
            private WaterMeters.Central waterMeters;
            private WaterMeters.Create waterMeterCreate;
    
            public WaterDistribution()
            {
                InitializeComponent();
    
                WaterMetersDisplaying = false;
                WaterMeterCreateDisplaying = false;
    
                waterMeters = new WaterMeters.Central();
                waterMeterCreate = new WaterMeters.Create();
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            private void miWaterMetersViews_Click(object sender, EventArgs e)
            {
                if (WaterMetersDisplaying == false)
                {
                    waterMeters = new WaterMeters.Central();
    
                    waterMeters.MdiParent = this;
                    waterMeters.Show();
    
                    WaterMetersDisplaying = true;
                }
                else
                {
                    waterMeters.BringToFront();
                }
            }
    
            private void miWaterMetersCreate_Click(object sender, EventArgs e)
            {
                if(WaterMeterCreateDisplaying == false)
                {
                    waterMeterCreate = new();
                    waterMeterCreate.MdiParent = this;
                    waterMeterCreate.Show();
    
                    WaterMeterCreateDisplaying = true;
                }
                else
                {
                    waterMeterCreate.BringToFront();
                }
            }
        }
    }
  19. To execute, on the main menu, click Debug -> Start Without Debugging:

  20. On the main menu, click Water Meters and click View Water Meters...:

  21. On the main menu, click Water Meters and click Setup Water Meter...:

  22. Enter the value for each of the following records and click OK (or press Enter) for each:
    Meter # Make Model Meter Size
    392-494-572 Constance Technologies TG-4822 5/8 Inches
    938-705-869 Stan Wood 66-G 1 Inch
    588-279-663 Estellano NCF-226 3/4 Inches

    Stellar Water Point - Water Meters

  23. Close the forms and return to your programming environment

Water Meter Details

.

Practical LearningPractical Learning: Creating a Water Meter Record

  1. To create a form, in the Solution Explorer, right-click the WaterMeters folder -> Add -> Form (Windows Forms)...
  2. For the Name of the form, type Details
  3. Press Enter
  4. Design the form as follows:

    Stellar Water Point - New Water Meter

    Control (Name) Text Enabled Modifiers Other Properties
    Label Label   &Meter #:      
    MaskedTextBox Masked Text Box mtbMeterNumber   False Public Masked: 000-000-000
    Button Button btnFindWaterMeter &Find Water Meter      
    Label Label   Make:      
    TextBox Text Box txtMake   False Public  
    Label Label   Model:      
    TextBox Text Box txtModel   False Public  
    Label Label   Meter Size:      
    TextBox Text Box txtMeterSize   False Public  
    Button Button btnClose &Close      
  5. On the form, double-click the Find Water Meter button
  6. Return to the form and double-click the Close button
  7. Change the document as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint5.Models;
    
    namespace StellarWaterPoint5.WaterMeters
    {
        public partial class Details : Form
        {
            public Details()
            {
                InitializeComponent();
            }
    
            private void btnFindWateMeter_Click(object sender, EventArgs e)
            {
                string strActual = mtbMeterNumber.Text.Replace(" ", "").Replace("-", "");
    
                if(string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a number for a water meter.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                WaterMeter? meter = null;
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters        = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters  = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters       = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists     == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        meter       = waterMeters.Find(m => m.MeterNumber == mtbMeterNumber.Text)!;
    
                        if (meter is not null)
                        {
                            txtMake.Text = meter.Make;
                            txtModel.Text = meter.Model;
                            txtMeterSize.Text = meter.MeterSize;
                        }
                    }
                }
    
                if (meter is null)
                {
                    MessageBox.Show("There is no water meter with that number in our system.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
            }
    
            private void btnClose_Click(object sender, EventArgs e)
            {
                Close();
            }
        }
    }
  8. In the Solution Explorer, right-click WaterDistribution.cs and click View Code
  9. Change the document as follows:
    namespace StellarWaterPoint5
    {
        public partial class WaterDistribution : Form
        {
            public static bool WaterMetersDisplaying;
            public static bool WaterMeterCreateDisplaying;
            public static bool WaterMeterDetailsDisplaying;
    
            private WaterMeters.Central waterMeters;
            private WaterMeters.Create  waterMeterCreate;
            private WaterMeters.Details  waterMeterDetails;
    
            public WaterDistribution()
            {
                InitializeComponent();
    
                WaterMetersDisplaying      = false;
                WaterMeterCreateDisplaying = false;
                WaterMeterDetailsDisplaying = false;
    
                waterMeters                = new WaterMeters.Central();
                waterMeterCreate           = new WaterMeters.Create();
                waterMeterDetails           = new WaterMeters.Details();
    
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            private void miWindowArrange_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.ArrangeIcons);
            }
    
            private void miWindowCascade_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.Cascade);
            }
    
            private void miWindowTileHorizontal_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.TileHorizontal);
            }
    
            private void miWindowTileVertical_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.TileVertical);
            }
    
            private void miWaterMetersViews_Click(object sender, EventArgs e)
            {
                if (WaterMetersDisplaying == false)
                {
                    waterMeters = new WaterMeters.Central();
    
                    waterMeters.MdiParent = this;
                    waterMeters.Show();
    
                    WaterMetersDisplaying = true;
                }
                else
                {
                    waterMeters.BringToFront();
                }
            }
    
            private void miWaterMetersCreate_Click(object sender, EventArgs e)
            {
                if (WaterMeterCreateDisplaying == false)
                {
                    waterMeterCreate = new();
                    waterMeterCreate.MdiParent = this;
                    waterMeterCreate.Show();
    
                    WaterMeterCreateDisplaying = true;
                }
                else
                {
                    waterMeterCreate.BringToFront();
                }
            }
        }
    }
  10. In the Solution Explorer, in the WaterMeters folder, double-click Details
  11. Click an unoccupied area of the form to select it
  12. In the Solution Explorer, click the Events button Events
  13. In the Events section of the Properties window, double-click FormClosing
  14. Implement the events as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint5.Models;
    
    namespace StellarWaterPoint5.WaterMeters
    {
        public partial class Details : Form
        {
            public Details()
            {
                InitializeComponent();
            }
    
            private void btnFindWateMeter_Click(object sender, EventArgs e)
            {
                string strActual = mtbMeterNumber.Text.Replace(" ", "").Replace("-", "");
    
                if(string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a number for a water meter.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                WaterMeter? meter = null;
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        meter = waterMeters.Find(m => m.MeterNumber == mtbMeterNumber.Text)!;
    
                        if (meter is not null)
                        {
                            txtMake.Text = meter.Make;
                            txtModel.Text = meter.Model;
                            txtMeterSize.Text = meter.MeterSize;
                        }
                    }
                }
    
                if (meter is null)
                {
                    MessageBox.Show("There is no water meter with that number in our system.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
            }
    
            private void btnClose_Click(object sender, EventArgs e)
            {
                Close();
            }
    
            private void Details_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (WaterDistribution.WaterMeterDetailsDisplaying == true)
                {
                    WaterDistribution.WaterMeterDetailsDisplaying = false;
                    Close();
                }
            }
        }
    }
  15. In the Solution Explorer, double-click WaterDistribution.cs to select the main form of the application
  16. On the menu bar of the form, click Water Meters and, below it, double-click Water Meter Details...
  17. Implement the event as follows:
    namespace StellarWaterPoint5
    {
        public partial class WaterDistribution : Form
        {
            public static bool WaterMetersDisplaying;
            public static bool WaterMeterCreateDisplaying;
            public static bool WaterMeterDetailsDisplaying;
    
            private WaterMeters.Central waterMeters;
            private WaterMeters.Create waterMeterCreate;
            private WaterMeters.Details waterMeterDetails;
    
            public WaterDistribution()
            {
                InitializeComponent();
    
                WaterMetersDisplaying = false;
                WaterMeterCreateDisplaying = false;
                WaterMeterDetailsDisplaying = false;
    
                waterMeters = new WaterMeters.Central();
                waterMeterCreate = new WaterMeters.Create();
                waterMeterDetails = new WaterMeters.Details();
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            private void miWindowArrange_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.ArrangeIcons);
            }
    
            private void miWindowCascade_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.Cascade);
            }
    
            private void miWindowTileHorizontal_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.TileHorizontal);
            }
    
            private void miWindowTileVertical_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.TileVertical);
            }
    
            private void miWaterMetersViews_Click(object sender, EventArgs e)
            {
                if (WaterMetersDisplaying == false)
                {
                    waterMeters = new WaterMeters.Central();
    
                    waterMeters.MdiParent = this;
                    waterMeters.Show();
    
                    WaterMetersDisplaying = true;
                }
                else
                {
                    waterMeters.BringToFront();
                }
            }
    
            private void miWaterMetersCreate_Click(object sender, EventArgs e)
            {
                if (WaterMeterCreateDisplaying == false)
                {
                    waterMeterCreate = new();
                    waterMeterCreate.MdiParent = this;
                    waterMeterCreate.Show();
    
                    WaterMeterCreateDisplaying = true;
                }
                else
                {
                    waterMeterCreate.BringToFront();
                }
            }
    
            private void miWaterMetersDetails_Click(object sender, EventArgs e)
            {
                if (WaterMeterDetailsDisplaying == false)
                {
                    waterMeterDetails = new();
                    waterMeterDetails.MdiParent = this;
                    waterMeterDetails.Show();
    
                    WaterMeterDetailsDisplaying = true;
                }
                else
                {
                    waterMeterDetails.BringToFront();
                }
            }
        }
    }
  18. To execute the application, on the main menu, click Debug -> Start Without Debugging:

  19. On the main menu of the Stellar Water Point form, click View Water Meters:

    Stellar Water Point - Water Meters

  20. Again, on the main menu of the form, click Water Meters and click Water Meter Details:

    Stellar Water Point - View Water Meter

  21. In the Meter # text, type 392-494-572
  22. Click the Find Water Button button:

    Stellar Water Point - View Water Meter

  23. Close the forms and return to your programming environment

Updating a Water Meter Record

.

Practical LearningPractical Learning: Updating a Water Meter

  1. To create a form, in the Solution Explorer, right-click WaterMeters -> Add -> Form (Windows Forms)...
  2. For the Name of the file, type Editor as the name of the form
  3. Click Add
  4. Design the form as follows:

    Stellar Water Point - New Water Meter

    Control (Name) Text Enabled Other Properties
    Label Label   &Meter #:    
    MaskedTextBox Masked Text Box mtbMeterNumber   False Masked: 000-000-000
    Button Button btnFindWaterMeter &Find Water Meter    
    Label Label   Make:    
    TextBox Text Box txtMake   False  
    Label Label   Model:    
    TextBox Text Box txtModel   False  
    Label Label   Meter Size:    
    TextBox Text Box txtMeterSize   False  
    Button Button btnUpdateWateMeter &Update Wate Meter    
    Button Button btnClose &Close    
  5. On the form, double-click the Find Water Meter button
  6. Change the document as follows:
    using StellarWaterPoint5.Models;
    using System.Xml.Serialization;
    
    namespace StellarWaterPoint5.WaterMeters
    {
        public partial class Editor : Form
        {
            public Editor()
            {
                InitializeComponent();
            }
    
            private void btnFindWateMeter_Click(object sender, EventArgs e)
            {
                string strActual = mtbMeterNumber.Text.Replace(" ", "").Replace("-", "");
    
                if(string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a number for a water meter.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                WaterMeter? meter = null;
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        meter = waterMeters.Find(m => m.MeterNumber == mtbMeterNumber.Text)!;
    
                        if (meter is not null)
                        {
                            txtMake.Text = meter.Make;
                            txtModel.Text = meter.Model;
                            txtMeterSize.Text = meter.MeterSize;
                        }
                    }
                }
    
                if (meter is null)
                {
                    MessageBox.Show("There is no water meter with that number in our system.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
            }
        }
    }
  7. Return to the form and double-click the Update Water Meter button
  8. Implement the event as follows:
    using StellarWaterPoint5.Models;
    using System.Xml.Serialization;
    
    namespace StellarWaterPoint5.WaterMeters
    {
        public partial class Editor : Form
        {
            public Editor()
            {
                InitializeComponent();
            }
    
            private void btnFindWateMeter_Click(object sender, EventArgs e)
            {
                string strActual = mtbMeterNumber.Text.Replace(" ", "").Replace("-", "");
    
                if(string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a number for a water meter.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                WaterMeter? meter = null;
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        meter = waterMeters.Find(m => m.MeterNumber == mtbMeterNumber.Text)!;
    
                        if (meter is not null)
                        {
                            txtMake.Text = meter.Make;
                            txtModel.Text = meter.Model;
                            txtMeterSize.Text = meter.MeterSize;
                        }
                    }
                }
    
                if (meter is null)
                {
                    MessageBox.Show("There is no water meter with that number in our system.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
            }
    
            private void btnUpdateWaterMeter_Click(object sender, EventArgs e)
            {
                string strActual = mtbMeterNumber.Text.Replace(" ", "").Replace("-", "");
    
                if(string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a number for a water meter.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        waterMeters.ForEach(meter =>
                        {
                            if (meter.MeterNumber == mtbMeterNumber.Text)
                            {
                                meter.Make      = txtMake.Text;
                                meter.Model     = txtModel.Text;
                                meter.MeterSize = txtMeterSize.Text;
                            }
                        });
                    }
                }
    
                using (TextWriter twWaterMeters = new StreamWriter(fiWaterMeters.FullName))
                {
                    xsWaterMeters.Serialize(twWaterMeters, waterMeters);
                }
    
                Close();
            }
        }
    }
  9. Return to the form and double-click the Close button
  10. Implement the event as follows:
    using StellarWaterPoint5.Models;
    using System.Xml.Serialization;
    
    namespace StellarWaterPoint5.WaterMeters
    {
        public partial class Editor : Form
        {
            public Editor()
            {
                InitializeComponent();
            }
    
            private void btnFindWateMeter_Click(object sender, EventArgs e)
            {
                string strActual = mtbMeterNumber.Text.Replace(" ", "").Replace("-", "");
    
                if(string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a number for a water meter.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                WaterMeter? meter = null;
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        meter = waterMeters.Find(m => m.MeterNumber == mtbMeterNumber.Text)!;
    
                        if (meter is not null)
                        {
                            txtMake.Text = meter.Make;
                            txtModel.Text = meter.Model;
                            txtMeterSize.Text = meter.MeterSize;
                        }
                    }
                }
    
                if (meter is null)
                {
                    MessageBox.Show("There is no water meter with that number in our system.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
            }
    
            private void btnUpdateWaterMeter_Click(object sender, EventArgs e)
            {
                if (string.IsNullOrEmpty(mtbMeterNumber.Text))
                {
                    MessageBox.Show("You must type a number for a water meter.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        waterMeters.ForEach(meter =>
                        {
                            if (meter.MeterNumber == mtbMeterNumber.Text)
                            {
                                meter.Make      = txtMake.Text;
                                meter.Model     = txtModel.Text;
                                meter.MeterSize = txtMeterSize.Text;
                            }
                        });
                    }
                }
    
                using (TextWriter twWaterMeters = new StreamWriter(fiWaterMeters.FullName))
                {
                    xsWaterMeters.Serialize(twWaterMeters, waterMeters);
                }
    
                Close();
            }
    
            private void btnClose_Click(object sender, EventArgs e)
            {
                Close();
            }
        }
    }
  11. In the Solution Explorer, right-click WaterDistribution.cs and click View Code
  12. Change the document as follows:
    namespace StellarWaterPoint5
    {
        public partial class WaterDistribution : Form
        {
            public static bool           WaterMetersDisplaying;
            public static bool           WaterMeterCreateDisplaying;
            public static bool           WaterMeterDetailsDisplaying;
            public static bool           WaterMeterEditorDisplaying;
    
            private WaterMeters.Central  waterMeters;
            private WaterMeters.Create   waterMeterCreate;
            private WaterMeters.Details  waterMeterDetails;
            private WaterMeters.Editor   waterMeterEditor;
    
            public WaterDistribution()
            {
                InitializeComponent();
    
                WaterMetersDisplaying       = false;
                WaterMeterCreateDisplaying  = false;
                WaterMeterDetailsDisplaying = false;
                WaterMeterEditorDisplaying  = false;
    
                waterMeters                 = new WaterMeters.Central();
                waterMeterCreate            = new WaterMeters.Create();
                waterMeterDetails           = new WaterMeters.Details();
                waterMeterEditor            = new WaterMeters.Editor();
    
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            private void miWindowArrange_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.ArrangeIcons);
            }
    
            private void miWindowCascade_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.Cascade);
            }
    
            private void miWindowTileHorizontal_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.TileHorizontal);
            }
    
            private void miWindowTileVertical_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.TileVertical);
            }
    
            private void miWaterMetersViews_Click(object sender, EventArgs e)
            {
                if (WaterMetersDisplaying == false)
                {
                    waterMeters = new WaterMeters.Central();
    
                    waterMeters.MdiParent = this;
                    waterMeters.Show();
    
                    WaterMetersDisplaying = true;
                }
                else
                {
                    waterMeters.BringToFront();
                }
            }
        }
    }
  13. In the Solution Explorer, in the WaterMeters folder, double-click Editor
  14. Click an unoccupied area of the form to select it
  15. In the Solution Explorer, click the Events button Events
  16. In the Events section of the Properties window, double-click FormClosing
  17. Implement the events as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.WaterMeters
    {
        public partial class Editor : Form
        {
            public Editor()
            {
                InitializeComponent();
            }
    
            private void btnFindWateMeter_Click(object sender, EventArgs e)
            {
                string strActual = mtbMeterNumber.Text.Replace(" ", "").Replace("-", "");
    
                if(string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a number for a water meter.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                WaterMeter? meter = null;
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        meter = waterMeters.Find(m => m.MeterNumber == mtbMeterNumber.Text)!;
    
                        if (meter is not null)
                        {
                            txtMake.Text = meter.Make;
                            txtModel.Text = meter.Model;
                            txtMeterSize.Text = meter.MeterSize;
                        }
                    }
                }
    
                if (meter is null)
                {
                    MessageBox.Show("There is no water meter with that number in our system.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
            }
    
            private void btnUpdateWaterMeter_Click(object sender, EventArgs e)
            {
                if (string.IsNullOrEmpty(mtbMeterNumber.Text))
                {
                    MessageBox.Show("You must type a number for a water meter.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        waterMeters.ForEach(meter =>
                        {
                            if (meter.MeterNumber == mtbMeterNumber.Text)
                            {
                                txtMake.Text = meter.Make;
                                txtModel.Text = meter.Model;
                                txtMeterSize.Text = meter.MeterSize;
                            }
                        });
                    }
                }
    
                using (TextWriter twWaterMeters = new StreamWriter(fiWaterMeters.FullName))
                {
                    xsWaterMeters.Serialize(twWaterMeters, waterMeters);
                }
    
                Close();
            }
    
            private void btnClose_Click(object sender, EventArgs e)
            {
                Close();
            }
    
            private void Editor_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (WaterDistribution.WaterMeterEditorDisplaying == true)
                {
                    WaterDistribution.WaterMeterEditorDisplaying = false;
                    Close();
                }
            }
        }
    }
  18. In the Solution Explorer, double-click WaterDistribution.cs to select the main form of the application
  19. On the menu bar of the form, click Water Meters and, below it, double-click Update Water Meter...
  20. Implement the event as follows:
    namespace StellarWaterPoint50
    {
        public partial class WaterDistribution : Form
        {
            public static bool              WaterMetersDisplaying;
            public static bool              WaterMeterCreateDisplaying;
            public static bool              WaterMeterDetailsDisplaying;
            public static bool              WaterMeterEditorDisplaying;
    
            private WaterMeters.Central     waterMeters;
            private WaterMeters.Create      waterMeterCreate;
            private WaterMeters.Details     waterMeterDetails;
            private WaterMeters.Editor      waterMeterEditor;
    
            public WaterDistribution()
            {
                InitializeComponent();
    
                WaterMetersDisplaying       = false;
                WaterMeterCreateDisplaying  = false;
                WaterMeterDetailsDisplaying = false;
                WaterMeterEditorDisplaying  = false;
    
                waterMeters                 = new WaterMeters.Central();
                waterMeterCreate            = new WaterMeters.Create();
                waterMeterDetails           = new WaterMeters.Details();
                waterMeterEditor            = new WaterMeters.Editor();
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            private void miWindowArrange_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.ArrangeIcons);
            }
    
            private void miWindowCascade_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.Cascade);
            }
    
            private void miWindowTileHorizontal_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.TileHorizontal);
            }
    
            private void miWindowTileVertical_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.TileVertical);
            }
    
            private void miWaterMetersView_Click(object sender, EventArgs e)
            {
                if (WaterMetersDisplaying == false)
                {
                    waterMeters = new WaterMeters.Central();
    
                    waterMeters.MdiParent = this;
                    waterMeters.Show();
    
                    WaterMetersDisplaying = true;
                }
                else
                {
                    waterMeters.BringToFront();
                }
            }
    
            private void miWaterMetersCreate_Click(object sender, EventArgs e)
            {
                if (WaterMeterCreateDisplaying == false)
                {
                    waterMeterCreate = new();
                    waterMeterCreate.MdiParent = this;
                    waterMeterCreate.Show();
    
                    WaterMeterCreateDisplaying = true;
                }
                else
                {
                    waterMeterCreate.BringToFront();
                }
            }
    
            private void miWaterMetersDetails_Click(object sender, EventArgs e)
            {
                if (WaterMeterDetailsDisplaying == false)
                {
                    waterMeterDetails = new();
                    waterMeterDetails.MdiParent = this;
                    waterMeterDetails.Show();
    
                    WaterMeterDetailsDisplaying = true;
                }
                else
                {
                    waterMeterDetails.BringToFront();
                }
            }
    
            private void miWaterMetersEditor_Click(object sender, EventArgs e)
            {
                if (WaterMeterEditorDisplaying == false)
                {
                    waterMeterEditor = new();
                    waterMeterEditor.MdiParent = this;
                    waterMeterEditor.Show();
    
                    WaterMeterEditorDisplaying = true;
                }
                else
                {
                    waterMeterEditor.BringToFront();
                }
            }
        }
    }
  21. To execute the application, on the main menu, click Debug -> Start Without Debugging

  22. On the main menu of the central form of the application, click Water Meters and click View Water Meters

    Stellar Water Point - Water Meters

  23. On the main menu of the central form of the application, click Water Meters and click Update Water Meter

    Stellar Water Point - Water Meters

  24. Click the Edit Water Meter button
  25. In the Meter # text, type 938-705-869
  26. Click the Find Water Meter button

    Stellar Water Point - Water Meter Editor

  27. Change the values as follows:
    Make: Stanford Trend
    Model: 266G
    Meter Size: 1 1/2 Inches

    Stellar Water Point - Water Meter Editor

  28. Click the Update Water Meter button:

    Stellar Water Point - Water Meters

  29. Close the forms and return to your programming environment

Deleting a Water Meter Record

.

Practical LearningPractical Learning: Deleting a Water Meter Record

  1. To create a form, in the Solution Explorer, right-click WaterMeters -> Add -> Form(Windows Forms)...
  2. In the Name text box, replace the string with Delete as the name of the form
  3. Press Enter
  4. Design the form as follows:

    Stellar Water Point - New Water Meter

    Control (Name) Text Enabled Other Properties
    Label Label   &Meter #:    
    MaskedTextBox Masked Text Box mtbMeterNumber   False Masked: 000-000-000
    Button Button btnFindWaterMeter &Find Water Meter    
    Label Label   Make:    
    TextBox Text Box txtMake   False  
    Label Label   Model:    
    TextBox Text Box txtModel   False  
    Label Label   Meter Size:    
    TextBox Text Box txtMeterSize   False  
    Button Button btnDeleteWaterMeter &Delete Water Meter    
    Button Button btnClose &Close    
  5. On the form, double-click the Find Water Meter button
  6. Change the document as follows:
    using StellarWaterPoint5.Models;
    using System.Xml.Serialization;
    
    namespace StellarWaterPoint5.WaterMeters
    {
        public partial class Delete : Form
        {
            public Editor()
            {
                InitializeComponent();
            }
    
            private void btnFindWateMeter_Click(object sender, EventArgs e)
            {
                string strActual = mtbMeterNumber.Text.Replace(" ", "").Replace("-", "");
    
                if(string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a number for a water meter.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                WaterMeter? meter = null;
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        meter = waterMeters.Find(m => m.MeterNumber == mtbMeterNumber.Text)!;
    
                        if (meter is not null)
                        {
                            txtMake.Text = meter.Make;
                            txtModel.Text = meter.Model;
                            txtMeterSize.Text = meter.MeterSize;
                        }
                    }
                }
    
                if (meter is null)
                {
                    MessageBox.Show("There is no water meter with that number in our system.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
            }
        }
    }
  7. Return to the form and double-click the Delete Water Meter button
  8. Return to the form and double-click the Close button
  9. Implement the events as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.WaterMeters
    {
        public partial class Delete : Form
        {
            public Delete()
            {
                InitializeComponent();
            }
    
            private void btnFindWateMeter_Click(object sender, EventArgs e)
            {
                string strActual = mtbMeterNumber.Text.Replace(" ", "").Replace("-", "");
    
                if (string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a number for a water meter.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                WaterMeter? meter = null;
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        meter = waterMeters.Find(m => m.MeterNumber == mtbMeterNumber.Text)!;
    
                        if (meter is not null)
                        {
                            txtMake.Text = meter.Make;
                            txtModel.Text = meter.Model;
                            txtMeterSize.Text = meter.MeterSize;
                        }
                    }
                }
    
                if (meter is null)
                {
                    MessageBox.Show("There is no water meter with that number in our system.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
            }
    
            private void btnDeleteWaterMeter_Click(object sender, EventArgs e)
            {
                string strActual = mtbMeterNumber.Text.Replace(" ", "").Replace("-", "");
    
                if (string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a number for a water meter.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
                        
                        foreach(WaterMeter meter in waterMeters)
                        {
                            if (meter.MeterNumber == mtbMeterNumber.Text)
                            {
                                if(MessageBox.Show("Are you sure you want to delete the water meter with meter number " +
                                                    mtbMeterNumber.Text + "?",
                                                    "Stellar Water Point",
                                                    MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes)
                                {
                                    waterMeters.Remove(meter);
    
                                    MessageBox.Show("The water meter whose meter number is " +
                                                    mtbMeterNumber.Text + " is going to be removed from our system.",
                                                    "Stellar Water Point",
                                                    MessageBoxButtons.OK, MessageBoxIcon.Information);
                                    break;
                                }
                            }
                        }
                    }
                }
    
                using (TextWriter twWaterMeters = new StreamWriter(fiWaterMeters.FullName))
                {
                    xsWaterMeters.Serialize(twWaterMeters, waterMeters);
                }
    
                Close();
            }
    
            private void btnClose_Click(object sender, EventArgs e)
            {
                Close();
            }
        }
    }
  10. In the Solution Explorer, right-click WaterDistribution.cs and click View Code
  11. Change the document as follows:
    namespace StellarWaterPoint5
    {
        public partial class WaterDistribution : Form
        {
            public static bool           WaterMetersDisplaying;
            public static bool           WaterMeterCreateDisplaying;
            public static bool           WaterMeterDetailsDisplaying;
            public static bool           WaterMeterEditorDisplaying;
            public static bool           WaterMeterDeleteDisplaying;
    
            private WaterMeters.Central  waterMeters;
            private WaterMeters.Create   waterMeterCreate;
            private WaterMeters.Details  waterMeterDetails;
            private WaterMeters.Editor   waterMeterEditor;
            private WaterMeters.Delete   waterMeterDelete;
    
            public WaterDistribution()
            {
                InitializeComponent();
    
                WaterMetersDisplaying       = false;
                WaterMeterCreateDisplaying  = false;
                WaterMeterDetailsDisplaying = false;
                WaterMeterEditorDisplaying  = false;
                WaterMeterDeleteDisplaying  = false;
    
                waterMeters                 = new WaterMeters.Central();
                waterMeterCreate            = new WaterMeters.Create();
                waterMeterDetails           = new WaterMeters.Details();
                waterMeterEditor            = new WaterMeters.Editor();
                waterMeterDelete            = new WaterMeters.Delete();
    
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            . . .
        }
    }
  12. In the Solution Explorer, in the WaterMeters folder, double-click Delete
  13. Click an unoccupied area of the form to select it
  14. In the Solution Explorer, click the Events button Events
  15. In the Events section of the Properties window, double-click FormClosing
  16. Implement the events as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.WaterMeters
    {
        public partial class Delete : Form
        {
            public Delete()
            {
                InitializeComponent();
            }
    
            private void btnFindWateMeter_Click(object sender, EventArgs e)
            {
                string strActual = mtbMeterNumber.Text.Replace(" ", "").Replace("-", "");
    
                if(string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a number for a water meter.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                WaterMeter? meter = null;
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        meter = waterMeters.Find(m => m.MeterNumber == mtbMeterNumber.Text)!;
    
                        if (meter is not null)
                        {
                            txtMake.Text = meter.Make;
                            txtModel.Text = meter.Model;
                            txtMeterSize.Text = meter.MeterSize;
                        }
                    }
                }
    
                if (meter is null)
                {
                    MessageBox.Show("There is no water meter with that number in our system.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
            }
    
            private void btnDeleteWaterMeter_Click(object sender, EventArgs e)
            {
                string strActual = mtbMeterNumber.Text.Replace(" ", "").Replace("-", "");
    
                if(string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a number for a water meter.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        waterMeters.ForEach(meter =>
                        {
                            if (meter.MeterNumber == mtbMeterNumber.Text)
                            {
                                waterMeters.Remove(meter);
                            }
                        });
                    }
                }
    
                using (TextWriter twWaterMeters = new StreamWriter(fiWaterMeters.FullName))
                {
                    xsWaterMeters.Serialize(twWaterMeters, waterMeters);
                }
    
                Close();
            }
    
            private void btnClose_Click(object sender, EventArgs e)
            {
                Close();
            }
    
            private void Delete_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (WaterDistribution.WaterMeterDeleteDisplaying == true)
                {
                    WaterDistribution.WaterMeterDeleteDisplaying = false;
                    Close();
                }
            }
        }
    }
  17. In the Solution Explorer, double-click WaterDistribution.cs to select the main form of the application
  18. On the menu bar of the form, click Water Meters and, below it, double-click Delete Water Meter...
  19. Implement the event as follows:
    namespace StellarWaterPoint50
    {
        public partial class WaterDistribution : Form
        {
            public static bool WaterMetersDisplaying;
            public static bool WaterMeterCreateDisplaying;
            public static bool WaterMeterDetailsDisplaying;
            public static bool WaterMeterEditorDisplaying;
            public static bool WaterMeterDeleteDisplaying;
    
            private WaterMeters.Central waterMeters;
            private WaterMeters.Create waterMeterCreate;
            private WaterMeters.Details waterMeterDetails;
            private WaterMeters.Editor waterMeterEditor;
            private WaterMeters.Delete waterMeterDelete;
    
            public WaterDistribution()
            {
                InitializeComponent();
    
                WaterMetersDisplaying = false;
                WaterMeterCreateDisplaying = false;
                WaterMeterDetailsDisplaying = false;
                WaterMeterEditorDisplaying = false;
                WaterMeterDeleteDisplaying = false;
    
                waterMeters = new WaterMeters.Central();
                waterMeterCreate = new WaterMeters.Create();
                waterMeterDetails = new WaterMeters.Details();
                waterMeterEditor = new WaterMeters.Editor();
                waterMeterDelete = new WaterMeters.Delete();
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            private void miWindowArrange_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.ArrangeIcons);
            }
    
            private void miWindowCascade_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.Cascade);
            }
    
            private void miWindowTileHorizontal_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.TileHorizontal);
            }
    
            private void miWindowTileVertical_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.TileVertical);
            }
    
            private void miWaterMetersView_Click(object sender, EventArgs e)
            {
                if (WaterMetersDisplaying == false)
                {
                    waterMeters = new WaterMeters.Central();
    
                    waterMeters.MdiParent = this;
                    waterMeters.Show();
    
                    WaterMetersDisplaying = true;
                }
                else
                {
                    waterMeters.BringToFront();
                }
            }
    
            private void miWaterMetersCreate_Click(object sender, EventArgs e)
            {
                if (WaterMeterCreateDisplaying == false)
                {
                    waterMeterCreate = new();
                    waterMeterCreate.MdiParent = this;
                    waterMeterCreate.Show();
    
                    WaterMeterCreateDisplaying = true;
                }
                else
                {
                    waterMeterCreate.BringToFront();
                }
            }
    
            private void miWaterMetersDetails_Click(object sender, EventArgs e)
            {
                if (WaterMeterDetailsDisplaying == false)
                {
                    waterMeterDetails = new();
                    waterMeterDetails.MdiParent = this;
                    waterMeterDetails.Show();
    
                    WaterMeterDetailsDisplaying = true;
                }
                else
                {
                    waterMeterDetails.BringToFront();
                }
            }
    
            private void miWaterMetersEditor_Click(object sender, EventArgs e)
            {
                if (WaterMeterEditorDisplaying == false)
                {
                    waterMeterEditor = new();
                    waterMeterEditor.MdiParent = this;
                    waterMeterEditor.Show();
    
                    WaterMeterEditorDisplaying = true;
                }
                else
                {
                    waterMeterEditor.BringToFront();
                }
            }
    
            private void miWaterMetersDelete_Click(object sender, EventArgs e)
            {
                if (WaterMeterDeleteDisplaying == false)
                {
                    waterMeterDelete = new();
                    waterMeterDelete.MdiParent = this;
                    waterMeterDelete.Show();
    
                    WaterMeterDeleteDisplaying = true;
                }
                else
                {
                    waterMeterDelete.BringToFront();
                }
            }
        }
    }
  20. To execute the application, on the main menu, click Debug -> Start Without Debugging

  21. On the main menu of the central form of the application, click Water Meters and click View Water Meters

    Stellar Water Point - Water Meters

  22. On the main menu of the central form of the application, click Water Meters and click Delete Water Meter

    Stellar Water Point - Water Meters

  23. In the Meter # text, type 938-705-869
  24. Click the Find Water Meter button

    Stellar Water Point - Water Meter Editor

  25. Click the Delete Water Meter button. Tead the first message box and click Yes. Then click OK on the second message box:

    Stellar Water Point - Water Meters

  26. In the same way, delete one of the other two records to leave the other record in the document
  27. Close the forms and return to your programming environment
  28. From the Windows Explorer, open the WaterMeters.xml file
  29. Replace the content of the file with the provided file
  30. Save the file
  31. Return to your programming environment

Customers

Introduction

.

Practical LearningPractical Learning: Starting Water Meters Issues

  1. To create a class, in the Solution Explorer, right-click Models -> Add -> Class...
  2. On the main menu, click Project -> Add Class...
  3. Replace the name with Customer
  4. Click Add
  5. Change the code as follows:
    namespace StellarWaterPoint5.Models
    {
        public record Customer
        {
            public string? AccountNumber { get; set; }
            public string? AccountName   { get; set; }
            public string? AccountType   { get; set; }
            public string? MeterNumber   { get; set; }
            public string? Address       { get; set; }
            public string? City          { get; set; }
            public string? County        { get; set; }
            public string? State         { get; set; }
            public string? ZIPCode       { get; set; }
        }
    }
  6. In the Solution Explorer, right-click StellarWaterPoint1 -> Add -> New Folder
  7. Type Customers as the name of the folder

Displaying Customers Records

.

Practical LearningPractical Learning: Displaying Water Meters

  1. To create a form, in the Solution Explorer, right-click Customers -> Add -> Form (Windows Forms)...
  2. For the Name of the form, type Central
  3. Click Add
  4. In the Toolbox, click the ListView button and click the form
  5. On the form, right-click the list view and click Edit Columns...
  6. Create the columns as follows:
    (Name) Text TextAlign Width
    colCustomerId Id   40
    colAccountNumber Account # Center 150
    colAccountName Account Name   200
    colAccountType Account Type   200
    colMeterNumber Meter # Center 100
    colAddress Address   250
    colCity City   125
    colCounty County   125
    colState State Center  
    colZIPCode ZIP-Code Center 125
  7. Click OK
  8. Position and resize the list view on the form as follows:

    Stellar Water Point - Water Meters

    Control (Name) Other Properties
    ListView List View lvwCustomers FullRowSelect: True
    GridLines: True
    View: Details
  9. Click an unoccupied area of the form to select it
  10. In the Solution Explorer, click the Events button Events
  11. In the Events section of the Properties window, double-click Activated
  12. Change the document as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.Customers
    {
        public partial class Central : Form
        {
            public Central()
            {
                InitializeComponent();
            }
    
            private void ShowCustomers()
            {
                string strCustomers = @"C:\Stellar Water Point8\Customers.xml";
                List<Customer> clients = new List<Customer>();
                XmlSerializer xsCustomers = new XmlSerializer(typeof(List<Customer>));
    
                FileInfo fiCustomers = new FileInfo(strCustomers);
    
                if (fiCustomers.Exists == true)
                {
                    using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
                    {
                        clients = (List<Customer>)xsCustomers.Deserialize(trCustomers)!;
    
                        int counter = 1;
    
                        lvwCustomers.Items.Clear();
    
                        foreach (Customer client in clients)
                        {
                            ListViewItem lviCustomer = new ListViewItem(counter++.ToString());
    
                            lviCustomer.SubItems.Add(client.AccountNumber);
                            lviCustomer.SubItems.Add(client.AccountName);
                            lviCustomer.SubItems.Add(client.AccountType);
                            lviCustomer.SubItems.Add(client.MeterNumber);
                            lviCustomer.SubItems.Add(client.Address);
                            lviCustomer.SubItems.Add(client.City);
                            lviCustomer.SubItems.Add(client.County);
                            lviCustomer.SubItems.Add(client.State);
                            lviCustomer.SubItems.Add(client.ZIPCode);
    
                            lvwCustomers.Items.Add(lviCustomer);
                        }
                    }
                }
            }
    
            private void Central_Activated(object sender, EventArgs e)
            {
                ShowCustomers();
            }
        }
    }
  13. In the Solution Explorer, right-click WaterDistribution.cs and click View Code
  14. Change the document as follows:
    namespace StellarWaterPoint50
    {
        public partial class WaterDistribution : Form
        {
            public static bool WaterMetersDisplaying;
            public static bool WaterMeterCreateDisplaying;
            public static bool WaterMeterDetailsDisplaying;
            public static bool WaterMeterEditorDisplaying;
            public static bool WaterMeterDeleteDisplaying;
    
            private WaterMeters.Central waterMeters;
            private WaterMeters.Create waterMeterCreate;
            private WaterMeters.Details waterMeterDetails;
            private WaterMeters.Editor waterMeterEditor;
            private WaterMeters.Delete waterMeterDelete;
    
            public static bool CustomersDisplaying;
            private Customers.Central customers;
    
            public WaterDistribution()
            {
                InitializeComponent();
    
                WaterMetersDisplaying = false;
                WaterMeterCreateDisplaying = false;
                WaterMeterDetailsDisplaying = false;
                WaterMeterEditorDisplaying = false;
                WaterMeterDeleteDisplaying = false;
    
                waterMeters = new WaterMeters.Central();
                waterMeterCreate = new WaterMeters.Create();
                waterMeterDetails = new WaterMeters.Details();
                waterMeterEditor = new WaterMeters.Editor();
                waterMeterDelete = new WaterMeters.Delete();
    
                CustomersDisplaying = false;
    
                customers = new Customers.Central();
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            . . .
        }
    }
  15. In the Solution Explorer, in the Customers folder, double-click Central (make sure the form is selected)
  16. In the Events section of the Properties window, double-click FormClosing
  17. Implement the event as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.Customers
    {
        public partial class Central : Form
        {
            public Central()
            {
                InitializeComponent();
            }
    
            private void ShowCustomers()
            {
                string strCustomers = @"C:\Stellar Water Point8\Customers.xml";
                List<Customer> clients = new List<Customer>();
                XmlSerializer xsCustomers = new XmlSerializer(typeof(List<Customer>));
    
                FileInfo fiCustomers = new FileInfo(strCustomers);
    
                if (fiCustomers.Exists == true)
                {
                    using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
                    {
                        clients = (List<Customer>)xsCustomers.Deserialize(trCustomers)!;
    
                        int counter = 1;
    
                        lvwCustomers.Items.Clear();
    
                        foreach (Customer client in clients)
                        {
                            ListViewItem lviCustomer = new ListViewItem(counter++.ToString());
    
                            lviCustomer.SubItems.Add(client.AccountNumber);
                            lviCustomer.SubItems.Add(client.AccountName);
                            lviCustomer.SubItems.Add(client.AccountType);
                            lviCustomer.SubItems.Add(client.MeterNumber);
                            lviCustomer.SubItems.Add(client.Address);
                            lviCustomer.SubItems.Add(client.City);
                            lviCustomer.SubItems.Add(client.County);
                            lviCustomer.SubItems.Add(client.State);
                            lviCustomer.SubItems.Add(client.ZIPCode);
    
                            lvwCustomers.Items.Add(lviCustomer);
                        }
                    }
                }
            }
    
            private void Central_Activated(object sender, EventArgs e)
            {
                ShowCustomers();
            }
    
            private void Central_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (WaterDistribution.CustomersDisplaying == true)
                {
                    WaterDistribution.CustomersDisplaying = false;
                    Close();
                }
            }
        }
    }
  18. In the Solution Explorer, double-click WaterDistribution.cs to display the form
  19. On the menu that was designed on the form, click Customers and, below it, double-click View Customers Accounts...
  20. Implement the event as follows:
    namespace StellarWaterPoint50
    {
        public partial class WaterDistribution : Form
        {
            public static bool WaterMetersDisplaying;
            public static bool WaterMeterCreateDisplaying;
            public static bool WaterMeterDetailsDisplaying;
            public static bool WaterMeterEditorDisplaying;
            public static bool WaterMeterDeleteDisplaying;
    
            private WaterMeters.Central waterMeters;
            private WaterMeters.Create waterMeterCreate;
            private WaterMeters.Details waterMeterDetails;
            private WaterMeters.Editor waterMeterEditor;
            private WaterMeters.Delete waterMeterDelete;
    
            public static bool CustomersDisplaying;
    
            private Customers.Central customers;
    
            public WaterDistribution()
            {
                InitializeComponent();
    
                WaterMetersDisplaying = false;
                WaterMeterCreateDisplaying = false;
                WaterMeterDetailsDisplaying = false;
                WaterMeterEditorDisplaying = false;
                WaterMeterDeleteDisplaying = false;
    
                waterMeters = new WaterMeters.Central();
                waterMeterCreate = new WaterMeters.Create();
                waterMeterDetails = new WaterMeters.Details();
                waterMeterEditor = new WaterMeters.Editor();
                waterMeterDelete = new WaterMeters.Delete();
    
                CustomersDisplaying = false;
    
                customers = new Customers.Central();
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            private void miWindowArrange_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.ArrangeIcons);
            }
    
            private void miWindowCascade_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.Cascade);
            }
    
            private void miWindowTileHorizontal_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.TileHorizontal);
            }
    
            private void miWindowTileVertical_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.TileVertical);
            }
    
            private void miWaterMetersView_Click(object sender, EventArgs e)
            {
                if (WaterMetersDisplaying == false)
                {
                    waterMeters = new WaterMeters.Central();
    
                    waterMeters.MdiParent = this;
                    waterMeters.Show();
    
                    WaterMetersDisplaying = true;
                }
                else
                {
                    waterMeters.BringToFront();
                }
            }
    
            private void miWaterMetersCreate_Click(object sender, EventArgs e)
            {
                if (WaterMeterCreateDisplaying == false)
                {
                    waterMeterCreate = new();
                    waterMeterCreate.MdiParent = this;
                    waterMeterCreate.Show();
    
                    WaterMeterCreateDisplaying = true;
                }
                else
                {
                    waterMeterCreate.BringToFront();
                }
            }
    
            private void miWaterMetersDetails_Click(object sender, EventArgs e)
            {
                if (WaterMeterDetailsDisplaying == false)
                {
                    waterMeterDetails = new();
                    waterMeterDetails.MdiParent = this;
                    waterMeterDetails.Show();
    
                    WaterMeterDetailsDisplaying = true;
                }
                else
                {
                    waterMeterDetails.BringToFront();
                }
            }
    
            private void miWaterMetersEditor_Click(object sender, EventArgs e)
            {
                if (WaterMeterEditorDisplaying == false)
                {
                    waterMeterEditor = new();
                    waterMeterEditor.MdiParent = this;
                    waterMeterEditor.Show();
    
                    WaterMeterEditorDisplaying = true;
                }
                else
                {
                    waterMeterEditor.BringToFront();
                }
            }
    
            private void miWaterMetersDelete_Click(object sender, EventArgs e)
            {
                if (WaterMeterDeleteDisplaying == false)
                {
                    waterMeterDelete = new();
                    waterMeterDelete.MdiParent = this;
                    waterMeterDelete.Show();
    
                    WaterMeterDeleteDisplaying = true;
                }
                else
                {
                    waterMeterDelete.BringToFront();
                }
            }
    
            private void miViewCustomers_Click(object sender, EventArgs e)
            {
                if (CustomersDisplaying == false)
                {
                    customers = new Customers.Central();
    
                    customers.MdiParent = this;
                    customers.Show();
    
                    CustomersDisplaying = true;
                }
                else
                {
                    customers.BringToFront();
                }
            }
        }
    }

A Customer Record

.

Practical LearningPractical Learning: Creating a Customer Record

  1. To create a form, in the Solution Explorer, right-click Customers -> Add -> Form(Windows Forms)...
  2. Type Create
  3. Press Enter
  4. Design the form as follows:

    Stellar Water Point - New Customer Account

    Control (Name) Text Other Properties
    Label Label   &Account #:  
    MaskedTextBox Masked Text Box mtbAccountNumber   Masked: 0000-000-0000
    Label Label   &Account Name:  
    TextBox Text Box txtAccountName    
    Label Label   &Meter #:  
    MaskedTextBox Masked Text Box mtbMeterNumber   Masked: 000-000-000
    Button Button btnFindWaterMeter &Find Water Meter  
    Label Label   Meter &Details:  
    TextBox Text Box txtMeterDetails   Enabled: False
    Label Label   &Account Type:  
    ComboBox Combo Box cbxAccountsTypes   Items:
    OTH - Other
    BUS - General Business
    RES - Residential Household
    SGO - Social/Government/Non-Profit Organization
    UUO - Unidentified or Unclassified Type of Organization
    WAT - Water Intensive Business (Laudromat, Hair Salon, Restaurant, etc
    Label Label   &Address:  
    TextBox Text Box txtAddress    
    Label Label   C&ity:  
    TextBox Text Box txtCity    
    Label Label   C&ounty:  
    TextBox Text Box txtCounty    
    Label Label   &State:  
    TextBox Text Box txtState    
    Label Label   &ZIP-Code:  
    MaskedTextBox Masked Text Box mtbZIPCode   Masked: Zip-Code
    Button Button btnSaveCustomerAccount S&ave Customer Account DialogResult: OK
    Button Button btnClose &Close DialogResult: Cancel
  5. On the form, double-click the Find Water Meter button
  6. Change the document as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.Customers
    {
        public partial class Create : Form
        {
            public Create()
            {
                InitializeComponent();
            }
    
            private void btnFindWateMeter_Click(object sender, EventArgs e)
            {
                string strActual = mtbMeterNumber.Text.Replace(" ", "").Replace("-", "");
    
                if (string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a number for a water meter.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                WaterMeter? meter = null;
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        meter = waterMeters.Find(m => m.MeterNumber == mtbMeterNumber.Text)!;
    
                        if (meter is not null)
                        {
                            txtMeterDetails.Text = meter.Make + " " + meter.Model + " (Mtr Size: " + meter.MeterSize + ")";
                        }
                    }
                }
    
                if (meter is null)
                {
                    MessageBox.Show("There is no water meter with that number in our system.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
            }
        }
    }
  7. Return to the form and double-click the S&ave Customer Account button
  8. Return to the form and double-click the &Close button
  9. Change the document as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.Customers
    {
        public partial class Create : Form
        {
            public Create()
            {
                InitializeComponent();
            }
    
            private void btnFindWateMeter_Click(object sender, EventArgs e)
            {
                string strActual = mtbMeterNumber.Text.Replace(" ", "").Replace("-", "");
    
                if (string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a number for a water meter.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                WaterMeter? meter = null;
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        meter = waterMeters.Find(m => m.MeterNumber == mtbMeterNumber.Text)!;
    
                        if (meter is not null)
                        {
                            txtMeterDetails.Text = meter.Make + " " + meter.Model + " (Mtr Size: " + meter.MeterSize + ")";
                        }
                    }
                }
    
                if (meter is null)
                {
                    MessageBox.Show("There is no water meter with that number in our system.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
            }
    
            private void btnSaveCustomerAccount_Click(object sender, EventArgs e)
            {
                string strActual = mtbMeterNumber.Text.Replace(" ", "").Replace("-", "");
    
                if (string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must provide an account number of the customer whose account you are creating. " +
                                    "Otherwise, the new customer account cannot be created.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                List<Customer> clients = new List<Customer>();
                string strCustomers = @"C:\Stellar Water Point8\Customers.xml";
                XmlSerializer xsCustomers = new XmlSerializer(typeof(List<Customer>));
    
                FileInfo fiCustomers = new FileInfo(strCustomers);
    
                if (fiCustomers.Exists == true)
                {
                    using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
                    {
                        clients = (List<Customer>)xsCustomers.Deserialize(trCustomers)!;
                    }
                }
    
                Customer client = new()
                {
                    AccountNumber = mtbAccountNumber.Text,
                    AccountName   = txtAccountName.Text,
                    AccountType   = cbxAccountsTypes.Text,
                    MeterNumber   = mtbMeterNumber.Text,
                    Address       = txtAddress.Text,
                    City          = txtCity.Text,
                    County        = txtCounty.Text,
                    State         = txtState.Text,
                    ZIPCode       = mtbZIPCode.Text
                };
                
                clients.Add(client);
    
                using (TextWriter twCustomers = new StreamWriter(fiCustomers.FullName))
                {
                    xsCustomers.Serialize(twCustomers, clients);
                }
    
                Close();
            }
    
            private void btnClose_Click(object sender, EventArgs e)
            {
                Close();
            }
        }
    }
  10. In the Solution Explorer, right-click WaterDistribution.cs and click View Code
  11. Change the document as follows:
    namespace StellarWaterPoint50
    {
        public partial class WaterDistribution : Form
        {
            public static bool          WaterMetersDisplaying;
            public static bool          WaterMeterCreateDisplaying;
            public static bool          WaterMeterDetailsDisplaying;
            public static bool          WaterMeterEditorDisplaying;
            public static bool          WaterMeterDeleteDisplaying;
    
            private WaterMeters.Central waterMeters;
            private WaterMeters.Create  waterMeterCreate;
            private WaterMeters.Details waterMeterDetails;
            private WaterMeters.Editor  waterMeterEditor;
            private WaterMeters.Delete  waterMeterDelete;
    
            public static bool          CustomersDisplaying;
            public static bool          CustomerCreateDisplaying;
    
            private Customers.Central   customers;
            private Customers.Create    customerCreate;
    
            public WaterDistribution()
            {
                InitializeComponent();
    
                WaterMetersDisplaying       = false;
                WaterMeterCreateDisplaying  = false;
                WaterMeterDetailsDisplaying = false;
                WaterMeterEditorDisplaying  = false;
                WaterMeterDeleteDisplaying  = false;
    
                waterMeters                 = new WaterMeters.Central();
                waterMeterCreate            = new WaterMeters.Create();
                waterMeterDetails           = new WaterMeters.Details();
                waterMeterEditor            = new WaterMeters.Editor();
                waterMeterDelete            = new WaterMeters.Delete();
    
                CustomersDisplaying         = false;
                CustomerCreateDisplaying    = false;
    
                customers                   = new Customers.Central();
                clientCreate                = new Customers.Create();
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            . . .
    
            private void miWaterMetersDetails_Click(object sender, EventArgs e)
            {
                if (WaterMeterDetailsDisplaying == false)
                {
                    waterMeterDetails = new();
                    waterMeterDetails.MdiParent = this;
                    waterMeterDetails.Show();
    
                    WaterMeterDetailsDisplaying = true;
                }
                else
                {
                    waterMeterDetails.BringToFront();
                }
            }
    
            private void miWaterMetersEditor_Click(object sender, EventArgs e)
            {
                if (WaterMeterEditorDisplaying == false)
                {
                    waterMeterEditor = new();
                    waterMeterEditor.MdiParent = this;
                    waterMeterEditor.Show();
    
                    WaterMeterEditorDisplaying = true;
                }
                else
                {
                    waterMeterEditor.BringToFront();
                }
            }
    
            private void miWaterMetersDelete_Click(object sender, EventArgs e)
            {
                if (WaterMeterDeleteDisplaying == false)
                {
                    waterMeterDelete = new();
                    waterMeterDelete.MdiParent = this;
                    waterMeterDelete.Show();
    
                    WaterMeterDeleteDisplaying = true;
                }
                else
                {
                    waterMeterDelete.BringToFront();
                }
            }
    
            private void miViewCustomers_Click(object sender, EventArgs e)
            {
                if (CustomersDisplaying == false)
                {
                    customers = new Customers.Central();
    
                    customers.MdiParent = this;
                    customers.Show();
    
                    CustomersDisplaying = true;
                }
                else
                {
                    customers.BringToFront();
                }
            }
        }
    }
  12. In the Solution Explorer, in the Customers folder, double-click Create
  13. Click an unoccupied area of the form to select it
  14. In the Solution Explorer, click the Events button Events
  15. In the Events section of the Properties window, double-click FormClosing
  16. Implement the event as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.Customers
    {
        public partial class Create : Form
        {
            public Create()
            {
                InitializeComponent();
            }
    
            private void btnFindWateMeter_Click(object sender, EventArgs e)
            {
                string strActual = mtbMeterNumber.Text.Replace(" ", "").Replace("-", "");
    
                if (string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a number for a water meter.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                WaterMeter? meter = null;
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        meter = waterMeters.Find(m => m.MeterNumber == mtbMeterNumber.Text)!;
    
                        if (meter is not null)
                        {
                            txtMeterDetails.Text = meter.Make + " " + meter.Model + " (Mtr Size: " + meter.MeterSize + ")";
                        }
                    }
                }
    
                if (meter is null)
                {
                    MessageBox.Show("There is no water meter with that number in our system.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
            }
    
            private void btnSaveCustomerAccount_Click(object sender, EventArgs e)
            {
                string strActual = mtbMeterNumber.Text.Replace(" ", "").Replace("-", "");
    
                if (string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must provide an account number of the customer whose account you are creating. " +
                                    "Otherwise, the new customer account cannot be created.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                List<Customer> clients = new List<Customer>();
                string strCustomers = @"C:\Stellar Water Point8\Customers.xml";
                XmlSerializer xsCustomers = new XmlSerializer(typeof(List<Customer>));
    
                FileInfo fiCustomers = new FileInfo(strCustomers);
    
                if (fiCustomers.Exists == true)
                {
                    using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
                    {
                        clients = (List<Customer>)xsCustomers.Deserialize(trCustomers)!;
                    }
                }
    
                Customer client = new()
                {
                    AccountNumber = mtbAccountNumber.Text,
                    AccountName   = txtAccountName.Text,
                    AccountType   = cbxAccountsTypes.Text,
                    MeterNumber   = mtbMeterNumber.Text,
                    Address       = txtAddress.Text,
                    City          = txtCity.Text,
                    County        = txtCounty.Text,
                    State         = txtState.Text,
                    ZIPCode       = mtbZIPCode.Text
                };
                
                clients.Add(client);
    
                using (TextWriter twCustomers = new StreamWriter(fiCustomers.FullName))
                {
                    xsCustomers.Serialize(twCustomers, clients);
                }
    
                Close();
            }
    
            private void btnClose_Click(object sender, EventArgs e)
            {
                Close();
            }
    
            private void Create_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (WaterDistribution.CustomerCreateDisplaying == true)
                {
                    WaterDistribution.CustomerCreateDisplaying = false;
                    Close();
                }
            }
        }
    }
  17. In the Solution Explorer, double-click WaterDistribution.cs to display the main form of the application
  18. On the menu that was designed on the form, click Customers and, below it, double-click Setup Water Meter...
  19. Implement the event as follows:
    namespace StellarWaterPoint5
    {
        public partial class WaterDistribution : Form
        {
            public static bool CustomersDisplaying;
            public static bool CustomerCreateDisplaying;
    
            private Customers.Central waterMeters;
            private Customers.Create waterMeterCreate;
    
            public WaterDistribution()
            {
                InitializeComponent();
    
                CustomersDisplaying = false;
                CustomerCreateDisplaying = false;
    
                waterMeters = new Customers.Central();
                waterMeterCreate = new Customers.Create();
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            private void miCustomersViews_Click(object sender, EventArgs e)
            {
                if (CustomersDisplaying == false)
                {
                    waterMeters = new Customers.Central();
    
                    waterMeters.MdiParent = this;
                    waterMeters.Show();
    
                    CustomersDisplaying = true;
                }
                else
                {
                    waterMeters.BringToFront();
                }
            }
    
            private void miCustomersCreate_Click(object sender, EventArgs e)
            {
                if(CustomerCreateDisplaying == false)
                {
                    waterMeterCreate = new();
                    waterMeterCreate.MdiParent = this;
                    waterMeterCreate.Show();
    
                    CustomerCreateDisplaying = true;
                }
                else
                {
                    waterMeterCreate.BringToFront();
                }
            }
        }
    }
  20. To execute, on the main menu, click Debug -> Start Without Debugging:

  21. On the main menu, click Customers and click View Customers Accounts...:

  22. On the main menu, click Customers and click Create Customer Account...:

  23. In the account # text box, type 9279-570-8394
  24. In the meter # text box, type 799-528-461
  25. Click the Find water meter button
  26. Enter the other values as follows:
    Account #:    9279-570-8394
    Account Name: Thomas Stones
    Meter #:      799-528-461
    Account Type: RES - Residential Household
    Address:      10252 Broward Ave #D4
    City:         Frederick
    County:       Frederick
    State:        MD
    ZIP-Code:     21703-4422
  27. Click Save Customer Account
  28. In the same way, create the following two records:
    Account # Account Name Meter # Account Type Address City County State ZIP-Code
    4086-938-4783 Hernola Dough 594-827-359 UUO - Unidentified or Unclassified Type of Organization 10 10 Hexagonal Drv Winston Yoke Penn 11402-4411
    7080-583-5947 Sunny Yard 827-508-248 WAT - Water Intensive Business(Laudromat, Hair Salon, Restaurant, etc 663 Sherry Wood East Street Shimpstown Franklin PA 17236-2626

    Stellar Water Point - Customers

  29. Close the forms and return to your programming environment

The Details of a Customer Account

.

Practical LearningPractical Learning: Viewing the Details of a Customer Account

  1. To create a form, in the Solution Explorer, right-click the Customers folder -> Add -> Form (Windows Forms)...
  2. For the Name of the form, type Details
  3. Press Enter
  4. Design the form as follows:

    Stellar Water Point - New Customer Account

    Control (Name) Text Other Properties
    Label Label   &Account #:  
    MaskedTextBox Masked Text Box mtbAccountNumber   Masked: 0000-000-0000
    Button Button btnFindCustomerAccount &Find Customer Account  
    Label Label   &Account Name:  
    TextBox Text Box txtAccountName   Enabled: False
    Label Label   Meter &Details:  
    TextBox Text Box txtMeterDetails   Enabled: False
    Label Label   &Account Type:  
    TextBox Combo Box txtAccountsTypes   Enabled: False
    Label Label   &Address:  
    TextBox Text Box txtAddress   Enabled: False
    Label Label   C&ity:  
    TextBox Text Box txtCity   Enabled: False
    Label Label   C&ounty:  
    TextBox Text Box txtCounty   Enabled: False
    Label Label   &State:  
    TextBox Text Box txtState   Enabled: False
    Label Label   &ZIP-Code:  
    TextBox Masked Text Box txtZIPCode   Enabled: False
    Button Button btnClose &Close  
  5. On the form, double-click the Find Customer Account button
  6. Return to the form and double-click the Close button
  7. Change the document as follows:
    using StellarWaterPoint50.Models;
    using System.Xml.Serialization;
    
    namespace StellarWaterPoint50.Customers
    {
        public partial class Details : Form
        {
            public Details()
            {
                InitializeComponent();
            }
    
            private void btnFindCustomerAccount_Click(object sender, EventArgs e)
            {
                string strActual = mtbAccountNumber.Text.Replace(" ", "").Replace("-", "");
    
                if (string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a valid account number of " +
                                    "a customer whose account you want to view.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                List<Customer> clients = new List<Customer>();
                string strCustomers = @"C:\Stellar Water Point8\Customers.xml";
                XmlSerializer xsCustomers = new XmlSerializer(typeof(List<Customer>));
    
                FileInfo fiCustomers = new FileInfo(strCustomers);
    
                string? strMeterNumber = string.Empty;
    
                if (fiCustomers.Exists == true)
                {
                    using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
                    {
                        clients = (List<Customer>)xsCustomers.Deserialize(trCustomers)!;
    
                        clients.ForEach(client =>
                        {
                            if (client.AccountNumber == mtbAccountNumber.Text)
                            {
                                txtAccountName.Text = client.AccountName;
                                txtAccountType.Text = client.AccountType;
                                strMeterNumber = client.MeterNumber;
                                txtAddress.Text = client.Address;
                                txtCity.Text = client.City;
                                txtCounty.Text = client.County;
                                txtState.Text = client.State;
                                txtZIPCode.Text = client.ZIPCode;
                            }
                        });
                    }
                }
    
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        WaterMeter? meter = waterMeters.Find(m => m.MeterNumber == strMeterNumber)!;
    
                        if (meter is not null)
                        {
                            txtMeterDetails.Text = meter.Make + " " + meter.Model + " (Mtr Size: " + meter.MeterSize + ")";
                        }
                    }
                }
            }
    
            private void btnClose_Click(object sender, EventArgs e)
            {
                Close();
            }
        }
    }
  8. In the Solution Explorer, right-click WaterDistribution.cs and click View Code
  9. Change the document as follows:
    namespace StellarWaterPoint50
    {
        public partial class WaterDistribution : Form
        {
            public static bool          WaterMetersDisplaying;
            public static bool          WaterMeterCreateDisplaying;
            public static bool          WaterMeterDetailsDisplaying;
            public static bool          WaterMeterEditorDisplaying;
            public static bool          WaterMeterDeleteDisplaying;
    
            private WaterMeters.Central waterMeters;
            private WaterMeters.Create  waterMeterCreate;
            private WaterMeters.Details waterMeterDetails;
            private WaterMeters.Editor  waterMeterEditor;
            private WaterMeters.Delete  waterMeterDelete;
    
            public static bool          CustomersDisplaying;
            public static bool          CustomerCreateDisplaying;
            public static bool          CustomerDetailsDisplaying;
    
            private Customers.Central   customers;
            private Customers.Create    customerCreate;
            private Customers.Details   customerDetails;
    
            public WaterDistribution()
            {
                InitializeComponent();
    
                WaterMetersDisplaying       = false;
                WaterMeterCreateDisplaying  = false;
                WaterMeterDetailsDisplaying = false;
                WaterMeterEditorDisplaying  = false;
                WaterMeterDeleteDisplaying  = false;
    
                waterMeters                 = new WaterMeters.Central();
                waterMeterCreate            = new WaterMeters.Create();
                waterMeterDetails           = new WaterMeters.Details();
                waterMeterEditor            = new WaterMeters.Editor();
                waterMeterDelete            = new WaterMeters.Delete();
    
                CustomersDisplaying         = false;
                CustomerCreateDisplaying    = false;
                CustomerDetailsDisplaying   = false;
    
                customers                   = new Customers.Central();
                customerCreate              = new Customers.Create();
                customerDetails             = new Customers.Details();
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            . . .
        }
    }
  10. In the Solution Explorer, in the Customers folder, double-click Details
  11. Click an unoccupied area of the form to select it
  12. In the Solution Explorer, click the Events button Events
  13. In the Events section of the Properties window, double-click FormClosing
  14. Implement the events as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.Customers
    {
        public partial class Details : Form
        {
            public Details()
            {
                InitializeComponent();
            }
    
            private void btnFindCustomerAccount_Click(object sender, EventArgs e)
            {
                string strActual = mtbAccountNumber.Text.Replace(" ", "").Replace("-", "");
    
                if (string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a valid account number of " +
                                    "a customer whose account you want to view.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                List<Customer> clients    = new List<Customer>();
                string strCustomers       = @"C:\Stellar Water Point8\Customers.xml";
                XmlSerializer xsCustomers = new XmlSerializer(typeof(List<Customer>));
    
                FileInfo fiCustomers      = new FileInfo(strCustomers);
    
                string? strMeterNumber    = string.Empty;
    
                if (fiCustomers.Exists    == true)
                {
                    using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
                    {
                        clients = (List<Customer>)xsCustomers.Deserialize(trCustomers)!;
    
                        clients.ForEach(client =>
                        {
                            if (client.AccountNumber == mtbAccountNumber.Text)
                            {
                                txtAccountName.Text = client.AccountName;
                                txtAccountType.Text = client.AccountType;
                                strMeterNumber      = client.MeterNumber;
                                txtAddress.Text     = client.Address;
                                txtCity.Text        = client.City;
                                txtCounty.Text      = client.County;
                                txtState.Text       = client.State;
                                txtZIPCode.Text     = client.ZIPCode;
                            }
                        });
                    }
                }
    
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        WaterMeter? meter = waterMeters.Find(m => m.MeterNumber == strMeterNumber)!;
    
                        if (meter is not null)
                        {
                            txtMeterDetails.Text = meter.Make + " " + meter.Model + " (Mtr Size: " + meter.MeterSize + ")";
                        }
                    }
                }
            }
    
            private void btnClose_Click(object sender, EventArgs e)
            {
                Close();
            }
    
            private void Details_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (WaterDistribution.CustomerDetailsDisplaying == true)
                {
                    WaterDistribution.CustomerDetailsDisplaying = false;
                    Close();
                }
            }
        }
    }
  15. In the Solution Explorer, double-click WaterDistribution.cs to display the primary form of the application
  16. On the menu bar of the form, click Customers and, below it, double-click Customer Account Details...
  17. Implement the event as follows:
    namespace StellarWaterPoint50
    {
        public partial class WaterDistribution : Form
        {
            public static bool          WaterMetersDisplaying;
            public static bool          WaterMeterCreateDisplaying;
            public static bool          WaterMeterDetailsDisplaying;
            public static bool          WaterMeterEditorDisplaying;
            public static bool          WaterMeterDeleteDisplaying;
    
            private WaterMeters.Central waterMeters;
            private WaterMeters.Create  waterMeterCreate;
            private WaterMeters.Details waterMeterDetails;
            private WaterMeters.Editor  waterMeterEditor;
            private WaterMeters.Delete  waterMeterDelete;
    
            public static bool          CustomersDisplaying;
            public static bool          CustomerCreateDisplaying;
            public static bool          CustomerDetailsDisplaying;
    
            private Customers.Central   customers;
            private Customers.Create    customerCreate;
            private Customers.Details   customerDetails;
    
            public WaterDistribution()
            {
                InitializeComponent();
    
                WaterMetersDisplaying       = false;
                WaterMeterCreateDisplaying  = false;
                WaterMeterDetailsDisplaying = false;
                WaterMeterEditorDisplaying  = false;
                WaterMeterDeleteDisplaying  = false;
    
                waterMeters                 = new WaterMeters.Central();
                waterMeterCreate            = new WaterMeters.Create();
                waterMeterDetails           = new WaterMeters.Details();
                waterMeterEditor            = new WaterMeters.Editor();
                waterMeterDelete            = new WaterMeters.Delete();
    
                CustomersDisplaying         = false;
                CustomerCreateDisplaying    = false;
                CustomerDetailsDisplaying   = false;
    
                customers                   = new Customers.Central();
                customerCreate              = new Customers.Create();
                customerDetails             = new Customers.Details();
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            private void miWindowArrange_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.ArrangeIcons);
            }
    
            private void miWindowCascade_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.Cascade);
            }
    
            private void miWindowTileHorizontal_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.TileHorizontal);
            }
    
            private void miWindowTileVertical_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.TileVertical);
            }
    
            private void miWaterMetersView_Click(object sender, EventArgs e)
            {
                if (WaterMetersDisplaying == false)
                {
                    waterMeters = new WaterMeters.Central();
    
                    waterMeters.MdiParent = this;
                    waterMeters.Show();
    
                    WaterMetersDisplaying = true;
                }
                else
                {
                    waterMeters.BringToFront();
                }
            }
    
            private void miWaterMetersCreate_Click(object sender, EventArgs e)
            {
                if (WaterMeterCreateDisplaying == false)
                {
                    waterMeterCreate = new();
                    waterMeterCreate.MdiParent = this;
                    waterMeterCreate.Show();
    
                    WaterMeterCreateDisplaying = true;
                }
                else
                {
                    waterMeterCreate.BringToFront();
                }
            }
    
            private void miWaterMetersDetails_Click(object sender, EventArgs e)
            {
                if (WaterMeterDetailsDisplaying == false)
                {
                    waterMeterDetails = new();
                    waterMeterDetails.MdiParent = this;
                    waterMeterDetails.Show();
    
                    WaterMeterDetailsDisplaying = true;
                }
                else
                {
                    waterMeterDetails.BringToFront();
                }
            }
    
            private void miWaterMetersEditor_Click(object sender, EventArgs e)
            {
                if (WaterMeterEditorDisplaying == false)
                {
                    waterMeterEditor = new();
                    waterMeterEditor.MdiParent = this;
                    waterMeterEditor.Show();
    
                    WaterMeterEditorDisplaying = true;
                }
                else
                {
                    waterMeterEditor.BringToFront();
                }
            }
    
            private void miWaterMetersDelete_Click(object sender, EventArgs e)
            {
                if (WaterMeterDeleteDisplaying == false)
                {
                    waterMeterDelete = new();
                    waterMeterDelete.MdiParent = this;
                    waterMeterDelete.Show();
    
                    WaterMeterDeleteDisplaying = true;
                }
                else
                {
                    waterMeterDelete.BringToFront();
                }
            }
    
            private void miViewCustomers_Click(object sender, EventArgs e)
            {
                if (CustomersDisplaying == false)
                {
                    customers = new Customers.Central();
    
                    customers.MdiParent = this;
                    customers.Show();
    
                    CustomersDisplaying = true;
                }
                else
                {
                    customers.BringToFront();
                }
            }
    
            private void miCustomersCreate_Click(object sender, EventArgs e)
            {
                if (CustomerCreateDisplaying == false)
                {
                    customerCreate = new();
                    customerCreate.MdiParent = this;
                    customerCreate.Show();
    
                    CustomerCreateDisplaying = true;
                }
                else
                {
                    customerCreate.BringToFront();
                }
            }
    
            private void miCustomersDetails_Click(object sender, EventArgs e)
            {
                if (CustomerDetailsDisplaying == false)
                {
                    customerDetails = new();
                    customerDetails.MdiParent = this;
                    customerDetails.Show();
    
                    CustomerDetailsDisplaying = true;
                }
                else
                {
                    customerDetails.BringToFront();
                }
            }
        }
    }
  18. To execute the application, on the main menu, click Debug -> Start Without Debugging:

  19. On the main menu of the Stellar Water Point form, click Customers and click View Customers Accounts:

    Stellar Water Point - Customers Accounts

  20. Again, on the main menu of the form, click Customers and click Customer Account Details:

    Stellar Water Point - View Water Meter

  21. In the Account # text, type 4086-938-4783
  22. Click the Find Customer Account button:

    Stellar Water Point - View Water Meter

  23. Close the forms and return to your programming environment

Updating a Customer Account

.

Practical LearningPractical Learning: Updating a Customer Account

  1. To create a form, in the Solution Explorer, right-click Customers -> Add -> Form (Windows Forms)...
  2. For the Name of the file, type Editor as the name of the form
  3. Click Add
  4. Design the form as follows:

    Stellar Water Point - Customer Account Editor

    Control (Name) Text Other Properties
    Label Label   &Account #:  
    MaskedTextBox Masked Text Box mtbAccountNumber   Masked: 0000-000-0000
    Button Button btnFindCustomerAccount &Find Customer Account  
    Label Label   &Account Name:  
    TextBox Text Box txtAccountName    
    Label Label   &Meter #:  
    MaskedTextBox Masked Text Box mtbMeterNumber   Masked: 000-000-000
    Button Button btnFindWaterMeter Find &Water Meter  
    Label Label   Meter &Details:  
    TextBox Text Box txtMeterDetails   Enabled: False
    Label Label   &Account Type:  
    ComboBox Combo Box cbxAccountsTypes   Items:
    OTH - Other
    BUS - General Business
    RES - Residential Household
    SGO - Social/Government/Non-Profit Organization
    UUO - Unidentified or Unclassified Type of Organization
    WAT - Water Intensive Business (Laudromat, Hair Salon, Restaurant, etc
    Label Label   &Address:  
    TextBox Text Box txtAddress    
    Label Label   C&ity:  
    TextBox Text Box txtCity    
    Label Label   C&ounty:  
    TextBox Text Box txtCounty    
    Label Label   &State:  
    TextBox Text Box txtState    
    Label Label   &ZIP-Code:  
    MaskedTextBox Masked Text Box mtbZIPCode   Masked: Zip-Code
    Button Button btnUpdateCustomerAccount &Update Customer Account DialogResult: OK
    Button Button btnClose &Close DialogResult: Cancel
  5. On the form, double-click the Find Customer Account button
  6. Change the document as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.Customers
    {
        public partial class Editor : Form
        {
            public Editor()
            {
                InitializeComponent();
            }
    
            private void btnFindCustomerAccount_Click(object sender, EventArgs e)
            {
                string strActual = mtbAccountNumber.Text.Replace(" ", "").Replace("-", "");
    
                if (string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a valid account number of " +
                                    "a customer whose account you want to view.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                List<Customer> clients = new List<Customer>();
                string strCustomers = @"C:\Stellar Water Point8\Customers.xml";
                XmlSerializer xsCustomers = new XmlSerializer(typeof(List<Customer>));
    
                FileInfo fiCustomers = new FileInfo(strCustomers);
    
                string? strMeterNumber = string.Empty;
    
                if (fiCustomers.Exists == true)
                {
                    using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
                    {
                        clients = (List<Customer>)xsCustomers.Deserialize(trCustomers)!;
    
                        clients.ForEach(client =>
                        {
                            if (client.AccountNumber == mtbAccountNumber.Text)
                            {
                                txtAccountName.Text   = client.AccountName;
                                cbxAccountsTypes.Text = client.AccountType;
                                strMeterNumber        = client.MeterNumber;
                                txtAddress.Text       = client.Address;
                                txtCity.Text          = client.City;
                                txtCounty.Text        = client.County;
                                txtState.Text         = client.State;
                                mtbZIPCode.Text       = client.ZIPCode;
                            }
                        });
                    }
                }
    
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        WaterMeter? meter = waterMeters.Find(m => m.MeterNumber == strMeterNumber)!;
    
                        if (meter is not null)
                        {
                            txtMeterDetails.Text = meter.Make + " " + meter.Model + " (Mtr Size: " + meter.MeterSize + ")";
                        }
                    }
                }
            }
        }
    }
  7. Return to the form and double-click the Find Water Meter button
  8. Implement the event as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.Customers
    {
        public partial class Editor : Form
        {
            public Editor()
            {
                InitializeComponent();
            }
    
            private void btnFindCustomerAccount_Click(object sender, EventArgs e)
            {
                string strActual = mtbAccountNumber.Text.Replace(" ", "").Replace("-", "");
    
                if (string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a valid account number of " +
                                    "a customer whose account you want to view.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                List<Customer> clients = new List<Customer>();
                string strCustomers = @"C:\Stellar Water Point8\Customers.xml";
                XmlSerializer xsCustomers = new XmlSerializer(typeof(List<Customer>));
    
                FileInfo fiCustomers = new FileInfo(strCustomers);
    
                string? strMeterNumber = string.Empty;
    
                if (fiCustomers.Exists == true)
                {
                    using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
                    {
                        clients = (List<Customer>)xsCustomers.Deserialize(trCustomers)!;
    
                        clients.ForEach(client =>
                        {
                            if (client.AccountNumber == mtbAccountNumber.Text)
                            {
                                txtAccountName.Text = client.AccountName;
                                cbxAccountsTypes.Text = client.AccountType;
                                mtbMeterNumber.Text = client.MeterNumber;
                                txtAddress.Text = client.Address;
                                txtCity.Text = client.City;
                                txtCounty.Text = client.County;
                                txtState.Text = client.State;
                                mtbZIPCode.Text = client.ZIPCode;
                            }
                        });
                    }
                }
    
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        WaterMeter? meter = waterMeters.Find(m => m.MeterNumber == mtbMeterNumber.Text)!;
    
                        if (meter is not null)
                        {
                            txtMeterDetails.Text = meter.Make + " " + meter.Model + " (Mtr Size: " + meter.MeterSize + ")";
                        }
                    }
                }
            }
    
            private void btnFindWateMeter_Click(object sender, EventArgs e)
            {
                string strActual = mtbMeterNumber.Text.Replace(" ", "").Replace("-", "");
    
                if (string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a number for a water meter.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                WaterMeter? meter = null;
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        meter = waterMeters.Find(m => m.MeterNumber == mtbMeterNumber.Text)!;
    
                        if (meter is not null)
                        {
                            txtMeterDetails.Text = meter.Make + " " + meter.Model + " (Mtr Size: " + meter.MeterSize + ")";
                        }
                    }
                }
    
                if (meter is null)
                {
                    MessageBox.Show("There is no water meter with that number in our system.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
            }
        }
    }
  9. Return to the form and double-click the Update Customer Account button
  10. Return to the form and double-click the Close button
  11. Implement the event as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.Customers
    {
        public partial class Editor : Form
        {
            public Editor()
            {
                InitializeComponent();
            }
    
            private void btnFindCustomerAccount_Click(object sender, EventArgs e)
            {
                string strActual = mtbAccountNumber.Text.Replace(" ", "").Replace("-", "");
    
                if (string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a valid account number of " +
                                    "a customer whose account you want to view.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                List<Customer> clients = new List<Customer>();
                string strCustomers = @"C:\Stellar Water Point8\Customers.xml";
                XmlSerializer xsCustomers = new XmlSerializer(typeof(List<Customer>));
    
                FileInfo fiCustomers = new FileInfo(strCustomers);
    
                string? strMeterNumber = string.Empty;
    
                if (fiCustomers.Exists == true)
                {
                    using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
                    {
                        clients = (List<Customer>)xsCustomers.Deserialize(trCustomers)!;
    
                        clients.ForEach(client =>
                        {
                            if (client.AccountNumber == mtbAccountNumber.Text)
                            {
                                txtAccountName.Text = client.AccountName;
                                cbxAccountsTypes.Text = client.AccountType;
                                mtbMeterNumber.Text = client.MeterNumber;
                                txtAddress.Text = client.Address;
                                txtCity.Text = client.City;
                                txtCounty.Text = client.County;
                                txtState.Text = client.State;
                                mtbZIPCode.Text = client.ZIPCode;
                            }
                        });
                    }
                }
    
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        WaterMeter? meter = waterMeters.Find(m => m.MeterNumber == mtbMeterNumber.Text)!;
    
                        if (meter is not null)
                        {
                            txtMeterDetails.Text = meter.Make + " " + meter.Model + " (Mtr Size: " + meter.MeterSize + ")";
                        }
                    }
                }
            }
    
            private void btnFindWateMeter_Click(object sender, EventArgs e)
            {
                string strActual = mtbMeterNumber.Text.Replace(" ", "").Replace("-", "");
    
                if (string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a number for a water meter.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                WaterMeter? meter = null;
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        meter = waterMeters.Find(m => m.MeterNumber == mtbMeterNumber.Text)!;
    
                        if (meter is not null)
                        {
                            txtMeterDetails.Text = meter.Make + " " + meter.Model + " (Mtr Size: " + meter.MeterSize + ")";
                        }
                    }
                }
    
                if (meter is null)
                {
                    MessageBox.Show("There is no water meter with that number in our system.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
            }
    
            private void btnUpdateCustomerAccount_Click(object sender, EventArgs e)
            {
                string strActual = mtbMeterNumber.Text.Replace(" ", "").Replace("-", "");
    
                if (string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must provide an account number of the customer " +
                                    "whose account you are creating. Then, click the Find Customer Account button.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                List<Customer> clients = new List<Customer>();
                string strCustomers = @"C:\Stellar Water Point8\Customers.xml";
                XmlSerializer xsCustomers = new XmlSerializer(typeof(List<Customer>));
    
                FileInfo fiCustomers = new FileInfo(strCustomers);
    
                if (fiCustomers.Exists == true)
                {
                    using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
                    {
                        clients = (List<Customer>)xsCustomers.Deserialize(trCustomers)!;
    
                        foreach (Customer client in clients)
                        {
                            if (client.AccountNumber == mtbAccountNumber.Text)
                            {
                                client.AccountName   = txtAccountName.Text;
                                client.AccountType   = cbxAccountsTypes.Text;
                                client.MeterNumber   = mtbMeterNumber.Text;
                                client.Address       = txtAddress.Text;
                                client.City          = txtCity.Text;
                                client.County        = txtCounty.Text;
                                client.State         = txtState.Text;
                                client.ZIPCode       = mtbZIPCode.Text;
                            }
                        }
                    }
    
                    using (TextWriter twCustomers = new StreamWriter(fiCustomers.FullName))
                    {
                        xsCustomers.Serialize(twCustomers, clients);
                    }
                }
    
                Close();
            }
    
            private void btnClose_Click(object sender, EventArgs e)
            {
                Close();
            }
        }
    }
  12. In the Solution Explorer, right-click WaterDistribution.cs and click View Code
  13. Change the document as follows:
    namespace StellarWaterPoint50
    {
        public partial class WaterDistribution : Form
        {
            public static bool          WaterMetersDisplaying;
            public static bool          WaterMeterCreateDisplaying;
            public static bool          WaterMeterDetailsDisplaying;
            public static bool          WaterMeterEditorDisplaying;
            public static bool          WaterMeterDeleteDisplaying;
    
            private WaterMeters.Central waterMeters;
            private WaterMeters.Create  waterMeterCreate;
            private WaterMeters.Details waterMeterDetails;
            private WaterMeters.Editor  waterMeterEditor;
            private WaterMeters.Delete  waterMeterDelete;
    
            public static bool          CustomersDisplaying;
            public static bool          CustomerCreateDisplaying;
            public static bool          CustomerDetailsDisplaying;
            public static bool          CustomerEditorDisplaying;
    
            private Customers.Central   customers;
            private Customers.Create    customerCreate;
            private Customers.Details   customerDetails;
            private Customers.Editor    customerEditor;
    
            public WaterDistribution()
            {
                InitializeComponent();
    
                WaterMetersDisplaying       = false;
                WaterMeterCreateDisplaying  = false;
                WaterMeterDetailsDisplaying = false;
                WaterMeterEditorDisplaying  = false;
                WaterMeterDeleteDisplaying  = false;
    
                waterMeters                 = new WaterMeters.Central();
                waterMeterCreate            = new WaterMeters.Create();
                waterMeterDetails           = new WaterMeters.Details();
                waterMeterEditor            = new WaterMeters.Editor();
                waterMeterDelete            = new WaterMeters.Delete();
    
                CustomersDisplaying         = false;
                CustomerCreateDisplaying    = false;
                CustomerDetailsDisplaying   = false;
                CustomerEditorDisplaying    = false;
    
                customers                   = new Customers.Central();
                customerCreate              = new Customers.Create();
                customerDetails             = new Customers.Details();
                customerEditor              = new Customers.Editor();
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            . . .
        }
    }
  14. In the Solution Explorer, in the Customers folder, double-click Editor
  15. Click an unoccupied area of the form to select it
  16. In the Solution Explorer, click the Events button Events
  17. In the Events section of the Properties window, double-click FormClosing
  18. Implement the events as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.Customers
    {
        public partial class Editor : Form
        {
            public Editor()
            {
                InitializeComponent();
            }
    
            private void btnFindCustomerAccount_Click(object sender, EventArgs e)
            {
                string strActual = mtbAccountNumber.Text.Replace(" ", "").Replace("-", "");
    
                if (string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a valid account number of " +
                                    "a customer whose account you want to view.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                List<Customer> clients = new List<Customer>();
                string strCustomers = @"C:\Stellar Water Point8\Customers.xml";
                XmlSerializer xsCustomers = new XmlSerializer(typeof(List<Customer>));
    
                FileInfo fiCustomers = new FileInfo(strCustomers);
    
                string? strMeterNumber = string.Empty;
    
                if (fiCustomers.Exists == true)
                {
                    using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
                    {
                        clients = (List<Customer>)xsCustomers.Deserialize(trCustomers)!;
    
                        clients.ForEach(client =>
                        {
                            if (client.AccountNumber == mtbAccountNumber.Text)
                            {
                                txtAccountName.Text = client.AccountName;
                                cbxAccountsTypes.Text = client.AccountType;
                                mtbMeterNumber.Text = client.MeterNumber;
                                txtAddress.Text = client.Address;
                                txtCity.Text = client.City;
                                txtCounty.Text = client.County;
                                txtState.Text = client.State;
                                mtbZIPCode.Text = client.ZIPCode;
                            }
                        });
                    }
                }
    
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        WaterMeter? meter = waterMeters.Find(m => m.MeterNumber == mtbMeterNumber.Text)!;
    
                        if (meter is not null)
                        {
                            txtMeterDetails.Text = meter.Make + " " + meter.Model + " (Mtr Size: " + meter.MeterSize + ")";
                        }
                    }
                }
            }
    
            private void btnFindWateMeter_Click(object sender, EventArgs e)
            {
                string strActual = mtbMeterNumber.Text.Replace(" ", "").Replace("-", "");
    
                if (string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a number for a water meter.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                WaterMeter? meter = null;
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        meter = waterMeters.Find(m => m.MeterNumber == mtbMeterNumber.Text)!;
    
                        if (meter is not null)
                        {
                            txtMeterDetails.Text = meter.Make + " " + meter.Model + " (Mtr Size: " + meter.MeterSize + ")";
                        }
                    }
                }
    
                if (meter is null)
                {
                    MessageBox.Show("There is no water meter with that number in our system.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
            }
    
            private void btnUpdateCustomerAccount_Click(object sender, EventArgs e)
            {
                string strActual = mtbMeterNumber.Text.Replace(" ", "").Replace("-", "");
    
                if (string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must provide an account number of the customer " +
                                    "whose account you are creating. Then, click the Find Customer Account button.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                List<Customer> clients = new List<Customer>();
                string strCustomers = @"C:\Stellar Water Point8\Customers.xml";
                XmlSerializer xsCustomers = new XmlSerializer(typeof(List<Customer>));
    
                FileInfo fiCustomers = new FileInfo(strCustomers);
    
                if (fiCustomers.Exists == true)
                {
                    using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
                    {
                        clients = (List<Customer>)xsCustomers.Deserialize(trCustomers)!;
    
                        foreach (Customer client in clients)
                        {
                            if (client.AccountNumber == mtbAccountNumber.Text)
                            {
                                client.AccountName   = txtAccountName.Text;
                                client.AccountType   = cbxAccountsTypes.Text;
                                client.MeterNumber   = mtbMeterNumber.Text;
                                client.Address       = txtAddress.Text;
                                client.City          = txtCity.Text;
                                client.County        = txtCounty.Text;
                                client.State         = txtState.Text;
                                client.ZIPCode       = mtbZIPCode.Text;
                            }
                        }
                    }
    
                    using (TextWriter twCustomers = new StreamWriter(fiCustomers.FullName))
                    {
                        xsCustomers.Serialize(twCustomers, clients);
                    }
                }
    
                Close();
            }
    
            private void btnClose_Click(object sender, EventArgs e)
            {
                Close();
            }
    
            private void Editor_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (WaterDistribution.CustomerEditorDisplaying == true)
                {
                    WaterDistribution.CustomerEditorDisplaying = false;
                    Close();
                }
            }
        }
    }
  19. In the Solution Explorer, double-click WaterDistribution.cs to select the main form of the application
  20. On the menu bar of the form, click Water Meters and, below it, double-click Update Customer Account...
  21. Implement the event as follows:
    namespace StellarWaterPoint50
    {
        public partial class WaterDistribution : Form
        {
            public static bool          WaterMetersDisplaying;
            public static bool          WaterMeterCreateDisplaying;
            public static bool          WaterMeterDetailsDisplaying;
            public static bool          WaterMeterEditorDisplaying;
            public static bool          WaterMeterDeleteDisplaying;
    
            private WaterMeters.Central waterMeters;
            private WaterMeters.Create  waterMeterCreate;
            private WaterMeters.Details waterMeterDetails;
            private WaterMeters.Editor  waterMeterEditor;
            private WaterMeters.Delete  waterMeterDelete;
    
            public static bool          CustomersDisplaying;
            public static bool          CustomerCreateDisplaying;
            public static bool          CustomerDetailsDisplaying;
            public static bool          CustomerEditorDisplaying;
    
            private Customers.Central   customers;
            private Customers.Create    customerCreate;
            private Customers.Details   customerDetails;
            private Customers.Editor    customerEditor;
    
            public WaterDistribution()
            {
                InitializeComponent();
    
                WaterMetersDisplaying       = false;
                WaterMeterCreateDisplaying  = false;
                WaterMeterDetailsDisplaying = false;
                WaterMeterEditorDisplaying  = false;
                WaterMeterDeleteDisplaying  = false;
    
                waterMeters                 = new WaterMeters.Central();
                waterMeterCreate            = new WaterMeters.Create();
                waterMeterDetails           = new WaterMeters.Details();
                waterMeterEditor            = new WaterMeters.Editor();
                waterMeterDelete            = new WaterMeters.Delete();
    
                CustomersDisplaying         = false;
                CustomerCreateDisplaying    = false;
                CustomerDetailsDisplaying   = false;
                CustomerEditorDisplaying    = false;
    
                customers                   = new Customers.Central();
                customerCreate              = new Customers.Create();
                customerDetails             = new Customers.Details();
                customerEditor              = new Customers.Editor();
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            private void miWindowArrange_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.ArrangeIcons);
            }
    
            private void miWindowCascade_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.Cascade);
            }
    
            private void miWindowTileHorizontal_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.TileHorizontal);
            }
    
            private void miWindowTileVertical_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.TileVertical);
            }
    
            private void miWaterMetersView_Click(object sender, EventArgs e)
            {
                if (WaterMetersDisplaying == false)
                {
                    waterMeters = new WaterMeters.Central();
    
                    waterMeters.MdiParent = this;
                    waterMeters.Show();
    
                    WaterMetersDisplaying = true;
                }
                else
                {
                    waterMeters.BringToFront();
                }
            }
    
            private void miWaterMetersCreate_Click(object sender, EventArgs e)
            {
                if (WaterMeterCreateDisplaying == false)
                {
                    waterMeterCreate = new();
                    waterMeterCreate.MdiParent = this;
                    waterMeterCreate.Show();
    
                    WaterMeterCreateDisplaying = true;
                }
                else
                {
                    waterMeterCreate.BringToFront();
                }
            }
    
            private void miWaterMetersDetails_Click(object sender, EventArgs e)
            {
                if (WaterMeterDetailsDisplaying == false)
                {
                    waterMeterDetails = new();
                    waterMeterDetails.MdiParent = this;
                    waterMeterDetails.Show();
    
                    WaterMeterDetailsDisplaying = true;
                }
                else
                {
                    waterMeterDetails.BringToFront();
                }
            }
    
            private void miWaterMetersEditor_Click(object sender, EventArgs e)
            {
                if (WaterMeterEditorDisplaying == false)
                {
                    waterMeterEditor = new();
                    waterMeterEditor.MdiParent = this;
                    waterMeterEditor.Show();
    
                    WaterMeterEditorDisplaying = true;
                }
                else
                {
                    waterMeterEditor.BringToFront();
                }
            }
    
            private void miWaterMetersDelete_Click(object sender, EventArgs e)
            {
                if (WaterMeterDeleteDisplaying == false)
                {
                    waterMeterDelete = new();
                    waterMeterDelete.MdiParent = this;
                    waterMeterDelete.Show();
    
                    WaterMeterDeleteDisplaying = true;
                }
                else
                {
                    waterMeterDelete.BringToFront();
                }
            }
    
            private void miViewCustomers_Click(object sender, EventArgs e)
            {
                if (CustomersDisplaying == false)
                {
                    customers = new Customers.Central();
    
                    customers.MdiParent = this;
                    customers.Show();
    
                    CustomersDisplaying = true;
                }
                else
                {
                    customers.BringToFront();
                }
            }
    
            private void miCustomersCreate_Click(object sender, EventArgs e)
            {
                if (CustomerCreateDisplaying == false)
                {
                    customerCreate = new();
                    customerCreate.MdiParent = this;
                    customerCreate.Show();
    
                    CustomerCreateDisplaying = true;
                }
                else
                {
                    customerCreate.BringToFront();
                }
            }
    
            private void miCustomersDetails_Click(object sender, EventArgs e)
            {
                if (CustomerDetailsDisplaying == false)
                {
                    customerDetails = new();
                    customerDetails.MdiParent = this;
                    customerDetails.Show();
    
                    CustomerDetailsDisplaying = true;
                }
                else
                {
                    customerDetails.BringToFront();
                }
            }
    
            private void miCustomersEditor_Click(object sender, EventArgs e)
            {
                if (CustomerEditorDisplaying == false)
                {
                    customerEditor = new();
                    customerEditor.MdiParent = this;
                    customerEditor.Show();
    
                    CustomerEditorDisplaying = true;
                }
                else
                {
                    customerEditor.BringToFront();
                }
            }
        }
    }
  22. To execute the application, on the main menu, click Debug -> Start Without Debugging

  23. On the main menu of the central form of the application, click Customers and click View Customers Accounts

    Stellar Water Point - Customer Accounts

  24. On the main menu of the central form of the application, click Customers and click Update Customer Account

    Stellar Water Point - Water Meters

  25. In the Account # text, type 4086-938-4783
  26. Click the Find Customer Account button
  27. Change the values as follows:
    Account Name: Bernotte Doughnuts
    Meter #:      580-742-825 and click Find Water Meter
    Account Type: BUS	- General Business
    Address:      10103 Hexagon Drive
    City:         Winterstown
    County:       York
    State:        PA
    ZIP-Code:     17402-8828

    Stellar Water Point - New Water Meter

  28. Click the Update Customer Account button:

    Stellar Water Point - Water Meters

  29. Close the forms and return to your programming environment

Deleting a Customer Account

.

Practical LearningPractical Learning: Deleting a Customer Account

  1. To create a form, in the Solution Explorer, right-click Customers -> Add -> Form(Windows Forms)...
  2. In the Name text box, replace the string with Delete as the name of the form
  3. Press Enter
  4. Design the form as follows:

    Stellar Water Point - Customer Account Deletion

    Control (Name) Text Other Properties
    Label Label   &Account #:  
    MaskedTextBox Masked Text Box mtbAccountNumber   Masked: 0000-000-0000
    Button Button btnFindCustomerAccount &Find Customer Account  
    Label Label   &Account Name:  
    TextBox Text Box txtAccountName   Enabled: False
    Label Label   Meter &Details:  
    TextBox Text Box txtMeterDetails   Enabled: False
    Label Label   &Account Type:  
    TextBox Combo Box txtAccountsTypes   Enabled: False
    Label Label   &Address:  
    TextBox Text Box txtAddress   Enabled: False
    Label Label   C&ity:  
    TextBox Text Box txtCity   Enabled: False
    Label Label   C&ounty:  
    TextBox Text Box txtCounty   Enabled: False
    Label Label   &State:  
    TextBox Text Box txtState   Enabled: False
    Label Label   &ZIP-Code:  
    TextBox Masked Text Box txtZIPCode   Enabled: False
    Button Button btnDeleteCustomerAccount &Delete Customer Account  
    Button Button btnClose &Close  
  5. On the form, double-click the Find Customer Account button
  6. Change the document as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.Customers
    {
        public partial class Delete: Form
        {
            public Delete()
            {
                InitializeComponent();
            }
    
            private void btnFindCustomerAccount_Click(object sender, EventArgs e)
            {
                string strActual = mtbAccountNumber.Text.Replace(" ", "").Replace("-", "");
    
                if (string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a valid account number of " +
                                    "a customer whose account you want to view.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                List<Customer> clients = new List<Customer>();
                string strCustomers = @"C:\Stellar Water Point8\Customers.xml";
                XmlSerializer xsCustomers = new XmlSerializer(typeof(List<Customer>));
    
                FileInfo fiCustomers = new FileInfo(strCustomers);
    
                string? strMeterNumber = string.Empty;
    
                if (fiCustomers.Exists == true)
                {
                    using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
                    {
                        clients = (List<Customer>)xsCustomers.Deserialize(trCustomers)!;
    
                        clients.ForEach(client =>
                        {
                            if (client.AccountNumber == mtbAccountNumber.Text)
                            {
                                txtAccountName.Text = client.AccountName;
                                txtAccountType.Text = client.AccountType;
                                strMeterNumber = client.MeterNumber;
                                txtAddress.Text = client.Address;
                                txtCity.Text = client.City;
                                txtCounty.Text = client.County;
                                txtState.Text = client.State;
                                txtZIPCode.Text = client.ZIPCode;
                            }
                        });
                    }
                }
    
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        WaterMeter? meter = waterMeters.Find(m => m.MeterNumber == strMeterNumber)!;
    
                        if (meter is not null)
                        {
                            txtMeterDetails.Text = meter.Make + " " + meter.Model + " (Mtr Size: " + meter.MeterSize + ")";
                        }
                    }
                }
            }
        }
    }
  7. Return to the form and double-click the Delete Customer Account button
  8. Return to the form and double-click the Close button
  9. Implement the events as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.Customers
    {
        public partial class Delete : Form
        {
            public Delete()
            {
                InitializeComponent();
            }
    
            private void btnFindCustomerAccount_Click(object sender, EventArgs e)
            {
                string strActual = mtbAccountNumber.Text.Replace(" ", "").Replace("-", "");
    
                if (string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must provide the account number of " +
                                    "the customer to delete.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                List<Customer> clients = new List<Customer>();
                string strCustomers = @"C:\Stellar Water Point8\Customers.xml";
                XmlSerializer xsCustomers = new XmlSerializer(typeof(List<Customer>));
    
                FileInfo fiCustomers = new FileInfo(strCustomers);
    
                string? strMeterNumber = string.Empty;
    
                if (fiCustomers.Exists == true)
                {
                    using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
                    {
                        clients = (List<Customer>)xsCustomers.Deserialize(trCustomers)!;
    
                        clients.ForEach(client =>
                        {
                            if (client.AccountNumber == mtbAccountNumber.Text)
                            {
                                txtAccountName.Text = client.AccountName;
                                txtAccountType.Text = client.AccountType;
                                strMeterNumber      = client.MeterNumber;
                                txtAddress.Text     = client.Address;
                                txtCity.Text        = client.City;
                                txtCounty.Text      = client.County;
                                txtState.Text       = client.State;
                                txtZIPCode.Text     = client.ZIPCode;
                            }
                        });
                    }
                }
    
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        WaterMeter? meter = waterMeters.Find(m => m.MeterNumber == strMeterNumber)!;
    
                        if (meter is not null)
                        {
                            txtMeterDetails.Text = meter.Make + " " + meter.Model + " (Mtr Size: " + meter.MeterSize + ")";
                        }
                    }
                }
            }
    
            private void btnDeleteCustomerAccount_Click(object sender, EventArgs e)
            {
                string strActual = mtbAccountNumber.Text.Replace(" ", "").Replace("-", "");
    
                if (string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a valid account number of " +
                                    "a customer whose account you want to remove.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                List<Customer> clients = new List<Customer>();
                string strCustomers = @"C:\Stellar Water Point8\Customers.xml";
                XmlSerializer xsCustomers = new XmlSerializer(typeof(List<Customer>));
    
                FileInfo fiCustomers = new FileInfo(strCustomers);
    
                string? strMeterNumber = string.Empty;
    
                if (fiCustomers.Exists == true)
                {
                    using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
                    {
                        clients = (List<Customer>)xsCustomers.Deserialize(trCustomers)!;
    
                        foreach(Customer client in clients)
                        {
                            if (client.AccountNumber == mtbAccountNumber.Text)
                            {
                                clients.Remove(client);
                                break;
                            }
                        }
                    }
    
                    using (TextWriter twCustomers = new StreamWriter(fiCustomers.FullName))
                    {
                        xsCustomers.Serialize(twCustomers, clients);
                    }
                }
                
                Close();
            }
    
            private void btnClose_Click(object sender, EventArgs e)
            {
                Close();
            }
        }
    }
  10. In the Solution Explorer, right-click WaterDistribution.cs and click View Code
  11. Change the document as follows:
    namespace StellarWaterPoint50
    {
        public partial class WaterDistribution : Form
        {
            public static bool          WaterMetersDisplaying;
            public static bool          WaterMeterCreateDisplaying;
            public static bool          WaterMeterDetailsDisplaying;
            public static bool          WaterMeterEditorDisplaying;
            public static bool          WaterMeterDeleteDisplaying;
    
            private WaterMeters.Central waterMeters;
            private WaterMeters.Create  waterMeterCreate;
            private WaterMeters.Details waterMeterDetails;
            private WaterMeters.Editor  waterMeterEditor;
            private WaterMeters.Delete  waterMeterDelete;
    
            public static bool          CustomersDisplaying;
            public static bool          CustomerCreateDisplaying;
            public static bool          CustomerDetailsDisplaying;
            public static bool          CustomerEditorDisplaying;
            public static bool          CustomerDeleteDisplaying;
    
            private Customers.Central   customers;
            private Customers.Create    customerCreate;
            private Customers.Details   customerDetails;
            private Customers.Editor    customerEditor;
            private Customers.Delete    customerDelete;
    
            public WaterDistribution()
            {
                InitializeComponent();
    
                WaterMetersDisplaying       = false;
                WaterMeterCreateDisplaying  = false;
                WaterMeterDetailsDisplaying = false;
                WaterMeterEditorDisplaying  = false;
                WaterMeterDeleteDisplaying  = false;
    
                waterMeters                 = new WaterMeters.Central();
                waterMeterCreate            = new WaterMeters.Create();
                waterMeterDetails           = new WaterMeters.Details();
                waterMeterEditor            = new WaterMeters.Editor();
                waterMeterDelete            = new WaterMeters.Delete();
    
                CustomersDisplaying         = false;
                CustomerCreateDisplaying    = false;
                CustomerDetailsDisplaying   = false;
                CustomerEditorDisplaying    = false;
                CustomerDeleteDisplaying    = false;
    
                customers                   = new Customers.Central();
                customerCreate              = new Customers.Create();
                customerDetails             = new Customers.Details();
                customerEditor              = new Customers.Editor();
                customerDelete              = new Customers.Delete();
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            . . .
        }
    }
  12. In the Solution Explorer, in the Customers folder, double-click Delete
  13. Click an unoccupied area of the form to select it
  14. In the Solution Explorer, click the Events button Events
  15. In the Events section of the Properties window, double-click FormClosing
  16. Implement the events as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.Customers
    {
        public partial class Delete : Form
        {
            public Delete()
            {
                InitializeComponent();
            }
    
            private void btnFindCustomerAccount_Click(object sender, EventArgs e)
            {
                string strActual = mtbAccountNumber.Text.Replace(" ", "").Replace("-", "");
    
                if (string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must provide the account number of " +
                                    "the customer to delete.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                List<Customer> clients = new List<Customer>();
                string strCustomers = @"C:\Stellar Water Point8\Customers.xml";
                XmlSerializer xsCustomers = new XmlSerializer(typeof(List<Customer>));
    
                FileInfo fiCustomers = new FileInfo(strCustomers);
    
                string? strMeterNumber = string.Empty;
    
                if (fiCustomers.Exists == true)
                {
                    using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
                    {
                        clients = (List<Customer>)xsCustomers.Deserialize(trCustomers)!;
    
                        clients.ForEach(client =>
                        {
                            if (client.AccountNumber == mtbAccountNumber.Text)
                            {
                                txtAccountName.Text = client.AccountName;
                                txtAccountType.Text = client.AccountType;
                                strMeterNumber = client.MeterNumber;
                                txtAddress.Text = client.Address;
                                txtCity.Text = client.City;
                                txtCounty.Text = client.County;
                                txtState.Text = client.State;
                                txtZIPCode.Text = client.ZIPCode;
                            }
                        });
                    }
                }
    
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        WaterMeter? meter = waterMeters.Find(m => m.MeterNumber == strMeterNumber)!;
    
                        if (meter is not null)
                        {
                            txtMeterDetails.Text = meter.Make + " " + meter.Model + " (Mtr Size: " + meter.MeterSize + ")";
                        }
                    }
                }
            }
    
            private void btnDeleteCustomerAccount_Click(object sender, EventArgs e)
            {
                string strActual = mtbAccountNumber.Text.Replace(" ", "").Replace("-", "");
    
                if (string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a valid account number of " +
                                    "a customer whose account you want to remove.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                List<Customer> clients = new List<Customer>();
                string strCustomers = @"C:\Stellar Water Point8\Customers.xml";
                XmlSerializer xsCustomers = new XmlSerializer(typeof(List<Customer>));
    
                FileInfo fiCustomers = new FileInfo(strCustomers);
    
                string? strMeterNumber = string.Empty;
    
                if (fiCustomers.Exists == true)
                {
                    using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
                    {
                        clients = (List<Customer>)xsCustomers.Deserialize(trCustomers)!;
    
                        foreach (Customer client in clients)
                        {
                            if (client.AccountNumber == mtbAccountNumber.Text)
                            {
                                clients.Remove(client);
                                break;
                            }
                        }
                    }
    
                    using (TextWriter twCustomers = new StreamWriter(fiCustomers.FullName))
                    {
                        xsCustomers.Serialize(twCustomers, clients);
                    }
                }
    
                Close();
            }
    
            private void btnClose_Click(object sender, EventArgs e)
            {
                Close();
            }
    
            private void Delete_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (WaterDistribution.CustomerDeleteDisplaying == true)
                {
                    WaterDistribution.CustomerDeleteDisplaying = false;
                    Close();
                }
            }
        }
    }
  17. In the Solution Explorer, double-click WaterDistribution.cs to display the central form of the application
  18. On the menu bar of the form, click Customers and, below it, double-click Delete Customer Account...
  19. Implement the event as follows:
    namespace StellarWaterPoint50
    {
        public partial class WaterDistribution : Form
        {
            public static bool          WaterMetersDisplaying;
            public static bool          WaterMeterCreateDisplaying;
            public static bool          WaterMeterDetailsDisplaying;
            public static bool          WaterMeterEditorDisplaying;
            public static bool          WaterMeterDeleteDisplaying;
    
            private WaterMeters.Central waterMeters;
            private WaterMeters.Create  waterMeterCreate;
            private WaterMeters.Details waterMeterDetails;
            private WaterMeters.Editor  waterMeterEditor;
            private WaterMeters.Delete  waterMeterDelete;
    
            public static bool          CustomersDisplaying;
            public static bool          CustomerCreateDisplaying;
            public static bool          CustomerDetailsDisplaying;
            public static bool          CustomerEditorDisplaying;
            public static bool          CustomerDeleteDisplaying;
    
            private Customers.Central   customers;
            private Customers.Create    customerCreate;
            private Customers.Details   customerDetails;
            private Customers.Editor    customerEditor;
            private Customers.Delete    customerDelete;
    
            public WaterDistribution()
            {
                InitializeComponent();
    
                WaterMetersDisplaying       = false;
                WaterMeterCreateDisplaying  = false;
                WaterMeterDetailsDisplaying = false;
                WaterMeterEditorDisplaying  = false;
                WaterMeterDeleteDisplaying  = false;
    
                waterMeters                 = new WaterMeters.Central();
                waterMeterCreate            = new WaterMeters.Create();
                waterMeterDetails           = new WaterMeters.Details();
                waterMeterEditor            = new WaterMeters.Editor();
                waterMeterDelete            = new WaterMeters.Delete();
    
                CustomersDisplaying         = false;
                CustomerCreateDisplaying    = false;
                CustomerDetailsDisplaying   = false;
                CustomerEditorDisplaying    = false;
                CustomerDeleteDisplaying    = false;
    
                customers                   = new Customers.Central();
                customerCreate              = new Customers.Create();
                customerDetails             = new Customers.Details();
                customerEditor              = new Customers.Editor();
                customerDelete              = new Customers.Delete();
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            private void miWindowArrange_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.ArrangeIcons);
            }
    
            private void miWindowCascade_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.Cascade);
            }
    
            private void miWindowTileHorizontal_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.TileHorizontal);
            }
    
            private void miWindowTileVertical_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.TileVertical);
            }
    
            private void miWaterMetersView_Click(object sender, EventArgs e)
            {
                if (WaterMetersDisplaying == false)
                {
                    waterMeters = new WaterMeters.Central();
    
                    waterMeters.MdiParent = this;
                    waterMeters.Show();
    
                    WaterMetersDisplaying = true;
                }
                else
                {
                    waterMeters.BringToFront();
                }
            }
    
            private void miWaterMetersCreate_Click(object sender, EventArgs e)
            {
                if (WaterMeterCreateDisplaying == false)
                {
                    waterMeterCreate = new();
                    waterMeterCreate.MdiParent = this;
                    waterMeterCreate.Show();
    
                    WaterMeterCreateDisplaying = true;
                }
                else
                {
                    waterMeterCreate.BringToFront();
                }
            }
    
            private void miWaterMetersDetails_Click(object sender, EventArgs e)
            {
                if (WaterMeterDetailsDisplaying == false)
                {
                    waterMeterDetails = new();
                    waterMeterDetails.MdiParent = this;
                    waterMeterDetails.Show();
    
                    WaterMeterDetailsDisplaying = true;
                }
                else
                {
                    waterMeterDetails.BringToFront();
                }
            }
    
            private void miWaterMetersEditor_Click(object sender, EventArgs e)
            {
                if (WaterMeterEditorDisplaying == false)
                {
                    waterMeterEditor = new();
                    waterMeterEditor.MdiParent = this;
                    waterMeterEditor.Show();
    
                    WaterMeterEditorDisplaying = true;
                }
                else
                {
                    waterMeterEditor.BringToFront();
                }
            }
    
            private void miWaterMetersDelete_Click(object sender, EventArgs e)
            {
                if (WaterMeterDeleteDisplaying == false)
                {
                    waterMeterDelete = new();
                    waterMeterDelete.MdiParent = this;
                    waterMeterDelete.Show();
    
                    WaterMeterDeleteDisplaying = true;
                }
                else
                {
                    waterMeterDelete.BringToFront();
                }
            }
    
            private void miViewCustomers_Click(object sender, EventArgs e)
            {
                if (CustomersDisplaying == false)
                {
                    customers = new Customers.Central();
    
                    customers.MdiParent = this;
                    customers.Show();
    
                    CustomersDisplaying = true;
                }
                else
                {
                    customers.BringToFront();
                }
            }
    
            private void miCustomersCreate_Click(object sender, EventArgs e)
            {
                if (CustomerCreateDisplaying == false)
                {
                    customerCreate = new();
                    customerCreate.MdiParent = this;
                    customerCreate.Show();
    
                    CustomerCreateDisplaying = true;
                }
                else
                {
                    customerCreate.BringToFront();
                }
            }
    
            private void miCustomersDetails_Click(object sender, EventArgs e)
            {
                if (CustomerDetailsDisplaying == false)
                {
                    customerDetails = new();
                    customerDetails.MdiParent = this;
                    customerDetails.Show();
    
                    CustomerDetailsDisplaying = true;
                }
                else
                {
                    customerDetails.BringToFront();
                }
            }
    
            private void miCustomersEditor_Click(object sender, EventArgs e)
            {
                if (CustomerEditorDisplaying == false)
                {
                    customerEditor = new();
                    customerEditor.MdiParent = this;
                    customerEditor.Show();
    
                    CustomerEditorDisplaying = true;
                }
                else
                {
                    customerEditor.BringToFront();
                }
            }
    
            private void miCustomersDelete_Click(object sender, EventArgs e)
            {
                if (CustomerDeleteDisplaying == false)
                {
                    customerDelete = new();
                    customerDelete.MdiParent = this;
                    customerDelete.Show();
    
                    CustomerDeleteDisplaying = true;
                }
                else
                {
                    customerDelete.BringToFront();
                }
            }
        }
    }
  20. To execute the application, on the main menu, click Debug -> Start Without Debugging

  21. On the main menu of the central form of the application, click Customers and click View Customers Accounts

    Stellar Water Point - Customers Accounts

  22. On the main menu of the central form of the application, click Customers and click Delete Customer Account

    Stellar Water Point - Customers Accounts

  23. In the Account # text box, type 4086-938-4783
  24. Click the Find Customer Account button:

    Stellar Water Point - Customer Account Deletion

  25. Click the Delete Customer Account button
  26. Read the text on the message box.
    On the message box, click Yes
  27. In the same way, delete one of the other two records
  28. Close the forms and return to your programming environment
  29. From the Windows Explorer, open the Customers.xml file
  30. Replace the content of the file with the provided file
  31. Save the file
  32. Return to your programming environment

Water Bills

Introduction

.

Practical LearningPractical Learning: Starting Water Meters Issues

  1. To create a class, in the Solution Explorer, right-click Models -> Add -> Class...
  2. Type WaterBillManagement as the Name of the file
  3. Click Add
  4. Define the class as follows:
    namespace StellarWaterPoint31.Models
    {
        internal static class WaterBillManagement
        {
            internal static (double a, double b, double c) CalculateTiers(string acnt, double total)
            {
                (double tier1, double tier2, double tier3) results = (0.00, 0.00, 0.00);
    
                if (acnt == "RES")
                {
                    results.tier1 = total * 41.50 / 10000.00;
                    results.tier2 = total * 32.50 / 10000.00;
                    results.tier3 = total * 26.00 / 10000.00;
                }
                else if (acnt == "SGO")
                {
                    results.tier1 = total * 46.00 / 10000.00;
                    results.tier2 = total * 50.00 / 10000.00;
                    results.tier3 = total * 4.00  / 10000.00;
                }
                else if (acnt == "BUS")
                {
                    results.tier1 = total * 45.00 / 10000.00;
                    results.tier2 = total * 30.00 / 10000.00;
                    results.tier3 = total * 25.00 / 10000.00;
                }
                else if (acnt == "UUO")
                {
                    results.tier1 = total * 25.00 / 10000.00;
                    results.tier2 = total * 35.00 / 10000.00;
                    results.tier3 = total * 40.00 / 10000.00;
                }
                else if (acnt == "WAT")
                {
                    results.tier1 = total * 50.00 / 10000.00;
                    results.tier2 = total * 40.00 / 10000.00;
                    results.tier3 = total * 10.00 / 10000.00;
                }
                else
                {
                    results.tier1 = total * (48.00 / 10000.00);
                    results.tier2 = total * (32.00 / 10000.00);
                    results.tier3 = total * (20.00 / 10000.00);
                }
    
                return results;
            }
    
            internal static double CalculateSewerCharges(string acnt, double total)
            {
                double result;
    
                if (acnt == "RES")
                {
                    result = total * 6.826941 / 100.00;
                }
                else if (acnt == "SGO")
                {
                    result = total * 4.162522 / 100.00;
                }
                else if (acnt == "BUS")
                {
                    result = total * 8.315136 / 100.00;
                }
                else if (acnt == "UUO")
                {
                    result = total * 10.626147 / 100.00;
                }
                else if (acnt == "WAT")
                {
                    result = total * 12.025135 / 100.00;
                }
                else // if (acnt == "OTH")
                {
                    result = total * 9.202615 / 100.00;
                }
    
                return result;
            }
    
            internal static double CalculateEnvironmentCharges(string acnt, double total)
            {
                double result;
    
                switch (acnt)
                {
                    case "RES":
                        result = total * 0.022724;
                        break;
                    case "SGO":
                        result = total * 0.118242;
                        break;
                    case "BUS":
                        result = total * 0.161369;
                        break;
                    case "UUO":
                        result = total * 0.082477;
                        break;
                    case "WAT":
                        result = total * 0.413574;
                        break;
                    default:
                        result = total * 0.221842;
                        break;
                }
    
                return result;
            }
    
            internal static double CalculateServiceCharges(string acnt, double total)
            {
                switch (acnt)
                {
                    case "RES":
                        return total * 0.145748;
                    case "SGO":
                        return total * 0.102246;
                    case "BUS":
                        return total * 0.242627;
                    case "UUO":
                        return total * 0.186692;
                    case "WAT":
                        return total * 0.412628;
                    default:
                        return total * 0.210248;
                }
            }
    
            internal static double CalculateLocalTaxes(string acnt, double total) => acnt switch
            {
                "RES" => total * 0.031574,
                "SGO" => total * 0.035026,
                "BUS" => total * 0.122517,
                "UUO" => total * 0.105737,
                "WAT" => total * 0.153248,
                _     => total * 0.125148
            };
    
            internal static double CalculateStateTaxes(string acnt, double total) => acnt switch
            {
                "RES" => total * 0.01724,
                "SGO" => total * 0.008779,
                "BUS" => total * 0.042448,
                "UUO" => total * 0.067958,
                "WAT" => total * 0.081622,
                _     => total * 0.013746
            };
    
            internal static DateTime SetPaymentDueDate(string acnt, DateTime date)
            {
                TimeSpan tsPaymentDueDate = new TimeSpan(1, 0, 0, 0);
    
                if (acnt == "RES")
                {
                    tsPaymentDueDate = new TimeSpan(15, 0, 0, 0);
                }
                else if (acnt == "SGO")
                {
                    tsPaymentDueDate = new TimeSpan(20, 0, 0, 0);
                }
                else if (acnt == "BUS")
                {
                    tsPaymentDueDate = new TimeSpan(30, 0, 0, 0);
                }
                else if (acnt == "UUO")
                {
                    tsPaymentDueDate = new TimeSpan(25, 0, 0, 0);
                }
                else if (acnt == "WAT")
                {
                    tsPaymentDueDate = new TimeSpan(40, 0, 0, 0);
                }
                else
                {
                    tsPaymentDueDate = new TimeSpan(35, 0, 0, 0);
                }
    
                return date + tsPaymentDueDate;
            }
    
            internal static DateTime SetLatePaymentDueDate(string acnt, DateTime date)
            {
                switch (acnt)
                {
                    case "RES":
                        return date + new TimeSpan(30, 0, 0, 0);
                    case "SGO":
                        return date + new TimeSpan(40, 0, 0, 0);
                    case "BUS":
                        return date + new TimeSpan(50, 0, 0, 0);
                    case "UUO":
                        return date + new TimeSpan(60, 0, 0, 0);
                    case "WAT":
                        return date + new TimeSpan(65, 0, 0, 0);
                    default:
                        return date + new TimeSpan(45, 0, 0, 0);
                }
            }
    
            internal static double CalculateLateAmountDue(string acnt, double amt) => acnt switch
            {
                "RES" => amt + 8.95,
                "SGO" => amt + (amt / 4.575),
                "BUS" => amt + (amt / 12.315),
                "UUO" => amt + (amt / 7.425),
                "WAT" => amt + (amt / 15.225),
                _     => amt + (amt / 6.735)
            };
        }
    }
  5. To create a class, in the Solution Explorer, right-click Models -> Add -> Class...
  6. On the main menu, click Project -> Add Class...
  7. Replace the name with WaterBill
  8. Click Add
  9. Change the code as follows:
    namespace StellarWaterPoint50.Models
    {
        public record WaterBill
        {
            public string?  BillNumber            { get; set; }
            public string?  AccountNumber         { get; set; }
            public DateTime MeterReadingStartDate { get; set; }
            public DateTime MeterReadingEndDate   { get; set; }
            public int      BillingDays           { get; set; }
            public int      CounterReadingStart   { get; set; }
            public int      CounterReadingEnd     { get; set; }
            public int      TotalHCF              { get; set; }
            public int      TotalGallons          { get; set; }
            public double   FirstTierConsumption  { get; set; }
            public double   SecondTierConsumption { get; set; }
            public double   LastTierConsumption   { get; set; }
            public double   WaterCharges          { get; set; }
            public double   SewerCharges          { get; set; }
            public double   EnvironmentCharges    { get; set; }
            public double   ServiceCharges        { get; set; }
            public double   TotalCharges          { get; set; }
            public double   LocalTaxes            { get; set; }
            public double   StateTaxes            { get; set; }
            public DateTime PaymentDueDate        { get; set; }
            public double   AmountDue             { get; set; }
            public DateTime LatePaymentDueDate    { get; set; }
            public double   LateAmountDue         { get; set; }
        }
    }
  10. In the Solution Explorer, right-click StellarWaterPoint1 -> Add -> New Folder
  11. Type WaterBills as the name of the folder

Displaying Water Bills

.

Practical LearningPractical Learning: Displaying Water Bills

  1. To create a form, in the Solution Explorer, right-click WaterBills -> Add -> Form (Windows Forms)...
  2. For the Name of the form, type Central
  3. Click Add
  4. In the Toolbox, click the ListView button and click the form
  5. On the form, right-click the list view and click Edit Columns...
  6. Create the columns as follows:
    (Name) Text TextAlign Width
    colWaterBillId Id   40
    colBillNumber Bill # Center 80
    colAccountSummary Account Summary Center 550
    colStartDate Start Date Center 150
    colEndDate End Date Center 150
    colBillingDays Days Center  
    colCounterStart Counter Start Right 125
    colCounterEnd Counter End Right 125
    colTotalHCF Total HCF Right 100
    colGallons Gallons Right 95
    colPaymentDueDate Pmt Due Date Center 125
    colAmountDue Amt Due Right 90
  7. Click OK
  8. Position and resize the list view on the form as follows:

    Stellar Water Point - Water Meters

    Control (Name) Other Properties
    ListView List View lvwWaterBills FullRowSelect: True
    GridLines: True
    View: Details
  9. Click an unoccupied area of the form to select it
  10. In the Solution Explorer, click the Events button Events
  11. In the Events section of the Properties window, double-click Activated
  12. Change the document as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.WaterBills
    {
        public partial class Central : Form
        {
            public Central()
            {
                InitializeComponent();
            }
    
            private void ShowWaterBills()
            {
                List<Customer> clients = new List<Customer>();
                string strCustomers = @"C:\Stellar Water Point8\Customers.xml";
                XmlSerializer xsCustomers = new XmlSerializer(typeof(List<Customer>));
    
                FileInfo fiCustomers = new FileInfo(strCustomers);
    
                if (fiCustomers.Exists == true)
                {
                    using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
                    {
                        clients = (List<Customer>)xsCustomers.Deserialize(trCustomers)!;
                    }
                }
    
                string strWaterBills = string.Empty;
                List<WaterBill> bills = new List<WaterBill>();
                string fileWaterBills = @"C:\Stellar Water Point8\WaterBills.xml";
                XmlSerializer xsWaterBills = new XmlSerializer(typeof(List<WaterBill>));
    
                FileInfo fiWaterBills = new FileInfo(fileWaterBills);
    
                if (fiWaterBills.Exists == true)
                {
                    using (TextReader trWaterBills = new StreamReader(fiWaterBills.FullName))
                    {
                        bills = (List<WaterBill>)xsWaterBills.Deserialize(trWaterBills)!;
    
                        int counter = 1;
    
                        lvwWaterBills.Items.Clear();
    
                        foreach (WaterBill bill in bills)
                        {
                            ListViewItem lviWaterBill = new ListViewItem(counter++.ToString());
    
                            lviWaterBill.SubItems.Add(bill.BillNumber!.ToString());
    
                            IEnumerable<Customer> customer = clients.Where(cust => cust.AccountNumber == bill.AccountNumber);
    
                                                    foreach (Customer cust in customer)
                                                  {
                            lviWaterBill.SubItems.Add(bill.AccountNumber + " - " +
                                                          cust.AccountName +
                                                          ", Type: " + cust.AccountType![..3] +
                                                          ", (Mtr #: " + cust.MeterNumber + ")");
                            }
    
                            lviWaterBill.SubItems.Add(bill.MeterReadingStartDate.ToShortDateString());
                            lviWaterBill.SubItems.Add(bill.MeterReadingEndDate.ToShortDateString());
                            lviWaterBill.SubItems.Add(bill.BillingDays.ToString());
                            lviWaterBill.SubItems.Add(bill.CounterReadingStart.ToString());
                            lviWaterBill.SubItems.Add(bill.CounterReadingEnd.ToString());
                            lviWaterBill.SubItems.Add(bill.TotalHCF.ToString());
                            lviWaterBill.SubItems.Add(bill.TotalGallons.ToString());
                            lviWaterBill.SubItems.Add(bill.PaymentDueDate.ToShortDateString());
                            lviWaterBill.SubItems.Add(bill.AmountDue.ToString());
    
                            lvwWaterBills.Items.Add(lviWaterBill);
                        }
                    }
                }
            }
    
            private void Central_Activated(object sender, EventArgs e)
            {
                ShowWaterBills();
            }
        }
    }
  13. In the Solution Explorer, right-click WaterDistribution.cs and click View Code
  14. Change the document as follows:
    namespace StellarWaterPoint50
    {
        public partial class WaterDistribution : Form
        {
            public static bool          WaterMetersDisplaying;
            public static bool          WaterMeterCreateDisplaying;
            public static bool          WaterMeterDetailsDisplaying;
            public static bool          WaterMeterEditorDisplaying;
            public static bool          WaterMeterDeleteDisplaying;
    
            private WaterMeters.Central waterMeters;
            private WaterMeters.Create  waterMeterCreate;
            private WaterMeters.Details waterMeterDetails;
            private WaterMeters.Editor  waterMeterEditor;
            private WaterMeters.Delete  waterMeterDelete;
    
            public static bool          CustomersDisplaying;
            public static bool          CustomerCreateDisplaying;
            public static bool          CustomerDetailsDisplaying;
            public static bool          CustomerEditorDisplaying;
            public static bool          CustomerDeleteDisplaying;
    
            private Customers.Central   customers;
            private Customers.Create    customerCreate;
            private Customers.Details   customerDetails;
            private Customers.Editor    customerEditor;
            private Customers.Delete    customerDelete;
    
            public static bool          WaterBillsDisplaying;
            private WaterBills.Central  waterBills;
    
            public WaterDistribution()
            {
                InitializeComponent();
    
                WaterMetersDisplaying       = false;
                WaterMeterCreateDisplaying  = false;
                WaterMeterDetailsDisplaying = false;
                WaterMeterEditorDisplaying  = false;
                WaterMeterDeleteDisplaying  = false;
    
                waterMeters                 = new WaterMeters.Central();
                waterMeterCreate            = new WaterMeters.Create();
                waterMeterDetails           = new WaterMeters.Details();
                waterMeterEditor            = new WaterMeters.Editor();
                waterMeterDelete            = new WaterMeters.Delete();
    
                CustomersDisplaying         = false;
                CustomerCreateDisplaying    = false;
                CustomerDetailsDisplaying   = false;
                CustomerEditorDisplaying    = false;
                CustomerDeleteDisplaying    = false;
    
                customers                   = new Customers.Central();
                customerCreate              = new Customers.Create();
                customerDetails             = new Customers.Details();
                customerEditor              = new Customers.Editor();
                customerDelete              = new Customers.Delete();
    
                WaterBillsDisplaying        = false;
                waterBills                  = new WaterBills.Central();
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            . . .
        }
    }
  15. In the Solution Explorer, in the WaterBills folder, double-click Central (make sure the form is selected)
  16. In the Events section of the Properties window, double-click FormClosing
  17. Implement the event as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.WaterBills
    {
        public partial class Central : Form
        {
            public Central()
            {
                InitializeComponent();
            }
    
            private void ShowWaterBills()
            {
                List<Customer> clients = new List<Customer>();
                string strCustomers = @"C:\Stellar Water Point8\Customers.xml";
                XmlSerializer xsCustomers = new XmlSerializer(typeof(List<Customer>));
    
                FileInfo fiCustomers = new FileInfo(strCustomers);
    
                if (fiCustomers.Exists == true)
                {
                    using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
                    {
                        clients = (List<Customer>)xsCustomers.Deserialize(trCustomers)!;
                    }
                }
    
                string strWaterBills = string.Empty;
                List<WaterBill> bills = new List<WaterBill>();
                string fileWaterBills = @"C:\Stellar Water Point8\WaterBills.xml";
                XmlSerializer xsWaterBills = new XmlSerializer(typeof(List<WaterBill>));
    
                FileInfo fiWaterBills = new FileInfo(fileWaterBills);
    
                if (fiWaterBills.Exists == true)
                {
                    using (TextReader trWaterBills = new StreamReader(fiWaterBills.FullName))
                    {
                        bills = (List<WaterBill>)xsWaterBills.Deserialize(trWaterBills)!;
    
                        int counter = 1;
    
                        lvwWaterBills.Items.Clear();
    
                        foreach (WaterBill bill in bills)
                        {
                            ListViewItem lviWaterBill = new ListViewItem(counter++.ToString());
    
                            lviWaterBill.SubItems.Add(bill.BillNumber!.ToString());
    
                            IEnumerable<Customer> customer = clients.Where(cust => cust.AccountNumber == bill.AccountNumber);
    
                                                    foreach (Customer cust in customer)
                                                  {
                            lviWaterBill.SubItems.Add(bill.AccountNumber + " - " +
                                                          cust.AccountName +
                                                          ", Type: " + cust.AccountType![..3] +
                                                          ", (Mtr #: " + cust.MeterNumber + ")");
                            }
    
                            lviWaterBill.SubItems.Add(bill.MeterReadingStartDate.ToShortDateString());
                            lviWaterBill.SubItems.Add(bill.MeterReadingEndDate.ToShortDateString());
                            lviWaterBill.SubItems.Add(bill.BillingDays.ToString());
                            lviWaterBill.SubItems.Add(bill.CounterReadingStart.ToString());
                            lviWaterBill.SubItems.Add(bill.CounterReadingEnd.ToString());
                            lviWaterBill.SubItems.Add(bill.TotalHCF.ToString());
                            lviWaterBill.SubItems.Add(bill.TotalGallons.ToString());
                            lviWaterBill.SubItems.Add(bill.PaymentDueDate.ToShortDateString());
                            lviWaterBill.SubItems.Add(bill.AmountDue.ToString());
    
                            lvwWaterBills.Items.Add(lviWaterBill);
                        }
                    }
                }
            }
    
            private void Central_Activated(object sender, EventArgs e)
            {
                ShowWaterBills();
            }
    
            private void Central_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (WaterDistribution.WaterBillsDisplaying == true)
                {
                    WaterDistribution.WaterBillsDisplaying = false;
                    Close();
                }
            }
        }
    }
  18. In the Solution Explorer, double-click WaterDistribution.cs to display the form
  19. On the menu that was designed on the form, click Water Bills and, below it, double-click View Water Bills...
  20. Implement the event as follows:
    namespace StellarWaterPoint50
    {
        public partial class WaterDistribution : Form
        {
            public static bool WaterMetersDisplaying;
            public static bool WaterMeterCreateDisplaying;
            public static bool WaterMeterDetailsDisplaying;
            public static bool WaterMeterEditorDisplaying;
            public static bool WaterMeterDeleteDisplaying;
    
            private WaterMeters.Central waterMeters;
            private WaterMeters.Create waterMeterCreate;
            private WaterMeters.Details waterMeterDetails;
            private WaterMeters.Editor waterMeterEditor;
            private WaterMeters.Delete waterMeterDelete;
    
            public static bool CustomersDisplaying;
            public static bool CustomerCreateDisplaying;
            public static bool CustomerDetailsDisplaying;
            public static bool CustomerEditorDisplaying;
            public static bool CustomerDeleteDisplaying;
    
            private Customers.Central customers;
            private Customers.Create customerCreate;
            private Customers.Details customerDetails;
            private Customers.Editor customerEditor;
            private Customers.Delete customerDelete;
    
            public static bool WaterBillsDisplaying;
            private WaterBills.Central waterBills;
    
            public WaterDistribution()
            {
                InitializeComponent();
    
                WaterMetersDisplaying = false;
                WaterMeterCreateDisplaying = false;
                WaterMeterDetailsDisplaying = false;
                WaterMeterEditorDisplaying = false;
                WaterMeterDeleteDisplaying = false;
    
                waterMeters = new WaterMeters.Central();
                waterMeterCreate = new WaterMeters.Create();
                waterMeterDetails = new WaterMeters.Details();
                waterMeterEditor = new WaterMeters.Editor();
                waterMeterDelete = new WaterMeters.Delete();
    
                CustomersDisplaying = false;
                CustomerCreateDisplaying = false;
                CustomerDetailsDisplaying = false;
                CustomerEditorDisplaying = false;
                CustomerDeleteDisplaying = false;
    
                customers = new Customers.Central();
                customerCreate = new Customers.Create();
                customerDetails = new Customers.Details();
                customerEditor = new Customers.Editor();
                customerDelete = new Customers.Delete();
    
                WaterBillsDisplaying = false;
                waterBills = new WaterBills.Central();
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            . . .
    
            private void miViewWaterBills_Click(object sender, EventArgs e)
            {
                if(WaterBillsDisplaying == false)
                {
                    waterBills = new WaterBills.Central();
    
                    waterBills.MdiParent = this;
                    waterBills.Show();
    
                    WaterBillsDisplaying = true;
                }
                else
                {
                    waterBills.BringToFront();
                }
            }
        }
    }

A Water Bill Record

.

Practical LearningPractical Learning: Creating a Water Bill Record

  1. To create a form, in the Solution Explorer, right-click WaterBills -> Add -> Form(Windows Forms)...
  2. Type Create
  3. Click Add
  4. Design the form as follows:

    Stellar Water Point - New Water Bill

    Control Text Name Other Properties
    Label Label &Water Bill #:    
    TextBox Text Box   txtBillNumber  
    GroupBox Group Box Customer Information    
    Label Label &Account #:    
    MaskedTextBox Masked Text Box   mtbAccountNumber Mask: 0000-000-0000
    Button Button Find Customer &Account btnFindCustomerAccount  
    Label Label Account Name:    
    TextBox Text Box   txtAccountName  
    Label Label Account Type:    
    TextBox Text Box   txtAccountType  
    Label Label Address:    
    TextBox Text Box   txtAddress  
    TextBox Text Box   txtCity  
    TextBox Text Box   txtCounty  
    TextBox Text Box   txtState  
    TextBox Text Box   txtZIPCode  
    Label Label ___________________________    
    Label Label Meter Details:    
    TextBox Text Box   txtMeterDetails  
    GroupBox Group Box Meter Reading    
    Label Label Meter &Reading Start Date:    
    Date Time Picker Text Box   dtpMeterReadingStartDate  
    Label Label Meter Reading &End Date:    
    Date Time Picker Text Box   dtpMeterReadingEndDate  
    Label Label Coun&ter Reading Start:    
    TextBox Text Box   txtCounterReadingStart  
    Label Label Counter Readi&ng End:    
    TextBox Text Box   txtCounterReadingEnd  
    Button Button &Evaluate Water Bill btnEvaluateWaterBill Times New Roman, 24pt, style=Bold
    GroupBox Group Box Meter Result    
    Label Label Billing Days:    
    TextBox Text Box   txtBillingDays  
    Label Label Total HCF:    
    TextBox Text Box   txtTotalHCF  
    Label Label Total Gallons:    
    TextBox Text Box   txtTotalGallons  
    Label Label First Tier Consumption:    
    TextBox Text Box   txtFirstTierConsumption  
    Label Label Second Tier:    
    TextBox Text Box   txtSecondTierConsumption  
    Label Label Last Tier:    
    TextBox Text Box   txtLastTierConsumption  
    GroupBox Group Box Consumption Charges    
    Label Label Water Charges:    
    TextBox Text Box   txtWaterCharges  
    Label Label Sewer Charges:    
    TextBox Text Box   txtSewerCharges  
    Label Label Environment Charges:    
    TextBox Text Box   txtEnvironmentCharges  
    Label Label Service Charges:    
    TextBox Text Box   txtServiceCharges  
    Label Label Total Charges:    
    TextBox Text Box   txtTotalCharges  
    GroupBox Group Box Taxes    
    Label Label Local Taxes:    
    TextBox Text Box   txtLocalTaxes  
    Label Label State Taxes:    
    TextBox Text Box   txtStateTaxes  
    GroupBox Group Box Water Bill Payment    
    Label Label Payment Due Date:    
    Date Time Picker Text Box   dtpPaymentDueDate  
    Label Label Amount Due:    
    TextBox Text Box   txtAmountDue  
    Label Label Late Payment Due Date:    
    Date Time Picker Text Box   dtpLatePaymentDueDate  
    Label Label &Late Amount Due:    
    TextBox Text Box   txtLateAmountDue  
    Button Button Save Water Bill btnSaveWaterBill  
    Button Button &Close btnClose  
  5. On the form, double-click the Find Customer Account button
  6. Change the document as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.WaterBills
    {
        public partial class Create : Form
        {
            public Create()
            {
                InitializeComponent();
            }
    
            private void btnFindCustomerAccount_Click(object sender, EventArgs e)
            {
                string strActual = mtbAccountNumber.Text.Replace(" ", "").Replace("-", "");
    
                if (string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type an account number for the customer whose record you want to find.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                Customer? client = null;
                List<Customer> clients = new List<Customer>();
                string strCustomers = @"C:\Stellar Water Point8\Customers.xml";
                XmlSerializer xsCustomers = new XmlSerializer(typeof(List<Customer>));
    
                FileInfo fiCustomers = new FileInfo(strCustomers);
    
                string? strMeterNumber = string.Empty;
    
                if (fiCustomers.Exists == true)
                {
                    using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
                    {
                        clients = (List<Customer>)xsCustomers.Deserialize(trCustomers)!;
    
                        client = clients.Find(cl => cl.AccountNumber == mtbAccountNumber.Text)!;
    
                        if (client is not null)
                        {
                            txtAccountName.Text  = client.AccountName;
                            strMeterNumber       = client.MeterNumber;
                            txtAccountType.Text  = client.AccountType;
                            txtAddress.Text      = client.Address;
                            txtCity.Text         = client.City;
                            txtCounty.Text       = client.County;
                            txtState.Text        = client.State;
                            txtZIPCode.Text      = client.ZIPCode;
                        }
                    }
                }
    
                if (strMeterNumber!.Length > 0)
                {
                    WaterMeter? meter = null;
                    List<WaterMeter> waterMeters = new List<WaterMeter>();
                    string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                    XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                    FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                    if (fiWaterMeters.Exists == true)
                    {
                        using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                        {
                            waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                            meter = waterMeters.Find(m => m.MeterNumber == strMeterNumber)!;
    
                            if (meter is not null)
                            {
                                txtMeterDetails.Text = meter.Make + " " + meter.Model + " (Mtr Size: " + meter.MeterSize + ")";
                            }
                        }
                    }
                }
            }
        }
    }
  7. Return to the form and double-click the Meter Reading End Date date time picker to generate its Value Changed event
  8. Implement the event as follows:
    using System.Data;
    using Microsoft.Data.SqlClient;
    
    namespace StellarWaterPoint31.WaterBills
    {
        public partial class Create : Form
        {
            public Create()
            {
                InitializeComponent();
            }
    
            private void btnFindCustomerAccount_Click(object sender, EventArgs e)
            {
                . . .
            }
    
            private void dtpMeterReadingEndDate_ValueChanged(object sender, EventArgs e)
            {
                TimeSpan tsDays = dtpMeterReadingEndDate.Value - dtpMeterReadingStartDate.Value;
    
                txtBillingDays.Text = (tsDays.Days + 1).ToString();
            }
        }
    }
  9. Return to the form and double-click the Evaluate Water Bill button
  10. Implement the event as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.WaterBills
    {
        public partial class Create : Form
        {
            public Create()
            {
                InitializeComponent();
            }
    
            private void btnFindCustomerAccount_Click(object sender, EventArgs e)
            {
                string strActual = mtbAccountNumber.Text.Replace(" ", "").Replace("-", "");
    
                if (string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type an account number for the customer whose record you want to find.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                Customer? client = null;
                List<Customer> clients = new List<Customer>();
                string strCustomers = @"C:\Stellar Water Point8\Customers.xml";
                XmlSerializer xsCustomers = new XmlSerializer(typeof(List<Customer>));
    
                FileInfo fiCustomers = new FileInfo(strCustomers);
    
                string? strMeterNumber = string.Empty;
    
                if (fiCustomers.Exists == true)
                {
                    using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
                    {
                        clients = (List<Customer>)xsCustomers.Deserialize(trCustomers)!;
    
                        client = clients.Find(cl => cl.AccountNumber == mtbAccountNumber.Text)!;
    
                        if (client is not null)
                        {
                            txtAccountName.Text = client.AccountName;
                            strMeterNumber      = client.MeterNumber;
                            txtAccountType.Text = client.AccountType;
                            txtAddress.Text     = client.Address;
                            txtCity.Text        = client.City;
                            txtCounty.Text      = client.County;
                            txtState.Text       = client.State;
                            txtZIPCode.Text     = client.ZIPCode;
                        }
                    }
                }
    
                if (strMeterNumber!.Length > 0)
                {
                    WaterMeter? meter = null;
                    List<WaterMeter> waterMeters = new List<WaterMeter>();
                    string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                    XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                    FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                    if (fiWaterMeters.Exists == true)
                    {
                        using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                        {
                            waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                            meter = waterMeters.Find(m => m.MeterNumber == strMeterNumber)!;
    
                            if (meter is not null)
                            {
                                txtMeterDetails.Text = meter.Make + " " + meter.Model + " (Mtr Size: " + meter.MeterSize + ")";
                            }
                        }
                    }
                }
            }
    
            private void dtpMeterReadingEndDate_ValueChanged(object sender, EventArgs e)
            {
                TimeSpan tsDays = dtpMeterReadingEndDate.Value - dtpMeterReadingStartDate.Value;
    
                txtBillingDays.Text = (tsDays.Days + 1).ToString();
            }
    
            private void btnEvaluateWaterBill_Click(object sender, EventArgs e)
            {
                double counterStart = 0d, counterEnd = 0d;
    
                try
                {
                    counterStart = double.Parse(txtCounterReadingStart.Text);
                }
                catch (FormatException feCRStart)
                {
                    MessageBox.Show("You must enter a valid value in the Counter Reading Start text box. " +
                                    "The error produced is: " + feCRStart.Message,
                                    "Stellar Water Point", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
    
                try
                {
                    counterEnd = double.Parse(txtCounterReadingEnd.Text);
                }
                catch (FormatException feCREnd)
                {
                    MessageBox.Show("You must enter a valid value in the Counter Reading End text box. " +
                                    "The error produced is: " + feCREnd.Message,
                                    "Stellar Water Point", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
    
                double consumption = counterEnd - counterStart;
                double gallons = consumption * 748.05;
                string strAccountType = txtAccountType.Text[..3];
    
                (double first, double second, double last) tiers = WaterBillManager.CalculateTiers(strAccountType, gallons);
    
                double waterCharges           = tiers.first + tiers.second + tiers.last;
                double sewerCharges           = WaterBillManager.CalculateSewerCharges(strAccountType, waterCharges);
                double envCharges             = WaterBillManager.CalculateEnvironmentCharges(strAccountType, waterCharges);
                double srvCharges             = WaterBillManager.CalculateServiceCharges(strAccountType, waterCharges);
                double totalCharges           = waterCharges + sewerCharges + envCharges + srvCharges;
                double localTaxes             = WaterBillManager.CalculateLocalTaxes(strAccountType, waterCharges);
                double stateTaxes             = WaterBillManager.CalculateStateTaxes(strAccountType, waterCharges);
                double amtDue                 = totalCharges + localTaxes + stateTaxes;
    
                txtTotalHCF.Text              = consumption.ToString();
                txtTotalGallons.Text          = ((int)(Math.Ceiling(gallons))).ToString();
                txtFirstTierConsumption.Text  = tiers.first.ToString("F");
                txtSecondTierConsumption.Text = tiers.second.ToString("F");
                txtLastTierConsumption.Text   = tiers.last.ToString("F");
                txtWaterCharges.Text          = waterCharges.ToString("F");
                txtSewerCharges.Text          = sewerCharges.ToString("F");
                txtEnvironmentCharges.Text    = envCharges.ToString("F");
                txtServiceCharges.Text        = srvCharges.ToString("F");
                txtTotalCharges.Text          = totalCharges.ToString("F");
                txtLocalTaxes.Text            = localTaxes.ToString("F");
                txtStateTaxes.Text            = stateTaxes.ToString("F");
                dtpPaymentDueDate.Value       = WaterBillManager.SetPaymentDueDate(strAccountType, dtpMeterReadingEndDate.Value);
                txtAmountDue.Text             = amtDue.ToString("F");
                dtpLatePaymentDueDate.Value   = WaterBillManager.SetLatePaymentDueDate(strAccountType, dtpMeterReadingEndDate.Value);
                txtLateAmountDue.Text         = WaterBillManager.CalculateLateAmountDue(strAccountType, amtDue).ToString("F");
            }
        }
    }
  11. Return to the form and double-click the Save Water Bill button
  12. Return to the form and double-click the &Close button
  13. Change the document as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.WaterBills
    {
        public partial class Create : Form
        {
            public Create()
            {
                InitializeComponent();
            }
    
            private void btnFindCustomerAccount_Click(object sender, EventArgs e)
            {
                string strActual = mtbAccountNumber.Text.Replace(" ", "").Replace("-", "");
    
                if (string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type an account number for the customer whose record you want to find.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                Customer? client = null;
                List<Customer> clients = new List<Customer>();
                string strCustomers = @"C:\Stellar Water Point8\Customers.xml";
                XmlSerializer xsCustomers = new XmlSerializer(typeof(List<Customer>));
    
                FileInfo fiCustomers = new FileInfo(strCustomers);
    
                string? strMeterNumber = string.Empty;
    
                if (fiCustomers.Exists == true)
                {
                    using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
                    {
                        clients = (List<Customer>)xsCustomers.Deserialize(trCustomers)!;
    
                        client = clients.Find(cl => cl.AccountNumber == mtbAccountNumber.Text)!;
    
                        if (client is not null)
                        {
                            txtAccountName.Text = client.AccountName;
                            strMeterNumber = client.MeterNumber;
                            txtAccountType.Text = client.AccountType;
                            txtAddress.Text = client.Address;
                            txtCity.Text = client.City;
                            txtCounty.Text = client.County;
                            txtState.Text = client.State;
                            txtZIPCode.Text = client.ZIPCode;
                        }
                    }
                }
    
                if (strMeterNumber!.Length > 0)
                {
                    WaterMeter? meter = null;
                    List<WaterMeter> waterMeters = new List<WaterMeter>();
                    string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                    XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                    FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                    if (fiWaterMeters.Exists == true)
                    {
                        using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                        {
                            waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                            meter = waterMeters.Find(m => m.MeterNumber == strMeterNumber)!;
    
                            if (meter is not null)
                            {
                                txtMeterDetails.Text = meter.Make + " " + meter.Model + " (Mtr Size: " + meter.MeterSize + ")";
                            }
                        }
                    }
                }
            }
    
            private void dtpMeterReadingEndDate_ValueChanged(object sender, EventArgs e)
            {
                TimeSpan tsDays = dtpMeterReadingEndDate.Value - dtpMeterReadingStartDate.Value;
    
                txtBillingDays.Text = (tsDays.Days + 1).ToString();
            }
    
            private void btnEvaluateWaterBill_Click(object sender, EventArgs e)
            {
                double counterStart = 0d, counterEnd = 0d;
    
                try
                {
                    counterStart = double.Parse(txtCounterReadingStart.Text);
                }
                catch (FormatException feCRStart)
                {
                    MessageBox.Show("You must enter a valid value in the Counter Reading Start text box. " +
                                    "The error produced is: " + feCRStart.Message,
                                    "Stellar Water Point", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
    
                try
                {
                    counterEnd = double.Parse(txtCounterReadingEnd.Text);
                }
                catch (FormatException feCREnd)
                {
                    MessageBox.Show("You must enter a valid value in the Counter Reading End text box. " +
                                    "The error produced is: " + feCREnd.Message,
                                    "Stellar Water Point", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
    
                double consumption = counterEnd - counterStart;
                double gallons = consumption * 748.05;
                string strAccountType = txtAccountType.Text[..3];
    
                (double first, double second, double last) tiers = WaterBillManager.CalculateTiers(strAccountType, gallons);
    
                double waterCharges = tiers.first + tiers.second + tiers.last;
                double sewerCharges = WaterBillManager.CalculateSewerCharges(strAccountType, waterCharges);
                double envCharges = WaterBillManager.CalculateEnvironmentCharges(strAccountType, waterCharges);
                double srvCharges = WaterBillManager.CalculateServiceCharges(strAccountType, waterCharges);
                double totalCharges = waterCharges + sewerCharges + envCharges + srvCharges;
                double localTaxes = WaterBillManager.CalculateLocalTaxes(strAccountType, waterCharges);
                double stateTaxes = WaterBillManager.CalculateStateTaxes(strAccountType, waterCharges);
                double amtDue = totalCharges + localTaxes + stateTaxes;
    
                txtTotalHCF.Text = consumption.ToString();
                txtTotalGallons.Text = ((int)(Math.Ceiling(gallons))).ToString();
                txtFirstTierConsumption.Text = tiers.first.ToString("F");
                txtSecondTierConsumption.Text = tiers.second.ToString("F");
                txtLastTierConsumption.Text = tiers.last.ToString("F");
                txtWaterCharges.Text = waterCharges.ToString("F");
                txtSewerCharges.Text = sewerCharges.ToString("F");
                txtEnvironmentCharges.Text = envCharges.ToString("F");
                txtServiceCharges.Text = srvCharges.ToString("F");
                txtTotalCharges.Text = totalCharges.ToString("F");
                txtLocalTaxes.Text = localTaxes.ToString("F");
                txtStateTaxes.Text = stateTaxes.ToString("F");
                dtpPaymentDueDate.Value = WaterBillManager.SetPaymentDueDate(strAccountType, dtpMeterReadingEndDate.Value);
                txtAmountDue.Text = amtDue.ToString("F");
                dtpLatePaymentDueDate.Value = WaterBillManager.SetLatePaymentDueDate(strAccountType, dtpMeterReadingEndDate.Value);
                txtLateAmountDue.Text = WaterBillManager.CalculateLateAmountDue(strAccountType, amtDue).ToString("F");
            }
    
            private void btnSaveWaterBill_Click(object sender, EventArgs e)
            {
                if (string.IsNullOrEmpty(txtBillNumber.Text))
                {
                    MessageBox.Show("You must provide a bill number for the water bill you are trying to creator save.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                string strWaterBills = string.Empty;
                List<WaterBill> bills = new List<WaterBill>();
                string fileWaterBills = @"C:\Stellar Water Point8\WaterBills.xml";
                XmlSerializer xsWaterBills = new XmlSerializer(typeof(List<WaterBill>));
    
                FileInfo fiWaterBills = new FileInfo(fileWaterBills);
    
                if (fiWaterBills.Exists == true)
                {
                    using (TextReader trWaterBills = new StreamReader(fiWaterBills.FullName))
                    {
                        bills = (List<WaterBill>)xsWaterBills.Deserialize(trWaterBills)!;
                    }
                }
    
                WaterBill bill = new()
                {
                    BillNumber = txtBillNumber.Text,
                    AccountNumber = mtbAccountNumber.Text,
                    MeterReadingStartDate = dtpMeterReadingStartDate.Value,
                    MeterReadingEndDate = dtpMeterReadingEndDate.Value,
                    BillingDays = int.Parse(txtBillingDays.Text),
                    CounterReadingStart = int.Parse(txtCounterReadingStart.Text),
                    CounterReadingEnd = int.Parse(txtCounterReadingEnd.Text),
                    TotalHCF = int.Parse(txtTotalHCF.Text),
                    TotalGallons = int.Parse(txtTotalGallons.Text),
                    FirstTierConsumption = double.Parse(txtFirstTierConsumption.Text),
                    SecondTierConsumption = double.Parse(txtSecondTierConsumption.Text),
                    LastTierConsumption = double.Parse(txtLastTierConsumption.Text),
                    WaterCharges = double.Parse(txtWaterCharges.Text),
                    SewerCharges = double.Parse(txtSewerCharges.Text),
                    EnvironmentCharges = double.Parse(txtEnvironmentCharges.Text),
                    ServiceCharges = double.Parse(txtServiceCharges.Text),
                    TotalCharges = double.Parse(txtTotalCharges.Text),
                    LocalTaxes = double.Parse(txtLocalTaxes.Text),
                    StateTaxes = double.Parse(txtStateTaxes.Text),
                    PaymentDueDate = dtpPaymentDueDate.Value,
                    AmountDue = double.Parse(txtAmountDue.Text),
                    LatePaymentDueDate = dtpLatePaymentDueDate.Value,
                    LateAmountDue = double.Parse(txtLateAmountDue.Text)
                };
    
                bills.Add(bill);
    
                using (TextWriter twWaterBills = new StreamWriter(fiWaterBills.FullName))
                {
                    xsWaterBills.Serialize(twWaterBills, bills);
                }
    
                Close();
            }
    
            private void btnClose_Click(object sender, EventArgs e)
            {
                Close();
            }
        }
    }
  14. In the Solution Explorer, right-click WaterDistribution.cs and click View Code
  15. Change the document as follows:
    namespace StellarWaterPoint50
    {
        public partial class WaterDistribution : Form
        {
            public static bool          WaterMetersDisplaying;
            public static bool          WaterMeterCreateDisplaying;
            public static bool          WaterMeterDetailsDisplaying;
            public static bool          WaterMeterEditorDisplaying;
            public static bool          WaterMeterDeleteDisplaying;
    
            private WaterMeters.Central waterMeters;
            private WaterMeters.Create  waterMeterCreate;
            private WaterMeters.Details waterMeterDetails;
            private WaterMeters.Editor  waterMeterEditor;
            private WaterMeters.Delete  waterMeterDelete;
    
            public static bool          CustomersDisplaying;
            public static bool          CustomerCreateDisplaying;
            public static bool          CustomerDetailsDisplaying;
            public static bool          CustomerEditorDisplaying;
            public static bool          CustomerDeleteDisplaying;
    
            private Customers.Central   customers;
            private Customers.Create    customerCreate;
            private Customers.Details   customerDetails;
            private Customers.Editor    customerEditor;
            private Customers.Delete    customerDelete;
    
            public static bool          WaterBillsDisplaying;
            public static bool          WaterBillCreateDisplaying;
    
            private WaterBills.Central  waterBills;
            private WaterBills.Create   waterBillCreate;
    
            public WaterDistribution()
            {
                InitializeComponent();
    
                WaterMetersDisplaying = false;
                WaterMeterCreateDisplaying = false;
                WaterMeterDetailsDisplaying = false;
                WaterMeterEditorDisplaying = false;
                WaterMeterDeleteDisplaying = false;
    
                waterMeters = new WaterMeters.Central();
                waterMeterCreate = new WaterMeters.Create();
                waterMeterDetails = new WaterMeters.Details();
                waterMeterEditor = new WaterMeters.Editor();
                waterMeterDelete = new WaterMeters.Delete();
    
                CustomersDisplaying = false;
                CustomerCreateDisplaying = false;
                CustomerDetailsDisplaying = false;
                CustomerEditorDisplaying = false;
                CustomerDeleteDisplaying = false;
    
                customers = new Customers.Central();
                customerCreate = new Customers.Create();
                customerDetails = new Customers.Details();
                customerEditor = new Customers.Editor();
                customerDelete = new Customers.Delete();
    
                WaterBillsDisplaying = false;
                waterBills = new WaterBills.Central();
    
                WaterBillsDisplaying = false;
                WaterBillCreateDisplaying = false;
                waterBills = new WaterBills.Central();
                waterBillCreate = new WaterBills.Create();
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
            
            . . .
        }
    }
  16. In the Solution Explorer, in the WaterBills folder, double-click Create
  17. Click an unoccupied area of the form to select it
  18. In the Solution Explorer, click the Events button Events
  19. In the Events section of the Properties window, double-click FormClosing
  20. Implement the event as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.WaterBills
    {
        public partial class Create : Form
        {
            public Create()
            {
                InitializeComponent();
            }
    
            private void btnFindCustomerAccount_Click(object sender, EventArgs e)
            {
                string strActual = mtbAccountNumber.Text.Replace(" ", "").Replace("-", "");
    
                if (string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type an account number for the customer whose record you want to find.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                Customer? client = null;
                List<Customer> clients = new List<Customer>();
                string strCustomers = @"C:\Stellar Water Point8\Customers.xml";
                XmlSerializer xsCustomers = new XmlSerializer(typeof(List<Customer>));
    
                FileInfo fiCustomers = new FileInfo(strCustomers);
    
                string? strMeterNumber = string.Empty;
    
                if (fiCustomers.Exists == true)
                {
                    using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
                    {
                        clients = (List<Customer>)xsCustomers.Deserialize(trCustomers)!;
    
                        client = clients.Find(cl => cl.AccountNumber == mtbAccountNumber.Text)!;
    
                        if (client is not null)
                        {
                            txtAccountName.Text = client.AccountName;
                            strMeterNumber = client.MeterNumber;
                            txtAccountType.Text = client.AccountType;
                            txtAddress.Text = client.Address;
                            txtCity.Text = client.City;
                            txtCounty.Text = client.County;
                            txtState.Text = client.State;
                            txtZIPCode.Text = client.ZIPCode;
                        }
                    }
                }
    
                if (strMeterNumber!.Length > 0)
                {
                    WaterMeter? meter = null;
                    List<WaterMeter> waterMeters = new List<WaterMeter>();
                    string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                    XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                    FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                    if (fiWaterMeters.Exists == true)
                    {
                        using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                        {
                            waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                            meter = waterMeters.Find(m => m.MeterNumber == strMeterNumber)!;
    
                            if (meter is not null)
                            {
                                txtMeterDetails.Text = meter.Make + " " + meter.Model + " (Mtr Size: " + meter.MeterSize + ")";
                            }
                        }
                    }
                }
            }
    
            private void dtpMeterReadingEndDate_ValueChanged(object sender, EventArgs e)
            {
                TimeSpan tsDays = dtpMeterReadingEndDate.Value - dtpMeterReadingStartDate.Value;
    
                txtBillingDays.Text = (tsDays.Days + 1).ToString();
            }
    
            private void btnEvaluateWaterBill_Click(object sender, EventArgs e)
            {
                double counterStart = 0d, counterEnd = 0d;
    
                try
                {
                    counterStart = double.Parse(txtCounterReadingStart.Text);
                }
                catch (FormatException feCRStart)
                {
                    MessageBox.Show("You must enter a valid value in the Counter Reading Start text box. " +
                                    "The error produced is: " + feCRStart.Message,
                                    "Stellar Water Point", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
    
                try
                {
                    counterEnd = double.Parse(txtCounterReadingEnd.Text);
                }
                catch (FormatException feCREnd)
                {
                    MessageBox.Show("You must enter a valid value in the Counter Reading End text box. " +
                                    "The error produced is: " + feCREnd.Message,
                                    "Stellar Water Point", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
    
                double consumption = counterEnd - counterStart;
                double gallons = consumption * 748.05;
                string strAccountType = txtAccountType.Text[..3];
    
                (double first, double second, double last) tiers = WaterBillManager.CalculateTiers(strAccountType, gallons);
    
                double waterCharges = tiers.first + tiers.second + tiers.last;
                double sewerCharges = WaterBillManager.CalculateSewerCharges(strAccountType, waterCharges);
                double envCharges = WaterBillManager.CalculateEnvironmentCharges(strAccountType, waterCharges);
                double srvCharges = WaterBillManager.CalculateServiceCharges(strAccountType, waterCharges);
                double totalCharges = waterCharges + sewerCharges + envCharges + srvCharges;
                double localTaxes = WaterBillManager.CalculateLocalTaxes(strAccountType, waterCharges);
                double stateTaxes = WaterBillManager.CalculateStateTaxes(strAccountType, waterCharges);
                double amtDue = totalCharges + localTaxes + stateTaxes;
    
                txtTotalHCF.Text = consumption.ToString();
                txtTotalGallons.Text = ((int)(Math.Ceiling(gallons))).ToString();
                txtFirstTierConsumption.Text = tiers.first.ToString("F");
                txtSecondTierConsumption.Text = tiers.second.ToString("F");
                txtLastTierConsumption.Text = tiers.last.ToString("F");
                txtWaterCharges.Text = waterCharges.ToString("F");
                txtSewerCharges.Text = sewerCharges.ToString("F");
                txtEnvironmentCharges.Text = envCharges.ToString("F");
                txtServiceCharges.Text = srvCharges.ToString("F");
                txtTotalCharges.Text = totalCharges.ToString("F");
                txtLocalTaxes.Text = localTaxes.ToString("F");
                txtStateTaxes.Text = stateTaxes.ToString("F");
                dtpPaymentDueDate.Value = WaterBillManager.SetPaymentDueDate(strAccountType, dtpMeterReadingEndDate.Value);
                txtAmountDue.Text = amtDue.ToString("F");
                dtpLatePaymentDueDate.Value = WaterBillManager.SetLatePaymentDueDate(strAccountType, dtpMeterReadingEndDate.Value);
                txtLateAmountDue.Text = WaterBillManager.CalculateLateAmountDue(strAccountType, amtDue).ToString("F");
            }
    
            private void btnSaveWaterBill_Click(object sender, EventArgs e)
            {
                if (string.IsNullOrEmpty(txtBillNumber.Text))
                {
                    MessageBox.Show("You must provide a bill number for the water bill you are trying to creator save.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                string strWaterBills = string.Empty;
                List<WaterBill> bills = new List<WaterBill>();
                string fileWaterBills = @"C:\Stellar Water Point8\WaterBills.xml";
                XmlSerializer xsWaterBills = new XmlSerializer(typeof(List<WaterBill>));
    
                FileInfo fiWaterBills = new FileInfo(fileWaterBills);
    
                if (fiWaterBills.Exists == true)
                {
                    using (TextReader trWaterBills = new StreamReader(fiWaterBills.FullName))
                    {
                        bills = (List<WaterBill>)xsWaterBills.Deserialize(trWaterBills)!;
                    }
                }
    
                WaterBill bill = new()
                {
                    BillNumber = txtBillNumber.Text,
                    AccountNumber = mtbAccountNumber.Text,
                    MeterReadingStartDate = dtpMeterReadingStartDate.Value,
                    MeterReadingEndDate = dtpMeterReadingEndDate.Value,
                    BillingDays = int.Parse(txtBillingDays.Text),
                    CounterReadingStart = int.Parse(txtCounterReadingStart.Text),
                    CounterReadingEnd = int.Parse(txtCounterReadingEnd.Text),
                    TotalHCF = int.Parse(txtTotalHCF.Text),
                    TotalGallons = int.Parse(txtTotalGallons.Text),
                    FirstTierConsumption = double.Parse(txtFirstTierConsumption.Text),
                    SecondTierConsumption = double.Parse(txtSecondTierConsumption.Text),
                    LastTierConsumption = double.Parse(txtLastTierConsumption.Text),
                    WaterCharges = double.Parse(txtWaterCharges.Text),
                    SewerCharges = double.Parse(txtSewerCharges.Text),
                    EnvironmentCharges = double.Parse(txtEnvironmentCharges.Text),
                    ServiceCharges = double.Parse(txtServiceCharges.Text),
                    TotalCharges = double.Parse(txtTotalCharges.Text),
                    LocalTaxes = double.Parse(txtLocalTaxes.Text),
                    StateTaxes = double.Parse(txtStateTaxes.Text),
                    PaymentDueDate = dtpPaymentDueDate.Value,
                    AmountDue = double.Parse(txtAmountDue.Text),
                    LatePaymentDueDate = dtpLatePaymentDueDate.Value,
                    LateAmountDue = double.Parse(txtLateAmountDue.Text)
                };
    
                bills.Add(bill);
    
                using (TextWriter twWaterBills = new StreamWriter(fiWaterBills.FullName))
                {
                    xsWaterBills.Serialize(twWaterBills, bills);
                }
    
                Close();
            }
    
            private void btnClose_Click(object sender, EventArgs e)
            {
                Close();
            }
    
            private void Create_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (WaterDistribution.WaterBillCreateDisplaying == true)
                {
                    WaterDistribution.WaterBillCreateDisplaying = false;
                    Close();
                }
            }
        }
    }
  21. In the Solution Explorer, double-click WaterDistribution.cs to display the main form of the application
  22. On the menu that was designed on the form, click Water Bills and, below it, double-click Process Water Bill...
  23. Implement the event as follows:
    namespace StellarWaterPoint50
    {
        public partial class WaterDistribution : Form
        {
            public static bool WaterMetersDisplaying;
            public static bool WaterMeterCreateDisplaying;
            public static bool WaterMeterDetailsDisplaying;
            public static bool WaterMeterEditorDisplaying;
            public static bool WaterMeterDeleteDisplaying;
    
            private WaterMeters.Central waterMeters;
            private WaterMeters.Create waterMeterCreate;
            private WaterMeters.Details waterMeterDetails;
            private WaterMeters.Editor waterMeterEditor;
            private WaterMeters.Delete waterMeterDelete;
    
            public static bool CustomersDisplaying;
            public static bool CustomerCreateDisplaying;
            public static bool CustomerDetailsDisplaying;
            public static bool CustomerEditorDisplaying;
            public static bool CustomerDeleteDisplaying;
    
            private Customers.Central customers;
            private Customers.Create customerCreate;
            private Customers.Details customerDetails;
            private Customers.Editor customerEditor;
            private Customers.Delete customerDelete;
    
            public static bool WaterBillsDisplaying;
            public static bool WaterBillCreateDisplaying;
    
            private WaterBills.Central waterBills;
            private WaterBills.Create  waterBillCreate;
    
            public WaterDistribution()
            {
                InitializeComponent();
    
                WaterMetersDisplaying = false;
                WaterMeterCreateDisplaying = false;
                WaterMeterDetailsDisplaying = false;
                WaterMeterEditorDisplaying = false;
                WaterMeterDeleteDisplaying = false;
    
                waterMeters = new WaterMeters.Central();
                waterMeterCreate = new WaterMeters.Create();
                waterMeterDetails = new WaterMeters.Details();
                waterMeterEditor = new WaterMeters.Editor();
                waterMeterDelete = new WaterMeters.Delete();
    
                CustomersDisplaying = false;
                CustomerCreateDisplaying = false;
                CustomerDetailsDisplaying = false;
                CustomerEditorDisplaying = false;
                CustomerDeleteDisplaying = false;
    
                customers = new Customers.Central();
                customerCreate = new Customers.Create();
                customerDetails = new Customers.Details();
                customerEditor = new Customers.Editor();
                customerDelete = new Customers.Delete();
    
                WaterBillsDisplaying = false;
                WaterBillCreateDisplaying = false;
                waterBills = new WaterBills.Central();
                waterBillCreate = new WaterBills.Create();
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            . . .
    
            private void miWaterBillsCreate_Click(object sender, EventArgs e)
            {
                if (WaterBillCreateDisplaying == false)
                {
                    waterBillCreate = new WaterBills.Create();
    
                    waterBillCreate.MdiParent = this;
                    waterBillCreate.Show();
    
                    WaterBillCreateDisplaying = true;
                }
                else
                {
                    waterBillCreate.BringToFront();
                }
            }
        }
    }
  24. To execute, on the main menu, click Debug -> Start Without Debugging:

  25. On the main menu, click Water Bills and click View Water Bills...:

  26. On the main menu, click Water Bills and click Process Water Bill...:

  27. Enter the following values in the indicated text boxes or select the date values. Then click Find Customer Account, followed by Evaluate Water Bill, followed by Save Water Bill:

    Stellar Water Point - Create Water Bill

    Stellar Water Point - Create Water Bill

    Water Bill # Account # Reading Start Date Reading End Date Counter Reading Start Counter Reading End
    451474 2068-258-9486 01/11/2010 04/12/2010 103943 103956
    923633 5293-957-3395 01/17/2010 08/18/2010 256945 256972
    917829 9279-570-8394 02/15/2010 05/14/2010 5205 5222
    202666 6986-829-3741 03/08/2010 06/06/2010 5679 5690

    Stellar Water Point - Water Bills

  28. Close the forms and return to your programming environment

Viewing the Details of a Water Bill

.

Practical LearningPractical Learning: Viewing the Details of a Water Bill

  1. To create a form, in the Solution Explorer, right-click the WaterBills folder -> Add -> Form (Windows Forms)...
  2. For the Name of the form, type Details
  3. Press Enter
  4. Design the form as follows:

    Stellar Water Point - Water Bill Details

    Control Text Name Other Properties
    Label Label &Water Bill #:    
    TextBox Text Box   txtBillNumber  
    Button Button &Find Water Bill btnFindWaterBill  
    GroupBox Group Box Customer Information    
    Label Label &Account #:    
    TextBox Text Box   txtAccountNumber Enabled: False
    Label Label Account Name:    
    TextBox Text Box   txtAccountName Enabled: False
    Label Label Account Type:    
    TextBox Text Box   txtAccountType Enabled: False
    Label Label Address:   Enabled: False
    TextBox Text Box   txtAddress Enabled: False
    TextBox Text Box   txtCity  
    TextBox Text Box   txtCounty Enabled: False
    TextBox Text Box   txtState Enabled: False
    TextBox Text Box   txtZIPCode Enabled: False
    Label Label ______________________    
    Label Label Meter Details:    
    TextBox Text Box   txtMeterDetails Enabled: False
    GroupBox Group Box Meter Reading    
    Label Label Meter &Reading Start Date:    
    Text Box Text Box   txtMeterReadingStartDate Enabled: False
    Label Label Meter Reading &End Date:    
    Text Box Text Box   txtMeterReadingEndDate Enabled: False
    Label Label Coun&ter Reading Start:    
    TextBox Text Box   txtCounterReadingStart Enabled: False
    Label Label Counter Readi&ng End:    
    TextBox Text Box   txtCounterReadingEnd Enabled: False
    GroupBox Group Box Meter Result    
    Label Label Billing Days:    
    TextBox Text Box   txtBillingDays Enabled: False
    Label Label Total HCF:    
    TextBox Text Box   txtTotalHCF Enabled: False
    Label Label Total Gallons:    
    TextBox Text Box   txtTotalGallons Enabled: False
    Label Label First Tier Consumption:    
    TextBox Text Box   txtFirstTierConsumption Enabled: False
    Label Label Second Tier:    
    TextBox Text Box   txtSecondTierConsumption Enabled: False
    Label Label Last Tier:    
    TextBox Text Box   txtLastTierConsumption Enabled: False
    GroupBox Group Box Consumption Charges    
    Label Label Water Charges:    
    TextBox Text Box   txtWaterCharges Enabled: False
    Label Label Sewer Charges:    
    TextBox Text Box   txtSewerCharges Enabled: False
    Label Label Environment Charges:    
    TextBox Text Box   txtEnvironmentCharges Enabled: False
    Label Label Service Charges:    
    TextBox Text Box   txtServiceCharges Enabled: False
    Label Label Total Charges:    
    TextBox Text Box   txtTotalCharges Enabled: False
    GroupBox Group Box Taxes    
    Label Label Local Taxes:    
    TextBox Text Box   txtLocalTaxes Enabled: False
    Label Label State Taxes:    
    TextBox Text Box   txtStateTaxes Enabled: False
    GroupBox Group Box Water Bill Payment    
    Label Label Payment Due Date:    
    Date Time Picker Text Box   dtpPaymentDueDate Enabled: False
    Label Label Amount Due:    
    TextBox Text Box   txtAmountDue Enabled: False
    Label Label Late Payment Due Date:    
    Text Box Text Box   txtLatePaymentDueDate Enabled: False
    Label Label &Late Amount Due:    
    TextBox Text Box   txtLateAmountDue  
    Button Button &Close btnClose  
  5. On the form, double-click the Find Water Bill button
  6. Return to the form and double-click the Close button
  7. Change the document as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.WaterBills
    {
        public partial class Details : Form
        {
            public Details()
            {
                InitializeComponent();
            }
    
            private void btnFindWaterBill_Click(object sender, EventArgs e)
            {
                if (string.IsNullOrEmpty(txtBillNumber.Text))
                {
                    MessageBox.Show("You must provide a bill number for the water bill you are trying to creator save.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                string strWaterBills = string.Empty;
                List<WaterBill> bills = new List<WaterBill>();
                string fileWaterBills = @"C:\Stellar Water Point8\WaterBills.xml";
                XmlSerializer xsWaterBills = new XmlSerializer(typeof(List<WaterBill>));
    
                FileInfo fiWaterBills = new FileInfo(fileWaterBills);
    
                if (fiWaterBills.Exists == true)
                {
                    using (TextReader trWaterBills = new StreamReader(fiWaterBills.FullName))
                    {
                        bills = (List<WaterBill>)xsWaterBills.Deserialize(trWaterBills)!;
    
                        IEnumerable<WaterBill> invoices = bills.Where(invoice => invoice.BillNumber == txtBillNumber.Text);
    
                        foreach (WaterBill bill in invoices)
                        {
                            txtAccountNumber.Text = bill.AccountNumber;
                            txtMeterReadingStartDate.Text = bill.MeterReadingStartDate.ToLongDateString();
                            txtMeterReadingEndDate.Text = bill.MeterReadingEndDate.ToShortDateString();
                            txtBillingDays.Text = bill.BillingDays.ToString();
                            txtCounterReadingStart.Text = bill.CounterReadingStart.ToString();
                            txtCounterReadingEnd.Text = bill.CounterReadingEnd.ToString();
                            txtTotalHCF.Text = bill.TotalHCF.ToString();
                            txtTotalGallons.Text = bill.TotalGallons.ToString();
                            txtFirstTierConsumption.Text = bill.FirstTierConsumption.ToString();
                            txtSecondTierConsumption.Text = bill.SecondTierConsumption.ToString();
                            txtLastTierConsumption.Text = bill.LastTierConsumption.ToString();
                            txtWaterCharges.Text = bill.WaterCharges.ToString();
                            txtSewerCharges.Text = bill.SewerCharges.ToString();
                            txtEnvironmentCharges.Text = bill.EnvironmentCharges.ToString();
                            txtServiceCharges.Text = bill.ServiceCharges.ToString();
                            txtTotalCharges.Text = bill.TotalCharges.ToString();
                            txtLocalTaxes.Text = bill.LocalTaxes.ToString();
                            txtStateTaxes.Text = bill.StateTaxes.ToString();
                            txtPaymentDueDate.Text = bill.PaymentDueDate.ToShortDateString();
                            txtAmountDue.Text = bill.AmountDue.ToString();
                            txtLatePaymentDueDate.Text = bill.LatePaymentDueDate.ToLongDateString();
                            txtLateAmountDue.Text = bill.LateAmountDue.ToString();
                        }
                        ;
                    }
                }
    
                List<Customer> clients = new List<Customer>();
                string strCustomers = @"C:\Stellar Water Point8\Customers.xml";
                XmlSerializer xsCustomers = new XmlSerializer(typeof(List<Customer>));
    
                FileInfo fiCustomers = new FileInfo(strCustomers);
    
                string? strMeterNumber = string.Empty;
    
                if (fiCustomers.Exists == true)
                {
                    using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
                    {
                        clients = (List<Customer>)xsCustomers.Deserialize(trCustomers)!;
    
                        clients.ForEach(client =>
                        {
                            if (client.AccountNumber == txtAccountNumber.Text)
                            {
                                txtAccountName.Text = client.AccountName;
                                txtAccountType.Text = client.AccountType;
                                strMeterNumber = client.MeterNumber;
                                txtAddress.Text = client.Address;
                                txtCity.Text = client.City;
                                txtCounty.Text = client.County;
                                txtState.Text = client.State;
                                txtZIPCode.Text = client.ZIPCode;
                            }
                        });
                    }
                }
    
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        WaterMeter? meter = waterMeters.Find(m => m.MeterNumber == strMeterNumber)!;
    
                        if (meter is not null)
                        {
                            txtMeterDetails.Text = meter.Make + " " + meter.Model + " (Mtr Size: " + meter.MeterSize + ")";
                        }
                    }
                }
            }
    
            private void btnClose_Click(object sender, EventArgs e)
            {
                Close();
            }
        }
    }
  8. In the Solution Explorer, right-click WaterDistribution.cs and click View Code
  9. Change the document as follows:
    namespace StellarWaterPoint50
    {
        public partial class WaterDistribution : Form
        {
            public static bool WaterMetersDisplaying;
            public static bool WaterMeterCreateDisplaying;
            public static bool WaterMeterDetailsDisplaying;
            public static bool WaterMeterEditorDisplaying;
            public static bool WaterMeterDeleteDisplaying;
    
            private WaterMeters.Central waterMeters;
            private WaterMeters.Create waterMeterCreate;
            private WaterMeters.Details waterMeterDetails;
            private WaterMeters.Editor waterMeterEditor;
            private WaterMeters.Delete waterMeterDelete;
    
            public static bool CustomersDisplaying;
            public static bool CustomerCreateDisplaying;
            public static bool CustomerDetailsDisplaying;
            public static bool CustomerEditorDisplaying;
            public static bool CustomerDeleteDisplaying;
    
            private Customers.Central customers;
            private Customers.Create customerCreate;
            private Customers.Details customerDetails;
            private Customers.Editor customerEditor;
            private Customers.Delete customerDelete;
    
            public static bool WaterBillsDisplaying;
            public static bool WaterBillCreateDisplaying;
            public static bool WaterBillDetailsDisplaying;
    
            private WaterBills.Central waterBills;
            private WaterBills.Create  waterBillCreate;
            private WaterBills.Details waterBillDetails;
    
            public WaterDistribution()
            {
                InitializeComponent();
    
                WaterMetersDisplaying = false;
                WaterMeterCreateDisplaying = false;
                WaterMeterDetailsDisplaying = false;
                WaterMeterEditorDisplaying = false;
                WaterMeterDeleteDisplaying = false;
    
                waterMeters = new WaterMeters.Central();
                waterMeterCreate = new WaterMeters.Create();
                waterMeterDetails = new WaterMeters.Details();
                waterMeterEditor = new WaterMeters.Editor();
                waterMeterDelete = new WaterMeters.Delete();
    
                CustomersDisplaying = false;
                CustomerCreateDisplaying = false;
                CustomerDetailsDisplaying = false;
                CustomerEditorDisplaying = false;
                CustomerDeleteDisplaying = false;
    
                customers = new Customers.Central();
                customerCreate = new Customers.Create();
                customerDetails = new Customers.Details();
                customerEditor = new Customers.Editor();
                customerDelete = new Customers.Delete();
    
                WaterBillsDisplaying = false;
                WaterBillCreateDisplaying = false;
                WaterBillDetailsDisplaying = false;
    
                waterBills = new WaterBills.Central();
                waterBillCreate = new WaterBills.Create();
                waterBillDetails = new WaterBills.Details();
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            . . .
        }
    }
  10. In the Solution Explorer, in the WaterBills folder, double-click Details
  11. Click an unoccupied area of the form to select it
  12. In the Solution Explorer, click the Events button Events
  13. In the Events section of the Properties window, double-click FormClosing
  14. Implement the events as follows:
    using StellarWaterPoint50.Models;
    using System.Xml.Serialization;
    
    namespace StellarWaterPoint50.WaterBills
    {
        public partial class Details : Form
        {
            public Details()
            {
                InitializeComponent();
            }
    
            private void btnFindWaterBill_Click(object sender, EventArgs e)
            {
                . . .
            }
    
            private void Details_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (WaterDistribution.WaterBillDetailsDisplaying == true)
                {
                    WaterDistribution.WaterBillDetailsDisplaying = false;
                    Close();
                }
            }
        }
    }
  15. In the Solution Explorer, double-click WaterDistribution.cs to display the primary form of the application
  16. On the menu bar of the form, click Water Bills and, below it, double-click Water Bill Details...
  17. Implement the event as follows:
    namespace StellarWaterPoint50
    {
        public partial class WaterDistribution : Form
        {
            . . .
    
            private WaterBills.Central waterBills;
            private WaterBills.Create waterBillCreate;
            private WaterBills.Details waterBillDetails;
    
            public WaterDistribution()
            {
                InitializeComponent();
    
                . . .
    
                WaterBillsDisplaying = false;
                WaterBillCreateDisplaying = false;
                WaterBillDetailsDisplaying = false;
    
                waterBills = new WaterBills.Central();
                waterBillCreate = new WaterBills.Create();
                waterBillDetails = new WaterBills.Details();
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            . . .
    
            private void miWaterBillsCreate_Click(object sender, EventArgs e)
            {
                if (WaterBillCreateDisplaying == false)
                {
                    waterBillCreate = new WaterBills.Create();
    
                    waterBillCreate.MdiParent = this;
                    waterBillCreate.Show();
    
                    WaterBillCreateDisplaying = true;
                }
                else
                {
                    waterBillCreate.BringToFront();
                }
            }
    
            private void miWaterBillsDetails_Click(object sender, EventArgs e)
            {
                if (WaterBillDetailsDisplaying == false)
                {
                    waterBillDetails = new();
                    waterBillDetails.MdiParent = this;
                    waterBillDetails.Show();
    
                    WaterBillDetailsDisplaying = true;
                }
                else
                {
                    waterBillDetails.BringToFront();
                }
            }
        }
    }
  18. To execute the application, on the main menu, click Debug -> Start Without Debugging:

  19. On the main menu of the Stellar Water Point form, click Water Bills and click View Water Bills:

    Stellar Water Point - Water Bills

  20. Again, on the main menu of the form, click Water Bills and click Water Bill Details:

    Stellar Water Point - View Water Meter

  21. In the Water Bill # text box, type 917829
  22. Click the Find Water Bill button:

    Stellar Water Point - View Water Bill

  23. Close the forms and return to your programming environment

Updating a Water Bill

.

Practical LearningPractical Learning: Updating a Customer Account

  1. To create a form, in the Solution Explorer, right-click WaterBills -> Add -> Form (Windows Forms)...
  2. For the Name of the file, type Editor as the name of the form
  3. Click Add
  4. Design the form as follows:

    Stellar Water Point - Water Bill Editor

    Control Text Name Other Properties
    Label Label &Water Bill #:    
    TextBox Text Box   txtBillNumber  
    Button Button &Find Water Bill btnFindWaterBill  
    GroupBox Group Box Customer Information    
    Label Label &Account #:    
    MaskedTextBox Masked Text Box   mtbAccountNumber Mask: 0000-000-0000
    Button Button Find Customer &Account btnFindCustomerAccount  
    Label Label Account Name:    
    TextBox Text Box   txtAccountName  
    Label Label Account Type:    
    TextBox Text Box   txtAccountType  
    Label Label Address:    
    TextBox Text Box   txtAddress  
    TextBox Text Box   txtCity  
    TextBox Text Box   txtCounty  
    TextBox Text Box   txtState  
    TextBox Text Box   txtZIPCode  
    Label Label ___________________________    
    Label Label Meter Details:    
    TextBox Text Box   txtMeterDetails  
    GroupBox Group Box Meter Reading    
    Label Label Meter &Reading Start Date:    
    Date Time Picker Text Box   dtpMeterReadingStartDate  
    Label Label Meter Reading &End Date:    
    Date Time Picker Text Box   dtpMeterReadingEndDate  
    Label Label Coun&ter Reading Start:    
    TextBox Text Box   txtCounterReadingStart  
    Label Label Counter Readi&ng End:    
    TextBox Text Box   txtCounterReadingEnd  
    Button Button &Evaluate Water Bill btnEvaluateWaterBill Times New Roman, 24pt, style=Bold
    GroupBox Group Box Meter Result    
    Label Label Billing Days:    
    TextBox Text Box   txtBillingDays  
    Label Label Total HCF:    
    TextBox Text Box   txtTotalHCF  
    Label Label Total Gallons:    
    TextBox Text Box   txtTotalGallons  
    Label Label First Tier Consumption:    
    TextBox Text Box   txtFirstTierConsumption  
    Label Label Second Tier:    
    TextBox Text Box   txtSecondTierConsumption  
    Label Label Last Tier:    
    TextBox Text Box   txtLastTierConsumption  
    GroupBox Group Box Consumption Charges    
    Label Label Water Charges:    
    TextBox Text Box   txtWaterCharges  
    Label Label Sewer Charges:    
    TextBox Text Box   txtSewerCharges  
    Label Label Environment Charges:    
    TextBox Text Box   txtEnvironmentCharges  
    Label Label Service Charges:    
    TextBox Text Box   txtServiceCharges  
    Label Label Total Charges:    
    TextBox Text Box   txtTotalCharges  
    GroupBox Group Box Taxes    
    Label Label Local Taxes:    
    TextBox Text Box   txtLocalTaxes  
    Label Label State Taxes:    
    TextBox Text Box   txtStateTaxes  
    GroupBox Group Box Water Bill Payment    
    Label Label Payment Due Date:    
    Date Time Picker Text Box   dtpPaymentDueDate  
    Label Label Amount Due:    
    TextBox Text Box   txtAmountDue  
    Label Label Late Payment Due Date:    
    Date Time Picker Text Box   dtpLatePaymentDueDate  
    Label Label &Late Amount Due:    
    TextBox Text Box   txtLateAmountDue  
    Button Button Save Water Bill btnSaveWaterBill  
    Button Button &Close btnClose  
  5. On the form, double-click the Find Water Bill button
  6. Change the document as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.WaterBills
    {
        public partial class Editor : Form
        {
            public Editor()
            {
                InitializeComponent();
            }
    
            private void btnFindWaterBill_Click(object sender, EventArgs e)
            {
                if (string.IsNullOrEmpty(txtBillNumber.Text))
                {
                    MessageBox.Show("You must provide a bill number for the water bill you are trying to creator save.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                string strWaterBills = string.Empty;
                List<WaterBill> bills = new List<WaterBill>();
                string fileWaterBills = @"C:\Stellar Water Point8\WaterBills.xml";
                XmlSerializer xsWaterBills = new XmlSerializer(typeof(List<WaterBill>));
    
                FileInfo fiWaterBills = new FileInfo(fileWaterBills);
    
                if (fiWaterBills.Exists == true)
                {
                    using (TextReader trWaterBills = new StreamReader(fiWaterBills.FullName))
                    {
                        bills = (List<WaterBill>)xsWaterBills.Deserialize(trWaterBills)!;
    
                        IEnumerable<WaterBill> invoices = bills.Where(invoice => invoice.BillNumber == txtBillNumber.Text);
    
                        foreach (WaterBill bill in invoices)
                        {
                            mtbAccountNumber.Text = bill.AccountNumber;
                            dtpMeterReadingStartDate.Value = bill.MeterReadingStartDate;
                            dtpMeterReadingEndDate.Value = bill.MeterReadingEndDate;
                            txtBillingDays.Text = bill.BillingDays.ToString();
                            txtCounterReadingStart.Text = bill.CounterReadingStart.ToString();
                            txtCounterReadingEnd.Text = bill.CounterReadingEnd.ToString();
                            txtTotalHCF.Text = bill.TotalHCF.ToString();
                            txtTotalGallons.Text = bill.TotalGallons.ToString();
                            txtFirstTierConsumption.Text = bill.FirstTierConsumption.ToString();
                            txtSecondTierConsumption.Text = bill.SecondTierConsumption.ToString();
                            txtLastTierConsumption.Text = bill.LastTierConsumption.ToString();
                            txtWaterCharges.Text = bill.WaterCharges.ToString();
                            txtSewerCharges.Text = bill.SewerCharges.ToString();
                            txtEnvironmentCharges.Text = bill.EnvironmentCharges.ToString();
                            txtServiceCharges.Text = bill.ServiceCharges.ToString();
                            txtTotalCharges.Text = bill.TotalCharges.ToString();
                            txtLocalTaxes.Text = bill.LocalTaxes.ToString();
                            txtStateTaxes.Text = bill.StateTaxes.ToString();
                            dtpPaymentDueDate.Value = bill.PaymentDueDate;
                            txtAmountDue.Text = bill.AmountDue.ToString();
                            dtpLatePaymentDueDate.Value = bill.LatePaymentDueDate;
                            txtLateAmountDue.Text = bill.LateAmountDue.ToString();
                        }
                        ;
                    }
                }
    
                List<Customer> clients = new List<Customer>();
                string strCustomers = @"C:\Stellar Water Point8\Customers.xml";
                XmlSerializer xsCustomers = new XmlSerializer(typeof(List<Customer>));
    
                FileInfo fiCustomers = new FileInfo(strCustomers);
    
                string? strMeterNumber = string.Empty;
    
                if (fiCustomers.Exists == true)
                {
                    using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
                    {
                        clients = (List<Customer>)xsCustomers.Deserialize(trCustomers)!;
    
                        clients.ForEach(client =>
                        {
                            if (client.AccountNumber == mtbAccountNumber.Text)
                            {
                                txtAccountName.Text = client.AccountName;
                                txtAccountType.Text = client.AccountType;
                                strMeterNumber = client.MeterNumber;
                                txtAddress.Text = client.Address;
                                txtCity.Text = client.City;
                                txtCounty.Text = client.County;
                                txtState.Text = client.State;
                                txtZIPCode.Text = client.ZIPCode;
                            }
                        });
                    }
                }
    
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        WaterMeter? meter = waterMeters.Find(m => m.MeterNumber == strMeterNumber)!;
    
                        if (meter is not null)
                        {
                            txtMeterDetails.Text = meter.Make + " " + meter.Model + " (Mtr Size: " + meter.MeterSize + ")";
                        }
                    }
                }
            }
        }
    }
  7. Return to the form and double-click the Find Customer Account button
  8. Change the document as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.WaterBills
    {
        public partial class Editor : Form
        {
            public Editor()
            {
                InitializeComponent();
            }
    
            private void btnFindWaterBill_Click(object sender, EventArgs e)
            {
                . . .
            }
    
            private void btnFindCustomerAccount_Click(object sender, EventArgs e)
            {
                string strActual = mtbAccountNumber.Text.Replace(" ", "").Replace("-", "");
    
                if (string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a valid account number of " +
                                    "a customer whose account you want to view.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                List<Customer> clients = new List<Customer>();
                string strCustomers = @"C:\Stellar Water Point8\Customers.xml";
                XmlSerializer xsCustomers = new XmlSerializer(typeof(List<Customer>));
    
                FileInfo fiCustomers = new FileInfo(strCustomers);
    
                string? strMeterNumber = string.Empty;
    
                if (fiCustomers.Exists == true)
                {
                    using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
                    {
                        clients = (List<Customer>)xsCustomers.Deserialize(trCustomers)!;
    
                        clients.ForEach(client =>
                        {
                            if (client.AccountNumber == mtbAccountNumber.Text)
                            {
                                txtAccountName.Text = client.AccountName;
                                txtAccountType.Text = client.AccountType;
                                strMeterNumber = client.MeterNumber;
                                txtAddress.Text = client.Address;
                                txtCity.Text = client.City;
                                txtCounty.Text = client.County;
                                txtState.Text = client.State;
                                txtZIPCode.Text = client.ZIPCode;
                            }
                        });
                    }
                }
    
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        WaterMeter? meter = waterMeters.Find(m => m.MeterNumber == strMeterNumber)!;
    
                        if (meter is not null)
                        {
                            txtMeterDetails.Text = meter.Make + " " + meter.Model + " (Mtr Size: " + meter.MeterSize + ")";
                        }
                    }
                }
            }
        }
    }
  9. Return to the form and double-click the Meter Reading End Date date time picker to generate its Value Changed event
  10. Implement the event as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.WaterBills
    {
        public partial class Editor : Form
        {
            public Editor()
            {
                InitializeComponent();
            }
    
            private void btnFindWaterBill_Click(object sender, EventArgs e)
            {
                . . .
            }
    
            private void btnFindCustomerAccount_Click(object sender, EventArgs e)
            {
                . . .
            }
    
            private void dtpMeterReadingEndDate_ValueChanged(object sender, EventArgs e)
            {
                TimeSpan tsDays     = dtpMeterReadingEndDate.Value - dtpMeterReadingStartDate.Value;
    
                txtBillingDays.Text = (tsDays.Days + 1).ToString();
            }
        }
    }
  11. Return to the form and double-click the Evaluate Water Bill button
  12. Implement the event as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.WaterBills
    {
        public partial class Editor : Form
        {
            public Editor()
            {
                InitializeComponent();
            }
    
            private void btnFindWaterBill_Click(object sender, EventArgs e)
            {
                . . .
            }
    
            private void btnFindCustomerAccount_Click(object sender, EventArgs e)
            {
                . . .
            }
    
            private void dtpMeterReadingEndDate_ValueChanged(object sender, EventArgs e)
            {
                TimeSpan tsDays = dtpMeterReadingEndDate.Value - dtpMeterReadingStartDate.Value;
    
                txtBillingDays.Text = (tsDays.Days + 1).ToString();
            }
    
            private void btnEvaluateWaterBill_Click(object sender, EventArgs e)
            {
                double counterStart = 0d, counterEnd = 0d;
    
                try
                {
                    counterStart = double.Parse(txtCounterReadingStart.Text);
                }
                catch (FormatException feCRStart)
                {
                    MessageBox.Show("You must enter a valid value in the Counter Reading Start text box. " +
                                    "The error produced is: " + feCRStart.Message,
                                    "Stellar Water Point", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
    
                try
                {
                    counterEnd = double.Parse(txtCounterReadingEnd.Text);
                }
                catch (FormatException feCREnd)
                {
                    MessageBox.Show("You must enter a valid value in the Counter Reading End text box. " +
                                    "The error produced is: " + feCREnd.Message,
                                    "Stellar Water Point", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
    
                double consumption = counterEnd - counterStart;
                double gallons = consumption * 748.05;
                string strAccountType = txtAccountType.Text[..3];
    
                (double first, double second, double last) tiers = WaterBillManager.CalculateTiers(strAccountType, gallons);
    
                double waterCharges = tiers.first + tiers.second + tiers.last;
                double sewerCharges = WaterBillManager.CalculateSewerCharges(strAccountType, waterCharges);
                double envCharges = WaterBillManager.CalculateEnvironmentCharges(strAccountType, waterCharges);
                double srvCharges = WaterBillManager.CalculateServiceCharges(strAccountType, waterCharges);
                double totalCharges = waterCharges + sewerCharges + envCharges + srvCharges;
                double localTaxes = WaterBillManager.CalculateLocalTaxes(strAccountType, waterCharges);
                double stateTaxes = WaterBillManager.CalculateStateTaxes(strAccountType, waterCharges);
                double amtDue = totalCharges + localTaxes + stateTaxes;
    
                txtTotalHCF.Text = consumption.ToString();
                txtTotalGallons.Text = ((int)(Math.Ceiling(gallons))).ToString();
                txtFirstTierConsumption.Text = tiers.first.ToString("F");
                txtSecondTierConsumption.Text = tiers.second.ToString("F");
                txtLastTierConsumption.Text = tiers.last.ToString("F");
                txtWaterCharges.Text = waterCharges.ToString("F");
                txtSewerCharges.Text = sewerCharges.ToString("F");
                txtEnvironmentCharges.Text = envCharges.ToString("F");
                txtServiceCharges.Text = srvCharges.ToString("F");
                txtTotalCharges.Text = totalCharges.ToString("F");
                txtLocalTaxes.Text = localTaxes.ToString("F");
                txtStateTaxes.Text = stateTaxes.ToString("F");
                dtpPaymentDueDate.Value = WaterBillManager.SetPaymentDueDate(strAccountType, dtpMeterReadingEndDate.Value);
                txtAmountDue.Text = amtDue.ToString("F");
                dtpLatePaymentDueDate.Value = WaterBillManager.SetLatePaymentDueDate(strAccountType, dtpMeterReadingEndDate.Value);
                txtLateAmountDue.Text = WaterBillManager.CalculateLateAmountDue(strAccountType, amtDue).ToString("F");
            }
        }
    }
  13. Return to the form and double-click the Update Water Bill button
  14. Implement the event as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.WaterBills
    {
        public partial class Editor : Form
        {
            public Editor()
            {
                InitializeComponent();
            }
    
            private void btnFindWaterBill_Click(object sender, EventArgs e)
            {
                . . .
            }
    
            private void btnFindCustomerAccount_Click(object sender, EventArgs e)
            {
                . . .
            }
    
            private void dtpMeterReadingEndDate_ValueChanged(object sender, EventArgs e)
            {
                TimeSpan tsDays = dtpMeterReadingEndDate.Value - dtpMeterReadingStartDate.Value;
    
                txtBillingDays.Text = (tsDays.Days + 1).ToString();
            }
    
            private void btnEvaluateWaterBill_Click(object sender, EventArgs e)
            {
                . . .
            }
    
            private void btnUpdateWaterBill_Click(object sender, EventArgs e)
            {
                if (string.IsNullOrEmpty(txtBillNumber.Text))
                {
                    MessageBox.Show("You must provide a bill number for the water bill you are trying to update.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                string strAccountNumber = mtbAccountNumber.Text.Replace(" ", "").Replace("-", "");
    
                if(string.IsNullOrEmpty(strAccountNumber) | string.IsNullOrEmpty(txtAccountName.Text))
                {
                    MessageBox.Show("You must provide an account number of the customer " +
                                    "whose water bill you are trying to update. " +
                                    "After providing the account number, click the Find Customer Account button.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                string strWaterBills = string.Empty;
                List<WaterBill> bills = new List<WaterBill>();
                string fileWaterBills = @"C:\Stellar Water Point8\WaterBills.xml";
                XmlSerializer xsWaterBills = new XmlSerializer(typeof(List<WaterBill>));
    
                FileInfo fiWaterBills = new FileInfo(fileWaterBills);
    
                if (fiWaterBills.Exists == true)
                {
                    using (TextReader trWaterBills = new StreamReader(fiWaterBills.FullName))
                    {
                        bills = (List<WaterBill>)xsWaterBills.Deserialize(trWaterBills)!;
    
                        foreach(WaterBill bill in bills)
                        {
                            if(bill.BillNumber == txtBillNumber.Text)
                            {
                                bill.AccountNumber = mtbAccountNumber.Text;
                                bill.MeterReadingStartDate = dtpMeterReadingStartDate.Value;
                                bill.MeterReadingEndDate = dtpMeterReadingEndDate.Value;
                                bill.BillingDays = int.Parse(txtBillingDays.Text);
                                bill.CounterReadingStart = int.Parse(txtCounterReadingStart.Text);
                                bill.CounterReadingEnd = int.Parse(txtCounterReadingEnd.Text);
                                bill.TotalHCF = int.Parse(txtTotalHCF.Text);
                                bill.TotalGallons = int.Parse(txtTotalGallons.Text);
                                bill.FirstTierConsumption = double.Parse(txtFirstTierConsumption.Text);
                                bill.SecondTierConsumption = double.Parse(txtSecondTierConsumption.Text);
                                bill.LastTierConsumption = double.Parse(txtLastTierConsumption.Text);
                                bill.WaterCharges = double.Parse(txtWaterCharges.Text);
                                bill.SewerCharges = double.Parse(txtSewerCharges.Text);
                                bill.EnvironmentCharges = double.Parse(txtEnvironmentCharges.Text);
                                bill.ServiceCharges = double.Parse(txtServiceCharges.Text);
                                bill.TotalCharges = double.Parse(txtTotalCharges.Text);
                                bill.LocalTaxes = double.Parse(txtLocalTaxes.Text);
                                bill.StateTaxes = double.Parse(txtStateTaxes.Text);
                                bill.PaymentDueDate = dtpPaymentDueDate.Value;
                                bill.AmountDue = double.Parse(txtAmountDue.Text);
                                bill.LatePaymentDueDate = dtpLatePaymentDueDate.Value;
                                bill.LateAmountDue = double.Parse(txtLateAmountDue.Text);
                            }
                        }
                    }
    
                    using (TextWriter twWaterBills = new StreamWriter(fiWaterBills.FullName))
                    {
                        xsWaterBills.Serialize(twWaterBills, bills);
                    }
                }
    
                Close();
            }
        }
    }
  15. In the Solution Explorer, right-click WaterDistribution.cs and click View Code
  16. Change the document as follows:
    namespace StellarWaterPoint50
    {
        public partial class WaterDistribution : Form
        {
            public static bool WaterMetersDisplaying;
            public static bool WaterMeterCreateDisplaying;
            public static bool WaterMeterDetailsDisplaying;
            public static bool WaterMeterEditorDisplaying;
            public static bool WaterMeterDeleteDisplaying;
    
            private WaterMeters.Central waterMeters;
            private WaterMeters.Create waterMeterCreate;
            private WaterMeters.Details waterMeterDetails;
            private WaterMeters.Editor waterMeterEditor;
            private WaterMeters.Delete waterMeterDelete;
    
            public static bool CustomersDisplaying;
            public static bool CustomerCreateDisplaying;
            public static bool CustomerDetailsDisplaying;
            public static bool CustomerEditorDisplaying;
            public static bool CustomerDeleteDisplaying;
    
            private Customers.Central customers;
            private Customers.Create customerCreate;
            private Customers.Details customerDetails;
            private Customers.Editor customerEditor;
            private Customers.Delete customerDelete;
    
            public static bool WaterBillsDisplaying;
            public static bool WaterBillCreateDisplaying;
            public static bool WaterBillDetailsDisplaying;
            public static bool WaterBillEditorDisplaying;
    
            private WaterBills.Central waterBills;
            private WaterBills.Create  waterBillCreate;
            private WaterBills.Details waterBillDetails;
            private WaterBills.Editor  waterBillEditor;
    
            public WaterDistribution()
            {
                InitializeComponent();
    
                WaterMetersDisplaying = false;
                WaterMeterCreateDisplaying = false;
                WaterMeterDetailsDisplaying = false;
                WaterMeterEditorDisplaying = false;
                WaterMeterDeleteDisplaying = false;
    
                waterMeters = new WaterMeters.Central();
                waterMeterCreate = new WaterMeters.Create();
                waterMeterDetails = new WaterMeters.Details();
                waterMeterEditor = new WaterMeters.Editor();
                waterMeterDelete = new WaterMeters.Delete();
    
                CustomersDisplaying = false;
                CustomerCreateDisplaying = false;
                CustomerDetailsDisplaying = false;
                CustomerEditorDisplaying = false;
                CustomerDeleteDisplaying = false;
    
                customers = new Customers.Central();
                customerCreate = new Customers.Create();
                customerDetails = new Customers.Details();
                customerEditor = new Customers.Editor();
                customerDelete = new Customers.Delete();
    
                WaterBillsDisplaying = false;
                WaterBillCreateDisplaying = false;
                WaterBillDetailsDisplaying = false;
                WaterBillEditorDisplaying = false;
    
                waterBills = new WaterBills.Central();
                waterBillCreate = new WaterBills.Create();
                waterBillDetails = new WaterBills.Details();
                waterBillEditor = new WaterBills.Editor();
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            . . .
        }
    }
  17. In the Solution Explorer, in the WaterBills folder, double-click Editor
  18. Click an unoccupied area of the form to select it
  19. In the Solution Explorer, click the Events button Events
  20. In the Events section of the Properties window, double-click FormClosing
  21. Return to the Editor form and double-click the Close button
  22. Implement the events as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.WaterBills
    {
        public partial class Editor : Form
        {
            public Editor()
            {
                InitializeComponent();
            }
    
            private void btnFindWaterBill_Click(object sender, EventArgs e)
            {
                if (string.IsNullOrEmpty(txtBillNumber.Text))
                {
                    MessageBox.Show("You must provide a bill number for the water bill you are trying to creator save.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                string strWaterBills       = string.Empty;
                List<WaterBill> bills      = new List<WaterBill>();
                string fileWaterBills      = @"C:\Stellar Water Point8\WaterBills.xml";
                XmlSerializer xsWaterBills = new XmlSerializer(typeof(List<WaterBill>));
    
                FileInfo fiWaterBills      = new FileInfo(fileWaterBills);
    
                if(fiWaterBills.Exists     == true)
                {
                    using(TextReader trWaterBills          = new StreamReader(fiWaterBills.FullName))
                    {
                        bills = (List<WaterBill>)xsWaterBills.Deserialize(trWaterBills)!;
    
                        IEnumerable<WaterBill> invoices    = bills.Where(invoice => invoice.BillNumber == txtBillNumber.Text);
    
                        foreach (WaterBill bill in invoices)
                        {
                            mtbAccountNumber.Text          = bill.AccountNumber;
                            dtpMeterReadingStartDate.Value = bill.MeterReadingStartDate;
                            dtpMeterReadingEndDate.Value   = bill.MeterReadingEndDate;
                            txtBillingDays.Text            = bill.BillingDays.ToString();
                            txtCounterReadingStart.Text    = bill.CounterReadingStart.ToString();
                            txtCounterReadingEnd.Text      = bill.CounterReadingEnd.ToString();
                            txtTotalHCF.Text               = bill.TotalHCF.ToString();
                            txtTotalGallons.Text           = bill.TotalGallons.ToString();
                            txtFirstTierConsumption.Text   = bill.FirstTierConsumption.ToString();
                            txtSecondTierConsumption.Text  = bill.SecondTierConsumption.ToString();
                            txtLastTierConsumption.Text    = bill.LastTierConsumption.ToString();
                            txtWaterCharges.Text           = bill.WaterCharges.ToString();
                            txtSewerCharges.Text           = bill.SewerCharges.ToString();
                            txtEnvironmentCharges.Text     = bill.EnvironmentCharges.ToString();
                            txtServiceCharges.Text         = bill.ServiceCharges.ToString();
                            txtTotalCharges.Text           = bill.TotalCharges.ToString();
                            txtLocalTaxes.Text             = bill.LocalTaxes.ToString();
                            txtStateTaxes.Text             = bill.StateTaxes.ToString();
                            dtpPaymentDueDate.Value        = bill.PaymentDueDate;
                            txtAmountDue.Text              = bill.AmountDue.ToString();
                            dtpLatePaymentDueDate.Value    = bill.LatePaymentDueDate;
                            txtLateAmountDue.Text          = bill.LateAmountDue.ToString();
                        }
                    }
                }
    
                List<Customer> clients = new List<Customer>();
                string strCustomers = @"C:\Stellar Water Point8\Customers.xml";
                XmlSerializer xsCustomers = new XmlSerializer(typeof(List<Customer>));
    
                FileInfo fiCustomers = new FileInfo(strCustomers);
    
                string? strMeterNumber = string.Empty;
    
                if (fiCustomers.Exists == true)
                {
                    using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
                    {
                        clients = (List<Customer>)xsCustomers.Deserialize(trCustomers)!;
    
                        clients.ForEach(client       =>
                        {
                            if (client.AccountNumber == mtbAccountNumber.Text)
                            {
                                txtAccountName.Text  = client.AccountName;
                                txtAccountType.Text  = client.AccountType;
                                strMeterNumber       = client.MeterNumber;
                                txtAddress.Text      = client.Address;
                                txtCity.Text         = client.City;
                                txtCounty.Text       = client.County;
                                txtState.Text        = client.State;
                                txtZIPCode.Text      = client.ZIPCode;
                            }
                        });
                    }
                }
    
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        WaterMeter? meter = waterMeters.Find(m => m.MeterNumber == strMeterNumber)!;
    
                        if (meter is not null)
                        {
                            txtMeterDetails.Text = meter.Make + " " + meter.Model + " (Mtr Size: " + meter.MeterSize + ")";
                        }
                    }
                }
            }
    
            private void btnFindCustomerAccount_Click(object sender, EventArgs e)
            {
                string strActual = mtbAccountNumber.Text.Replace(" ", "").Replace("-", "");
    
                if (string.IsNullOrEmpty(strActual))
                {
                    MessageBox.Show("You must type a valid account number of " +
                                    "a customer whose account you want to view.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                List<Customer> clients = new List<Customer>();
                string strCustomers = @"C:\Stellar Water Point8\Customers.xml";
                XmlSerializer xsCustomers = new XmlSerializer(typeof(List<Customer>));
    
                FileInfo fiCustomers = new FileInfo(strCustomers);
    
                string? strMeterNumber = string.Empty;
    
                if (fiCustomers.Exists == true)
                {
                    using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
                    {
                        clients = (List<Customer>)xsCustomers.Deserialize(trCustomers)!;
    
                        clients.ForEach(client =>
                        {
                            if (client.AccountNumber == mtbAccountNumber.Text)
                            {
                                txtAccountName.Text = client.AccountName;
                                txtAccountType.Text = client.AccountType;
                                strMeterNumber      = client.MeterNumber;
                                txtAddress.Text     = client.Address;
                                txtCity.Text        = client.City;
                                txtCounty.Text      = client.County;
                                txtState.Text       = client.State;
                                txtZIPCode.Text     = client.ZIPCode;
                            }
                        });
                    }
                }
    
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        WaterMeter? meter = waterMeters.Find(m => m.MeterNumber == strMeterNumber)!;
    
                        if (meter is not null)
                        {
                            txtMeterDetails.Text = meter.Make + " " + meter.Model + " (Mtr Size: " + meter.MeterSize + ")";
                        }
                    }
                }
            }
    
            private void dtpMeterReadingEndDate_ValueChanged(object sender, EventArgs e)
            {
                TimeSpan tsDays = dtpMeterReadingEndDate.Value - dtpMeterReadingStartDate.Value;
    
                txtBillingDays.Text = (tsDays.Days + 1).ToString();
            }
    
            private void btnEvaluateWaterBill_Click(object sender, EventArgs e)
            {
                double counterStart = 0d, counterEnd = 0d;
    
                try
                {
                    counterStart = double.Parse(txtCounterReadingStart.Text);
                }
                catch (FormatException feCRStart)
                {
                    MessageBox.Show("You must enter a valid value in the Counter Reading Start text box. " +
                                    "The error produced is: " + feCRStart.Message,
                                    "Stellar Water Point", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
    
                try
                {
                    counterEnd = double.Parse(txtCounterReadingEnd.Text);
                }
                catch (FormatException feCREnd)
                {
                    MessageBox.Show("You must enter a valid value in the Counter Reading End text box. " +
                                    "The error produced is: " + feCREnd.Message,
                                    "Stellar Water Point", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
    
                double consumption            = counterEnd - counterStart;
                double gallons                = consumption * 748.05;
                string strAccountType         = txtAccountType.Text[..3];
    
                (double first, double second, double last) tiers = WaterBillManager.CalculateTiers(strAccountType, gallons);
    
                double waterCharges           = tiers.first + tiers.second + tiers.last;
                double sewerCharges           = WaterBillManager.CalculateSewerCharges(strAccountType, waterCharges);
                double envCharges             = WaterBillManager.CalculateEnvironmentCharges(strAccountType, waterCharges);
                double srvCharges             = WaterBillManager.CalculateServiceCharges(strAccountType, waterCharges);
                double totalCharges           = waterCharges + sewerCharges + envCharges + srvCharges;
                double localTaxes             = WaterBillManager.CalculateLocalTaxes(strAccountType, waterCharges);
                double stateTaxes             = WaterBillManager.CalculateStateTaxes(strAccountType, waterCharges);
                double amtDue                 = totalCharges + localTaxes + stateTaxes;
    
                txtTotalHCF.Text              = consumption.ToString();
                txtTotalGallons.Text          = ((int)(Math.Ceiling(gallons))).ToString();
                txtFirstTierConsumption.Text  = tiers.first.ToString("F");
                txtSecondTierConsumption.Text = tiers.second.ToString("F");
                txtLastTierConsumption.Text   = tiers.last.ToString("F");
                txtWaterCharges.Text          = waterCharges.ToString("F");
                txtSewerCharges.Text          = sewerCharges.ToString("F");
                txtEnvironmentCharges.Text    = envCharges.ToString("F");
                txtServiceCharges.Text        = srvCharges.ToString("F");
                txtTotalCharges.Text          = totalCharges.ToString("F");
                txtLocalTaxes.Text            = localTaxes.ToString("F");
                txtStateTaxes.Text            = stateTaxes.ToString("F");
                dtpPaymentDueDate.Value       = WaterBillManager.SetPaymentDueDate(strAccountType, dtpMeterReadingEndDate.Value);
                txtAmountDue.Text             = amtDue.ToString("F");
                dtpLatePaymentDueDate.Value   = WaterBillManager.SetLatePaymentDueDate(strAccountType, dtpMeterReadingEndDate.Value);
                txtLateAmountDue.Text         = WaterBillManager.CalculateLateAmountDue(strAccountType, amtDue).ToString("F");
            }
    
            private void btnUpdateWaterBill_Click(object sender, EventArgs e)
            {
                if (string.IsNullOrEmpty(txtBillNumber.Text))
                {
                    MessageBox.Show("You must provide a bill number for the water bill you are trying to update.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                string strAccountNumber = mtbAccountNumber.Text.Replace(" ", "").Replace("-", "");
    
                if (string.IsNullOrEmpty(strAccountNumber) | string.IsNullOrEmpty(txtAccountName.Text))
                {
                    MessageBox.Show("You must provide an account number of the customer " +
                                    "whose water bill you are trying to update. " +
                                    "After providing the account number, click the Find Customer Account button.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                string strWaterBills       = string.Empty;
                List<WaterBill> bills      = new List<WaterBill>();
                string fileWaterBills      = @"C:\Stellar Water Point8\WaterBills.xml";
                XmlSerializer xsWaterBills = new XmlSerializer(typeof(List<WaterBill>));
    
                FileInfo fiWaterBills      = new FileInfo(fileWaterBills);
    
                if (fiWaterBills.Exists    == true)
                {
                    using (TextReader trWaterBills = new StreamReader(fiWaterBills.FullName))
                    {
                        bills = (List<WaterBill>)xsWaterBills.Deserialize(trWaterBills)!;
    
                        foreach (WaterBill bill in bills)
                        {
                            if (bill.BillNumber            == txtBillNumber.Text)
                            {
                                bill.AccountNumber         =              mtbAccountNumber.Text;
                                bill.MeterReadingStartDate =              dtpMeterReadingStartDate.Value;
                                bill.MeterReadingEndDate   =              dtpMeterReadingEndDate.Value;
                                bill.BillingDays           =    int.Parse(txtBillingDays.Text);
                                bill.CounterReadingStart   =    int.Parse(txtCounterReadingStart.Text);
                                bill.CounterReadingEnd     =    int.Parse(txtCounterReadingEnd.Text);
                                bill.TotalHCF              =    int.Parse(txtTotalHCF.Text);
                                bill.TotalGallons          =    int.Parse(txtTotalGallons.Text);
                                bill.FirstTierConsumption  = double.Parse(txtFirstTierConsumption.Text);
                                bill.SecondTierConsumption = double.Parse(txtSecondTierConsumption.Text);
                                bill.LastTierConsumption   = double.Parse(txtLastTierConsumption.Text);
                                bill.WaterCharges          = double.Parse(txtWaterCharges.Text);
                                bill.SewerCharges          = double.Parse(txtSewerCharges.Text);
                                bill.EnvironmentCharges    = double.Parse(txtEnvironmentCharges.Text);
                                bill.ServiceCharges        = double.Parse(txtServiceCharges.Text);
                                bill.TotalCharges          = double.Parse(txtTotalCharges.Text);
                                bill.LocalTaxes            = double.Parse(txtLocalTaxes.Text);
                                bill.StateTaxes            = double.Parse(txtStateTaxes.Text);
                                bill.PaymentDueDate        =              dtpPaymentDueDate.Value;
                                bill.AmountDue             = double.Parse(txtAmountDue.Text);
                                bill.LatePaymentDueDate    =              dtpLatePaymentDueDate.Value;
                                bill.LateAmountDue         = double.Parse(txtLateAmountDue.Text);
                            }
                        }
                    }
    
                    using (TextWriter twWaterBills = new StreamWriter(fiWaterBills.FullName))
                    {
                        xsWaterBills.Serialize(twWaterBills, bills);
                    }
                }
    
                Close();
            }
    
            private void Editor_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (WaterDistribution.WaterBillEditorDisplaying == true)
                {
                    WaterDistribution.WaterBillEditorDisplaying = false;
                    Close();
                }
            }
    
            private void btnClose_Click(object sender, EventArgs e)
            {
                Close();
            }
        }
    }
  23. In the Solution Explorer, double-click WaterDistribution.cs to select the main form of the application
  24. On the menu bar of the form, click Water Bills and, below it, double-click Update Water Bill...
  25. Implement the event as follows:
    namespace StellarWaterPoint50
    {
        public partial class WaterDistribution : Form
        {
            . . .
    
            public WaterDistribution()
            {
                InitializeComponent();
    
                . . .   
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            . . .
    
            private void miViewWaterBills_Click(object sender, EventArgs e)
            {
                if (WaterBillsDisplaying == false)
                {
                    waterBills = new WaterBills.Central();
    
                    waterBills.MdiParent = this;
                    waterBills.Show();
    
                    WaterBillsDisplaying = true;
                }
                else
                {
                    waterBills.BringToFront();
                }
            }
    
            private void miWaterBillsCreate_Click(object sender, EventArgs e)
            {
                if (WaterBillCreateDisplaying == false)
                {
                    waterBillCreate = new WaterBills.Create();
    
                    waterBillCreate.MdiParent = this;
                    waterBillCreate.Show();
    
                    WaterBillCreateDisplaying = true;
                }
                else
                {
                    waterBillCreate.BringToFront();
                }
            }
    
            private void miWaterBillsDetails_Click(object sender, EventArgs e)
            {
                if (WaterBillDetailsDisplaying == false)
                {
                    waterBillDetails = new();
                    waterBillDetails.MdiParent = this;
                    waterBillDetails.Show();
    
                    WaterBillDetailsDisplaying = true;
                }
                else
                {
                    waterBillDetails.BringToFront();
                }
            }
    
            private void miWaterBillsEditor_Click(object sender, EventArgs e)
            {
                if (WaterBillEditorDisplaying == false)
                {
                    waterBillEditor = new();
                    waterBillEditor.MdiParent = this;
                    waterBillEditor.Show();
    
                    WaterBillEditorDisplaying = true;
                }
                else
                {
                    waterBillEditor.BringToFront();
                }
            }
        }
    }
  26. To execute the application, on the main menu, click Debug -> Start Without Debugging

  27. On the main menu of the central form of the application, click Water Meters and click View Water Meters

    Stellar Water Point - Water Bills

  28. On the main menu of the central form of the application, click Water Bills and click Update Water Bill

    Stellar Water Point - Water Bills

  29. In the Water Bill # text, type 923633
  30. Click the Find Water Bill button

    Stellar Water Point - Water Bill Editor

  31. Change the following values:
    Account #:                9249-379-6848 and click Find Customer Account
    Meter Reading Start Date: 1/19/2010
    Meter Reading End Date:   4/17/2010
    Counter Reading Start:    256953
    Counter Reading End:      256966
  32. Click the Evaluate Water Bill button:

    Stellar Water Point - Update Water Bill

  33. Click the Update Water Bill button and click OK on the message box:

    Stellar Water Point - Water Bills

  34. Close the forms and return to your programming environment

Deleting a Water Bill

.

Practical LearningPractical Learning: Deleting a Water Bill

  1. To create a form, in the Solution Explorer, right-click WaterBills -> Add -> Form(Windows Forms)...
  2. In the Name text box, replace the string with Delete as the name of the form
  3. Press Enter
  4. Design the form as follows:

    Stellar Water Point - Customer Account Deletion

    Control Text Name Other Properties
    Label Label &Water Bill #:    
    TextBox Text Box   txtBillNumber  
    Button Button &Find Water Bill btnFindWaterBill  
    GroupBox Group Box Customer Information    
    Label Label &Account #:    
    TextBox Text Box   txtAccountNumber Enabled: False
    Label Label Account Name:    
    TextBox Text Box   txtAccountName Enabled: False
    Label Label Account Type:    
    TextBox Text Box   txtAccountType Enabled: False
    Label Label Address:   Enabled: False
    TextBox Text Box   txtAddress Enabled: False
    TextBox Text Box   txtCity  
    TextBox Text Box   txtCounty Enabled: False
    TextBox Text Box   txtState Enabled: False
    TextBox Text Box   txtZIPCode Enabled: False
    Label Label ________________________________    
    Label Label Meter Details:    
    TextBox Text Box   txtMeterDetails Enabled: False
    GroupBox Group Box Meter Reading    
    Label Label Meter &Reading Start Date:    
    Text Box Text Box   txtMeterReadingStartDate Enabled: False
    Label Label Meter Reading &End Date:    
    Text Box Text Box   txtMeterReadingEndDate Enabled: False
    Label Label Coun&ter Reading Start:    
    TextBox Text Box   txtCounterReadingStart Enabled: False
    Label Label Counter Readi&ng End:    
    TextBox Text Box   txtCounterReadingEnd Enabled: False
    GroupBox Group Box Meter Result    
    Label Label Billing Days:    
    TextBox Text Box   txtBillingDays Enabled: False
    Label Label Total HCF:    
    TextBox Text Box   txtTotalHCF Enabled: False
    Label Label Total Gallons:    
    TextBox Text Box   txtTotalGallons Enabled: False
    Label Label First Tier Consumption:    
    TextBox Text Box   txtFirstTierConsumption Enabled: False
    Label Label Second Tier:    
    TextBox Text Box   txtSecondTierConsumption Enabled: False
    Label Label Last Tier:    
    TextBox Text Box   txtLastTierConsumption Enabled: False
    GroupBox Group Box Consumption Charges    
    Label Label Water Charges:    
    TextBox Text Box   txtWaterCharges Enabled: False
    Label Label Sewer Charges:    
    TextBox Text Box   txtSewerCharges Enabled: False
    Label Label Environment Charges:    
    TextBox Text Box   txtEnvironmentCharges Enabled: False
    Label Label Service Charges:    
    TextBox Text Box   txtServiceCharges Enabled: False
    Label Label Total Charges:    
    TextBox Text Box   txtTotalCharges Enabled: False
    GroupBox Group Box Taxes    
    Label Label Local Taxes:    
    TextBox Text Box   txtLocalTaxes Enabled: False
    Label Label State Taxes:    
    TextBox Text Box   txtStateTaxes Enabled: False
    GroupBox Group Box Water Bill Payment    
    Label Label Payment Due Date:    
    Date Time Picker Text Box   dtpPaymentDueDate Enabled: False
    Label Label Amount Due:    
    TextBox Text Box   txtAmountDue Enabled: False
    Label Label Late Payment Due Date:    
    Text Box Text Box   txtLatePaymentDueDate Enabled: False
    Label Label &Late Amount Due:    
    TextBox Text Box   txtLateAmountDue  
    Button Button &Delete Water Bill btnDeleteWaterBill  
    Button Button &Close btnClose  
  5. On the form, double-click the Find Water Bill button
  6. Change the document as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.WaterBills
    {
        public partial class Delete: Form
        {
            public Delete()
            {
                InitializeComponent();
            }
    
            private void btnFindWaterBillAccount_Click(object sender, EventArgs e)
            {
                
            }
        }
    }
  7. Return to the form and double-click the Delete Water Bill button
  8. Implement the events as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.WaterBills
    {
        public partial class Delete : Form
        {
            public Delete()
            {
                InitializeComponent();
            }
    
            private void btnFindWaterBill_Click(object sender, EventArgs e)
            {
                if (string.IsNullOrEmpty(txtBillNumber.Text))
                {
                    MessageBox.Show("You must provide a bill number for the water bill you are trying to creator save.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                string strWaterBills = string.Empty;
                List<WaterBill> bills = new List<WaterBill>();
                string fileWaterBills = @"C:\Stellar Water Point8\WaterBills.xml";
                XmlSerializer xsWaterBills = new XmlSerializer(typeof(List<WaterBill>));
    
                FileInfo fiWaterBills = new FileInfo(fileWaterBills);
    
                string? strAccountNumber = string.Empty;
    
                if (fiWaterBills.Exists == true)
                {
                    using (TextReader trWaterBills = new StreamReader(fiWaterBills.FullName))
                    {
                        bills = (List<WaterBill>)xsWaterBills.Deserialize(trWaterBills)!;
    
                        IEnumerable<WaterBill> invoices = bills.Where(invoice => invoice.BillNumber == txtBillNumber.Text);
    
                        foreach (WaterBill bill in invoices)
                        {
                            txtAccountNumber.Text = bill.AccountNumber;
                            txtMeterReadingStartDate.Text = bill.MeterReadingStartDate.ToLongDateString();
                            txtMeterReadingEndDate.Text = bill.MeterReadingEndDate.ToLongDateString();
                            txtBillingDays.Text = bill.BillingDays.ToString();
                            txtCounterReadingStart.Text = bill.CounterReadingStart.ToString();
                            txtCounterReadingEnd.Text = bill.CounterReadingEnd.ToString();
                            txtTotalHCF.Text = bill.TotalHCF.ToString();
                            txtTotalGallons.Text = bill.TotalGallons.ToString();
                            txtFirstTierConsumption.Text = bill.FirstTierConsumption.ToString();
                            txtSecondTierConsumption.Text = bill.SecondTierConsumption.ToString();
                            txtLastTierConsumption.Text = bill.LastTierConsumption.ToString();
                            txtWaterCharges.Text = bill.WaterCharges.ToString();
                            txtSewerCharges.Text = bill.SewerCharges.ToString();
                            txtEnvironmentCharges.Text = bill.EnvironmentCharges.ToString();
                            txtServiceCharges.Text = bill.ServiceCharges.ToString();
                            txtTotalCharges.Text = bill.TotalCharges.ToString();
                            txtLocalTaxes.Text = bill.LocalTaxes.ToString();
                            txtStateTaxes.Text = bill.StateTaxes.ToString();
                            txtPaymentDueDate.Text = bill.PaymentDueDate.ToLongDateString();
                            txtAmountDue.Text = bill.AmountDue.ToString();
                            txtLatePaymentDueDate.Text = bill.LatePaymentDueDate.ToLongDateString();
                            txtLateAmountDue.Text = bill.LateAmountDue.ToString();
                        }
                    }
                }
    
                List<Customer> clients = new List<Customer>();
                string strCustomers = @"C:\Stellar Water Point8\Customers.xml";
                XmlSerializer xsCustomers = new XmlSerializer(typeof(List<Customer>));
    
                FileInfo fiCustomers = new FileInfo(strCustomers);
    
                string? strMeterNumber = string.Empty;
    
                if (fiCustomers.Exists == true)
                {
                    using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
                    {
                        clients = (List<Customer>)xsCustomers.Deserialize(trCustomers)!;
    
                        clients.ForEach(client =>
                        {
                            if (client.AccountNumber == txtAccountNumber.Text)
                            {
                                txtAccountName.Text = client.AccountName;
                                txtAccountType.Text = client.AccountType;
                                strMeterNumber = client.MeterNumber;
                                txtAddress.Text = client.Address;
                                txtCity.Text = client.City;
                                txtCounty.Text = client.County;
                                txtState.Text = client.State;
                                txtZIPCode.Text = client.ZIPCode;
                            }
                        });
                    }
                }
    
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        WaterMeter? meter = waterMeters.Find(m => m.MeterNumber == strMeterNumber)!;
    
                        if (meter is not null)
                        {
                            txtMeterDetails.Text = meter.Make + " " + meter.Model + " (Mtr Size: " + meter.MeterSize + ")";
                        }
                    }
                }
            }
    
            private void btnDeleteWaterBill_Click(object sender, EventArgs e)
            {
                if (string.IsNullOrEmpty(txtBillNumber.Text))
                {
                    MessageBox.Show("You must provide a bill number for the water bill you are trying to update.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                string strWaterBills       = string.Empty;
                List<WaterBill> bills      = new List<WaterBill>();
                string fileWaterBills      = @"C:\Stellar Water Point8\WaterBills.xml";
                XmlSerializer xsWaterBills = new XmlSerializer(typeof(List<WaterBill>));
    
                FileInfo fiWaterBills      = new FileInfo(fileWaterBills);
    
                if (fiWaterBills.Exists    == true)
                {
                    using (TextReader trWaterBills = new StreamReader(fiWaterBills.FullName))
                    {
                        bills = (List<WaterBill>)xsWaterBills.Deserialize(trWaterBills)!;
    
                        foreach (WaterBill bill in bills)
                        {
                            if(bill.BillNumber == txtBillNumber.Text)
                            {
                                if(MessageBox.Show("Are you sure you want to delete (or cancel) this water invoice " +
                                                   "whose bill number is " + txtBillNumber.Text + "?",
                                                   "Stellar Water Point",
                                                   MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes)
                                {
                                    bills.Remove(bill);
    
                                    MessageBox.Show("The water bill whose bill number is " +
                                                    txtBillNumber.Text + " has been canceled (or deleted from our system).",
                                                    "Stellar Water Point",
                                                    MessageBoxButtons.OK, MessageBoxIcon.Information);
                                    break;
                                }                
                            }
                        }
                    }
    
                    using (TextWriter twWaterBills = new StreamWriter(fiWaterBills.FullName))
                    {
                        xsWaterBills.Serialize(twWaterBills, bills);
                    }
                }
    
                Close();
            }
        }
    }
  9. In the Solution Explorer, right-click WaterDistribution.cs and click View Code
  10. Change the document as follows:
    namespace StellarWaterPoint50
    {
        public partial class WaterDistribution : Form
        {
            public static bool WaterMetersDisplaying;
            public static bool WaterMeterCreateDisplaying;
            public static bool WaterMeterDetailsDisplaying;
            public static bool WaterMeterEditorDisplaying;
            public static bool WaterMeterDeleteDisplaying;
    
            private WaterMeters.Central waterMeters;
            private WaterMeters.Create waterMeterCreate;
            private WaterMeters.Details waterMeterDetails;
            private WaterMeters.Editor waterMeterEditor;
            private WaterMeters.Delete waterMeterDelete;
    
            public static bool CustomersDisplaying;
            public static bool CustomerCreateDisplaying;
            public static bool CustomerDetailsDisplaying;
            public static bool CustomerEditorDisplaying;
            public static bool CustomerDeleteDisplaying;
    
            private Customers.Central customers;
            private Customers.Create customerCreate;
            private Customers.Details customerDetails;
            private Customers.Editor customerEditor;
            private Customers.Delete customerDelete;
    
            public static bool WaterBillsDisplaying;
            public static bool WaterBillCreateDisplaying;
            public static bool WaterBillDetailsDisplaying;
            public static bool WaterBillEditorDisplaying;
            public static bool WaterBillDeleteDisplaying;
    
            private WaterBills.Central waterBills;
            private WaterBills.Create waterBillCreate;
            private WaterBills.Details waterBillDetails;
            private WaterBills.Editor waterBillEditor;
            private WaterBills.Delete waterBillDelete;
    
            public WaterDistribution()
            {
                InitializeComponent();
    
                WaterMetersDisplaying = false;
                WaterMeterCreateDisplaying = false;
                WaterMeterDetailsDisplaying = false;
                WaterMeterEditorDisplaying = false;
                WaterMeterDeleteDisplaying = false;
    
                waterMeters = new WaterMeters.Central();
                waterMeterCreate = new WaterMeters.Create();
                waterMeterDetails = new WaterMeters.Details();
                waterMeterEditor = new WaterMeters.Editor();
                waterMeterDelete = new WaterMeters.Delete();
    
                CustomersDisplaying = false;
                CustomerCreateDisplaying = false;
                CustomerDetailsDisplaying = false;
                CustomerEditorDisplaying = false;
                CustomerDeleteDisplaying = false;
    
                customers = new Customers.Central();
                customerCreate = new Customers.Create();
                customerDetails = new Customers.Details();
                customerEditor = new Customers.Editor();
                customerDelete = new Customers.Delete();
    
                WaterBillsDisplaying = false;
                WaterBillCreateDisplaying = false;
                WaterBillDetailsDisplaying = false;
                WaterBillEditorDisplaying = false;
                WaterBillDeleteDisplaying = false;
    
                waterBills = new WaterBills.Central();
                waterBillCreate = new WaterBills.Create();
                waterBillDetails = new WaterBills.Details();
                waterBillEditor = new WaterBills.Editor();
                waterBillDelete = new WaterBills.Delete();
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            . . .
    
        }
    }
  11. In the Solution Explorer, in the WaterBills folder, double-click Delete
  12. Click an unoccupied area of the form to select it
  13. In the Solution Explorer, click the Events button Events
  14. In the Events section of the Properties window, double-click FormClosing
  15. Return to the form and double-click the Close button
  16. Implement the events as follows:
    using System.Xml.Serialization;
    using StellarWaterPoint50.Models;
    
    namespace StellarWaterPoint50.WaterBills
    {
        public partial class Delete : Form
        {
            public Delete()
            {
                InitializeComponent();
            }
    
            private void btnFindWaterBill_Click(object sender, EventArgs e)
            {
                if (string.IsNullOrEmpty(txtBillNumber.Text))
                {
                    MessageBox.Show("You must provide a bill number for the water bill you are trying to creator save.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                string strWaterBills       = string.Empty;
                List<WaterBill> bills      = new List<WaterBill>();
                string fileWaterBills      = @"C:\Stellar Water Point8\WaterBills.xml";
                XmlSerializer xsWaterBills = new XmlSerializer(typeof(List<WaterBill>));
    
                FileInfo fiWaterBills = new FileInfo(fileWaterBills);
    
                string? strAccountNumber   = string.Empty;
    
                if (fiWaterBills.Exists    == true)
                {
                    using (TextReader trWaterBills = new StreamReader(fiWaterBills.FullName))
                    {
                        bills = (List<WaterBill>)xsWaterBills.Deserialize(trWaterBills)!;
    
                        IEnumerable<WaterBill> invoices = bills.Where(invoice => invoice.BillNumber == txtBillNumber.Text);
    
                        foreach (WaterBill bill in invoices)
                        {
                            txtAccountNumber.Text         = bill.AccountNumber;
                            txtMeterReadingStartDate.Text = bill.MeterReadingStartDate.ToLongDateString();
                            txtMeterReadingEndDate.Text   = bill.MeterReadingEndDate.ToLongDateString();
                            txtBillingDays.Text           = bill.BillingDays.ToString();
                            txtCounterReadingStart.Text   = bill.CounterReadingStart.ToString();
                            txtCounterReadingEnd.Text     = bill.CounterReadingEnd.ToString();
                            txtTotalHCF.Text              = bill.TotalHCF.ToString();
                            txtTotalGallons.Text          = bill.TotalGallons.ToString();
                            txtFirstTierConsumption.Text  = bill.FirstTierConsumption.ToString();
                            txtSecondTierConsumption.Text = bill.SecondTierConsumption.ToString();
                            txtLastTierConsumption.Text   = bill.LastTierConsumption.ToString();
                            txtWaterCharges.Text          = bill.WaterCharges.ToString();
                            txtSewerCharges.Text          = bill.SewerCharges.ToString();
                            txtEnvironmentCharges.Text    = bill.EnvironmentCharges.ToString();
                            txtServiceCharges.Text        = bill.ServiceCharges.ToString();
                            txtTotalCharges.Text          = bill.TotalCharges.ToString();
                            txtLocalTaxes.Text            = bill.LocalTaxes.ToString();
                            txtStateTaxes.Text            = bill.StateTaxes.ToString();
                            txtPaymentDueDate.Text        = bill.PaymentDueDate.ToLongDateString();
                            txtAmountDue.Text             = bill.AmountDue.ToString();
                            txtLatePaymentDueDate.Text    = bill.LatePaymentDueDate.ToLongDateString();
                            txtLateAmountDue.Text         = bill.LateAmountDue.ToString();
                        }
                    }
                }
    
                List<Customer> clients    = new List<Customer>();
                string strCustomers       = @"C:\Stellar Water Point8\Customers.xml";
                XmlSerializer xsCustomers = new XmlSerializer(typeof(List<Customer>));
    
                FileInfo fiCustomers      = new FileInfo(strCustomers);
    
                string? strMeterNumber    = string.Empty;
    
                if (fiCustomers.Exists    == true)
                {
                    using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
                    {
                        clients = (List<Customer>)xsCustomers.Deserialize(trCustomers)!;
    
                        clients.ForEach(client =>
                        {
                            if (client.AccountNumber == txtAccountNumber.Text)
                            {
                                txtAccountName.Text  = client.AccountName;
                                txtAccountType.Text  = client.AccountType;
                                strMeterNumber       = client.MeterNumber;
                                txtAddress.Text      = client.Address;
                                txtCity.Text         = client.City;
                                txtCounty.Text       = client.County;
                                txtState.Text        = client.State;
                                txtZIPCode.Text      = client.ZIPCode;
                            }
                        });
                    }
                }
    
                List<WaterMeter> waterMeters = new List<WaterMeter>();
                string strWaterMeters = @"C:\Stellar Water Point8\WaterMeters.xml";
                XmlSerializer xsWaterMeters = new XmlSerializer(typeof(List<WaterMeter>));
    
                FileInfo fiWaterMeters = new FileInfo(strWaterMeters);
    
                if (fiWaterMeters.Exists == true)
                {
                    using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
                    {
                        waterMeters = (List<WaterMeter>)xsWaterMeters.Deserialize(trWaterMeters)!;
    
                        WaterMeter? meter = waterMeters.Find(m => m.MeterNumber == strMeterNumber)!;
    
                        if (meter is not null)
                        {
                            txtMeterDetails.Text = meter.Make + " " + meter.Model + " (Mtr Size: " + meter.MeterSize + ")";
                        }
                    }
                }
            }
    
            private void btnDeleteWaterBill_Click(object sender, EventArgs e)
            {
                if (string.IsNullOrEmpty(txtBillNumber.Text))
                {
                    MessageBox.Show("You must provide a bill number for the water bill you are trying to update.",
                                    "Stellar Water Point", MessageBoxButtons.OK);
                    return;
                }
    
                string strWaterBills       = string.Empty;
                List<WaterBill> bills      = new List<WaterBill>();
                string fileWaterBills      = @"C:\Stellar Water Point8\WaterBills.xml";
                XmlSerializer xsWaterBills = new XmlSerializer(typeof(List<WaterBill>));
    
                FileInfo fiWaterBills      = new FileInfo(fileWaterBills);
    
                if (fiWaterBills.Exists    == true)
                {
                    using (TextReader trWaterBills = new StreamReader(fiWaterBills.FullName))
                    {
                        bills = (List<WaterBill>)xsWaterBills.Deserialize(trWaterBills)!;
    
                        foreach (WaterBill bill in bills)
                        {
                            if(bill.BillNumber == txtBillNumber.Text)
                            {
                                if(MessageBox.Show("Are you sure you want to delete (or cancel) this water invoice " +
                                                   "whose bill number is " + txtBillNumber.Text + "?",
                                                   "Stellar Water Point",
                                                   MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes)
                                {
                                    bills.Remove(bill);
    
                                    MessageBox.Show("The water bill whose bill number is " +
                                                    txtBillNumber.Text + " has been canceled (or deleted from our system).",
                                                    "Stellar Water Point",
                                                    MessageBoxButtons.OK, MessageBoxIcon.Information);
                                    break;
                                }                
                            }
                        }
                    }
    
                    using (TextWriter twWaterBills = new StreamWriter(fiWaterBills.FullName))
                    {
                        xsWaterBills.Serialize(twWaterBills, bills);
                    }
                }
    
                Close();
            }
    
            private void Delete_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (WaterDistribution.WaterBillDeleteDisplaying == true)
                {
                    WaterDistribution.WaterBillDeleteDisplaying = false;
                    Close();
                }
            }
    
            private void btnClose_Click(object sender, EventArgs e)
            {
                Close();
            }
        }
    }
  17. In the Solution Explorer, double-click WaterDistribution.cs to display the central form of the application
  18. On the menu bar of the form, click Water Bills and, below it, double-click Delete Water Bill...
  19. Return to the form
  20. On the menu bar of the form, click Help and, below it, About Stellar Water Point
  21. Return to the form
  22. On the menu bar of the form, click File and, below it, double-click Exit
  23. Implement the events as follows:
    namespace StellarWaterPoint50
    {
        public partial class WaterDistribution : Form
        {
            public static bool              WaterMetersDisplaying;
            public static bool              WaterMeterCreateDisplaying;
            public static bool              WaterMeterDetailsDisplaying;
            public static bool              WaterMeterEditorDisplaying;
            public static bool              WaterMeterDeleteDisplaying;
    
            private WaterMeters.Central     waterMeters;
            private WaterMeters.Create      waterMeterCreate;
            private WaterMeters.Details     waterMeterDetails;
            private WaterMeters.Editor      waterMeterEditor;
            private WaterMeters.Delete      waterMeterDelete;
    
            public static bool              CustomersDisplaying;
            public static bool              CustomerCreateDisplaying;
            public static bool              CustomerDetailsDisplaying;
            public static bool              CustomerEditorDisplaying;
            public static bool              CustomerDeleteDisplaying;
    
            private Customers.Central       customers;
            private Customers.Create        customerCreate;
            private Customers.Details       customerDetails;
            private Customers.Editor        customerEditor;
            private Customers.Delete        customerDelete;
    
            public static bool              WaterBillsDisplaying;
            public static bool              WaterBillCreateDisplaying;
            public static bool              WaterBillDetailsDisplaying;
            public static bool              WaterBillEditorDisplaying;
            public static bool              WaterBillDeleteDisplaying;
    
            private WaterBills.Central      waterBills;
            private WaterBills.Create       waterBillCreate;
            private WaterBills.Details      waterBillDetails;
            private WaterBills.Editor       waterBillEditor;
            private WaterBills.Delete       waterBillDelete;
    
            public WaterDistribution()
            {
                InitializeComponent();
    
                WaterMetersDisplaying       = false;
                WaterMeterCreateDisplaying  = false;
                WaterMeterDetailsDisplaying = false;
                WaterMeterEditorDisplaying  = false;
                WaterMeterDeleteDisplaying  = false;
    
                waterMeters                 = new WaterMeters.Central();
                waterMeterCreate            = new WaterMeters.Create();
                waterMeterDetails           = new WaterMeters.Details();
                waterMeterEditor            = new WaterMeters.Editor();
                waterMeterDelete            = new WaterMeters.Delete();
    
                CustomersDisplaying         = false;
                CustomerCreateDisplaying    = false;
                CustomerDetailsDisplaying   = false;
                CustomerEditorDisplaying    = false;
                CustomerDeleteDisplaying    = false;
    
                customers                   = new Customers.Central();
                customerCreate              = new Customers.Create();
                customerDetails             = new Customers.Details();
                customerEditor              = new Customers.Editor();
                customerDelete              = new Customers.Delete();
    
                WaterBillsDisplaying        = false;
                WaterBillCreateDisplaying   = false;
                WaterBillDetailsDisplaying  = false;
                WaterBillEditorDisplaying   = false;
                WaterBillDeleteDisplaying   = false;
    
                waterBills                  = new WaterBills.Central();
                waterBillCreate             = new WaterBills.Create();
                waterBillDetails            = new WaterBills.Details();
                waterBillEditor             = new WaterBills.Editor();
                waterBillDelete             = new WaterBills.Delete();
            }
    
            private void WaterDistribution_Load(object sender, EventArgs e)
            {
                Directory.CreateDirectory(@"C:\Stellar Water Point8");
            }
    
            private void miWindowArrange_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.ArrangeIcons);
            }
    
            private void miWindowCascade_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.Cascade);
            }
    
            private void miWindowTileHorizontal_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.TileHorizontal);
            }
    
            private void miWindowTileVertical_Click(object sender, EventArgs e)
            {
                LayoutMdi(MdiLayout.TileVertical);
            }
    
            private void miWaterMetersView_Click(object sender, EventArgs e)
            {
                if (WaterMetersDisplaying == false)
                {
                    waterMeters = new WaterMeters.Central();
    
                    waterMeters.MdiParent = this;
                    waterMeters.Show();
    
                    WaterMetersDisplaying = true;
                }
                else
                {
                    waterMeters.BringToFront();
                }
            }
    
            private void miWaterMetersCreate_Click(object sender, EventArgs e)
            {
                if (WaterMeterCreateDisplaying == false)
                {
                    waterMeterCreate = new();
                    waterMeterCreate.MdiParent = this;
                    waterMeterCreate.Show();
    
                    WaterMeterCreateDisplaying = true;
                }
                else
                {
                    waterMeterCreate.BringToFront();
                }
            }
    
            private void miWaterMetersDetails_Click(object sender, EventArgs e)
            {
                if (WaterMeterDetailsDisplaying == false)
                {
                    waterMeterDetails = new();
                    waterMeterDetails.MdiParent = this;
                    waterMeterDetails.Show();
    
                    WaterMeterDetailsDisplaying = true;
                }
                else
                {
                    waterMeterDetails.BringToFront();
                }
            }
    
            private void miWaterMetersEditor_Click(object sender, EventArgs e)
            {
                if (WaterMeterEditorDisplaying == false)
                {
                    waterMeterEditor = new();
                    waterMeterEditor.MdiParent = this;
                    waterMeterEditor.Show();
    
                    WaterMeterEditorDisplaying = true;
                }
                else
                {
                    waterMeterEditor.BringToFront();
                }
            }
    
            private void miWaterMetersDelete_Click(object sender, EventArgs e)
            {
                if (WaterMeterDeleteDisplaying == false)
                {
                    waterMeterDelete = new();
                    waterMeterDelete.MdiParent = this;
                    waterMeterDelete.Show();
    
                    WaterMeterDeleteDisplaying = true;
                }
                else
                {
                    waterMeterDelete.BringToFront();
                }
            }
    
            private void miViewCustomers_Click(object sender, EventArgs e)
            {
                if (CustomersDisplaying == false)
                {
                    customers = new Customers.Central();
    
                    customers.MdiParent = this;
                    customers.Show();
    
                    CustomersDisplaying = true;
                }
                else
                {
                    customers.BringToFront();
                }
            }
    
            private void miCustomersCreate_Click(object sender, EventArgs e)
            {
                if (CustomerCreateDisplaying == false)
                {
                    customerCreate = new();
                    customerCreate.MdiParent = this;
                    customerCreate.Show();
    
                    CustomerCreateDisplaying = true;
                }
                else
                {
                    customerCreate.BringToFront();
                }
            }
    
            private void miCustomersDetails_Click(object sender, EventArgs e)
            {
                if (CustomerDetailsDisplaying == false)
                {
                    customerDetails = new();
                    customerDetails.MdiParent = this;
                    customerDetails.Show();
    
                    CustomerDetailsDisplaying = true;
                }
                else
                {
                    customerDetails.BringToFront();
                }
            }
    
            private void miCustomersEditor_Click(object sender, EventArgs e)
            {
                if (CustomerEditorDisplaying == false)
                {
                    customerEditor = new();
                    customerEditor.MdiParent = this;
                    customerEditor.Show();
    
                    CustomerEditorDisplaying = true;
                }
                else
                {
                    customerEditor.BringToFront();
                }
            }
    
            private void miCustomersDelete_Click(object sender, EventArgs e)
            {
                if (CustomerDeleteDisplaying == false)
                {
                    customerDelete = new();
                    customerDelete.MdiParent = this;
                    customerDelete.Show();
    
                    CustomerDeleteDisplaying = true;
                }
                else
                {
                    customerDelete.BringToFront();
                }
            }
    
            private void miViewWaterBills_Click(object sender, EventArgs e)
            {
                if (WaterBillsDisplaying == false)
                {
                    waterBills = new WaterBills.Central();
    
                    waterBills.MdiParent = this;
                    waterBills.Show();
    
                    WaterBillsDisplaying = true;
                }
                else
                {
                    waterBills.BringToFront();
                }
            }
    
            private void miWaterBillsCreate_Click(object sender, EventArgs e)
            {
                if (WaterBillCreateDisplaying == false)
                {
                    waterBillCreate = new WaterBills.Create();
    
                    waterBillCreate.MdiParent = this;
                    waterBillCreate.Show();
    
                    WaterBillCreateDisplaying = true;
                }
                else
                {
                    waterBillCreate.BringToFront();
                }
            }
    
            private void miWaterBillsDetails_Click(object sender, EventArgs e)
            {
                if (WaterBillDetailsDisplaying == false)
                {
                    waterBillDetails = new();
                    waterBillDetails.MdiParent = this;
                    waterBillDetails.Show();
    
                    WaterBillDetailsDisplaying = true;
                }
                else
                {
                    waterBillDetails.BringToFront();
                }
            }
    
            private void miWaterBillsEditor_Click(object sender, EventArgs e)
            {
                if (WaterBillEditorDisplaying == false)
                {
                    waterBillEditor = new();
                    waterBillEditor.MdiParent = this;
                    waterBillEditor.Show();
    
                    WaterBillEditorDisplaying = true;
                }
                else
                {
                    waterBillEditor.BringToFront();
                }
            }
    
            private void miWaterBillsDeletion_Click(object sender, EventArgs e)
            {
                if (WaterBillDeleteDisplaying == false)
                {
                    waterBillDelete = new();
                    waterBillDelete.MdiParent = this;
                    waterBillDelete.Show();
    
                    WaterBillDeleteDisplaying = true;
                }
                else
                {
                    waterBillDelete.BringToFront();
                }
            }
    
            private void miHelpAbout_Click(object sender, EventArgs e)
            {
                AboutSWP about = new();
    
                about.ShowDialog();
            }
    
            private void miFileExit_Click(object sender, EventArgs e)
            {
                Close();
            }
        }
    }
  24. To execute the application, on the main menu, click Debug -> Start Without Debugging

  25. On the main menu of the central form of the application, click Water Bills and click View Water Bills

    Stellar Water Point - Customers Accounts

  26. On the main menu of the central form of the application, click Water Bills and click Delete Water Bill

    Stellar Water Point - Water Bills

  27. In the Water Bill # text box, type 917829
  28. Click Find Water Bill

    Stellar Water Point - Water Bill Deletion

  29. Click Delete Water Bill
  30. Read the message in the message box and click Yes:

    Stellar Water Point - Water Bills

  31. Close the forms and return to your programming environment
  32. Close your programming environment

Home Copyright © 2010-2024, FunctionX, Inc. Sunday 11 June 2023 Home