Application Setup

Introduction

Hi, for our exercise, we will create a text-based database Windows Forms application. We will use XML to store the records of our database.

Practical LearningPractical Learning: Introducing the Application

  1. Start Microsoft Visual Studio
  2. In the Visual Studion 2026 dialog box, click Create a New Project
  3. In the Create a New Project dialog box, in the languages combo box, select Visual Basic
  4. In the list of projects templates, click Windows Forms App
  5. Click Next
  6. Change the Project Name to StellarWaterPoint.
    Set the Location to a path of your choice
  7. Click Next
  8. In the Additional Information wizard page, in the Framework combo box, select the highest version (.NET 10.0 (Long Term Support))
  9. Click Create

The Main Form of the Application

Our application will use a central form to access the other forms. We will use the default form for that purpose.

Practical LearningPractical Learning: Preparing the Central Form of the Application

  1. In the Solution Explorer, right-click Form1.cs and click Rename
  2. Type WaterDistribution (to get WaterDistribution.vb) and press Enter
  3. Read the message on the message box and click Yes
  4. Click the body of the form to make sure it is selected.
    In the Properties window, change the following characteristics:
    Text: Stellar Water Point
    StartPosition: CenterScreen
    MaximizeBox: False
  5. Double-click an unoccupied area of the form to generate its Load event
  6. Impliment the event as follows:
    Public Class WaterDistribution
        Private Sub Exercise_Load(sender As Object, e As EventArgs) Handles MyBase.Load Handles MyBase.Load
            Rem If the directory for the database doesn't yet exist, create it
            Directory.CreateDirectory("C:\Stellar Water Point1")
        End Sub
    End Class

Water Meters

Introduction

Our application will use forms to create water meter records, to view a record of a water meter, to edit or to delete the record of a water meter.

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 StellarWaterPoint -> Add -> Form (Windows Forms)...
  2. TFor the Name of the form, type MeterCentral
  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
    ColWaterMeterId Id 40
    ColMeterNumber Meter # 150
    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 - New Water Meter

    Control (Name) Other Properties
    ListView List View LvwWaterMeters FullRowSelect: True
    GridLines: True
    View: Details
  9. Double-click an unoccupied area of the form to generate its Load event
  10. Change the document as follows:
    Imports System.IO
    Imports System.Xml
    
    Public Class MeterCentral
        Private Sub ShowWaterMeters()
            Dim xdWaterMeters As XmlDocument = New XmlDocument()
            Dim strFileWaterMeters As String = "C:\Stellar Water Point10\WaterMeters.xml"
    
            If File.Exists(strFileWaterMeters) Then
                Using fsWaterMeters As FileStream = New FileStream(strFileWaterMeters, FileMode.Open,
                                                                     FileAccess.Read, FileShare.Read)
    
                    xdWaterMeters.Load(fsWaterMeters)
    
                    Dim xnlWaterMeters As XmlNodeList = xdWaterMeters.DocumentElement.ChildNodes
    
                    LvwWaterMeters.Items.Clear()
    
                    For Each xnWaterMeter As XmlNode In xnlWaterMeters
                        Dim lviWaterMeter As ListViewItem = New ListViewItem(xnWaterMeter.FirstChild.InnerText)
    
                        lviWaterMeter.SubItems.Add(xnWaterMeter.FirstChild.NextSibling.InnerText)
                        lviWaterMeter.SubItems.Add(xnWaterMeter.FirstChild.NextSibling.NextSibling.InnerText)
                        lviWaterMeter.SubItems.Add(xnWaterMeter.FirstChild.NextSibling.NextSibling.NextSibling.InnerText)
                        lviWaterMeter.SubItems.Add(xnWaterMeter.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.InnerText)
    
                        LvwWaterMeters.Items.Add(lviWaterMeter)
                    Next
                End Using
            End If
        End Sub
        
        Private Sub MeterCentral_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            ShowWaterMeters()
        End Sub
    End Class
  11. In the Solution Explorer, double-click WaterDistribution.cs to display the main form of the application
  12. From the Toolbox, add a button to the form
  13. From the Properties window, change the characteristics of the button as follows:

    Stellar Water Point

    Control (Name) Text Font
    Button Button BtnWaterMeters &Water Meters... Times New Roman, 24pt, style=Bold
  14. Double-click the &Water Meters button
  15. Impliment the event as follows:
    Imports System.IO
    
    Public Class WaterDistribution
        Private Sub Exercise_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            REM If the directory for the database doesn't yet exist, create it
            Directory.CreateDirectory("C:\Stellar Water Point10")
        End Sub
    
        Private Sub BtnWaterMeters_Click(sender As Object, e As EventArgs) Handles BtnWaterMeters.Click
            Dim Central As MeterCentral = New MeterCentral()
    
            Central.ShowDialog()
        End Sub
    End Class

A Water Meter Record

Our application will have a list of water meters. A record for each water meter must be created. To make this happen, we will equip the application with an appropriate form.

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 file, type Create as the name of the form
  3. Click Add
  4. Design the form as follows:

    Stellar Water Point - New Water Meter

    Control (Name) Text Modifiers Other Properties
    Label Label   &Meter #:    
    MaskedTextBox Masked Text Box MtbMeterNumber   Public Masked: 000-000-000
    Label Label   Meter &Id:    
    TextBox Text Box TxtWaterMeterId   Public  
    Label Label   M&ake:    
    TextBox Text Box TxtMake   Public
    Label Label   M&odel:    
    TextBox Text Box TxtModel   Public  
    Label Label   Me&ter Size:    
    TextBox Text Box TxtMeterSize   Public  
    Button Button BtnOK &OK   DialogResult: OK
    Button Button BtnCancel &Cancel   DialogResult: Cancel
  5. Using the Properties window, change some characteristics of the form as follows:
    FormBorderStyle: FixedDialog
    Text:            Stellar Water Point - Water Meter Setup
    StartPosition:   CenterScreen
    AcceptButton:    BtnOK
    CancelButton:    BtnCancel
  6. In the Solution Explorer, below the WaterMeters folder, double-click MeterCentral.cs
  7. From the Toolbox, add a button to the form below the list view
  8. Change the characteristics of the button as follows:

    Stellar Water Point - Water Meters

    Control (Name) Other Properties
    ListView List View LvwWaterMeters FullRowSelect: True
    GridLines: True
    View: Details
    Button Button BtnNewWaterMeter &New Water Meter...
  9. On the MeterCentral form, double-click the New Water Meter button
  10. Implement the event as follows:
    Imports System.IO
    Imports System.Xml
    
    Public Class MeterCentral
        Private Sub ShowWaterMeters()
            REM Create a reference to the XML's DOM object
            Dim xdWaterMeters As XmlDocument = New XmlDocument()
            REM Indicate the file that holds a list of water meters
            Dim strFileWaterMeters As String = "C:\Stellar Water Point10\WaterMeters.xml"
    
            REM Check whether a file that holds a list of water meters exists
            If File.Exists(strFileWaterMeters) Then
                REM If that file exists, open it
                Using fsWaterMeters As FileStream = New FileStream(strFileWaterMeters, FileMode.Open,
                                                                     FileAccess.Read, FileShare.Read)
    
                    REM Get the list of water meters from the file and store
                    REM the records in the previously created DOM object.
                    xdWaterMeters.Load(fsWaterMeters)
    
                    REM If there is at least one record for the water meters, 
                    REM create an XmlNodeList list and transmit it to 
                    REM a collection that wille be used in the view page.
                    Dim xnlWaterMeters As XmlNodeList = xdWaterMeters.DocumentElement.ChildNodes
    
                    LvwWaterMeters.Items.Clear()
    
                    For Each xnWaterMeter As XmlNode In xnlWaterMeters
                        Dim lviWaterMeter As ListViewItem = New ListViewItem(xnWaterMeter.FirstChild.InnerText)
    
                        lviWaterMeter.SubItems.Add(xnWaterMeter.FirstChild.NextSibling.InnerText)
                        lviWaterMeter.SubItems.Add(xnWaterMeter.FirstChild.NextSibling.NextSibling.InnerText)
                        lviWaterMeter.SubItems.Add(xnWaterMeter.FirstChild.NextSibling.NextSibling.NextSibling.InnerText)
                        lviWaterMeter.SubItems.Add(xnWaterMeter.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.InnerText)
    
                        LvwWaterMeters.Items.Add(lviWaterMeter)
                    Next
                End Using
            End If
        End Sub
        
        Private Sub MeterCentral_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            ShowWaterMeters()
        End Sub
    
        Private Sub BtnNewWaterMeter_Click(sender As Object, e As EventArgs) Handles BtnNewWaterMeter.Click
            Dim wm = New Create
            Dim fiWaterMeters As FileInfo = Nothing
            Dim xdWaterMeters = New XmlDocument
            Dim strWaterMeters = "C:\Stellar Water Point10\WaterMeters.xml"
     
            If wm.ShowDialog = DialogResult.OK Then
                fiWaterMeters = New FileInfo(strWaterMeters)
    
                If fiWaterMeters.Exists Then
                    Using fsWaterMeters = New FileStream(fiWaterMeters.FullName, FileMode.Open,
                                                              FileAccess.Read, FileShare.Read)
    
                        xdWaterMeters.Load(fsWaterMeters)
                    End Using
                Else
                    Using fsWaterMeters = New FileStream(fiWaterMeters.FullName, FileMode.Create,
                                                              FileAccess.Write, FileShare.Write)
    
                        xdWaterMeters.LoadXml("<?xml version=""1.0"" encoding=""utf-8""?>" +
                                                      "<water-meters></water-meters>")
                        xdWaterMeters.Save(fsWaterMeters)
                    End Using
                End If
            End If
    
            Using fsWaterMeters = New FileStream(fiWaterMeters.FullName, FileMode.OpenOrCreate,
                                                  FileAccess.ReadWrite, FileShare.ReadWrite)
    
                Dim xeWaterMeter = xdWaterMeters.CreateElement("water-meter")
    
                xeWaterMeter.InnerXml = "<water-meter-id>" + wm.TxtWaterMeterId.Text + "</water-meter-id>" +
                                        "<meter-number>" + wm.MtbMeterNumber.Text + "</meter-number>" +
                                        "<make>" + wm.TxtMake.Text + "</make>" +
                                        "<model>" + wm.TxtModel.Text + "</model>" +
                                        "<meter-size>" + wm.TxtMeterSize.Text + "</meter-size>"
                
                xdWaterMeters.DocumentElement.AppendChild(xeWaterMeter)
                xdWaterMeters.Save(fsWaterMeters)
            End Using
    
            ShowWaterMeters()
        End Sub
    End Class
  11. To execute the application, on the main menu, click Debug -> Start Without Debugging

    Stellar Water Point

  12. On the MeterCentral form, click the Water Meters button:

    Stellar Water Point - Water Meters

  13. Click the New Water Meter button:

    Stellar Water Point - New Water Meter

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

    Stellar Water Point - Water Meters

  15. Close the forms and return to your programming environment

Water Meter Details

Sometimes, a user may want to check the values of a water meter record. To support this, we will add an appropriate form to our application.

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. For the Name of the form, type Details
  3. Press Enter
  4. Resize the Editor form to have the same size as the Create form
  5. Copy everything from the Create form and paste it in the Editor form
  6. Delete the bottom two buttons and add a new button
  7. Change the design of the form as follows:

    Stellar Water Point - New Water Meter

    Control (Name) Text
    Button Button BtnFindWateMeter &Find Water Meter
    Button Button BtnClose &Close
  8. On the form, double-click the Find Water Meter button
  9. Implement the event as follows:
    Imports System.IO
    Imports System.Xml
    
    Public Class Details
        Private Sub BtnFindWateMeter_Click(sender As Object, e As EventArgs) Handles BtnFindWaterMeter.Click
            If String.IsNullOrEmpty(MtbMeterNumber.Text) Then
                MsgBox("You must type a meter number and then click the Find button.",
                                    "Stellar Water Point", MsgBoxStyle.OkOnly Or MsgBoxStyle.Information)
                Exit Sub
            End If
    
            Dim xdWaterMeters As XmlDocument = New XmlDocument()
            Dim strWaterMeters As String = "C:\Stellar Water Point10\WaterMeters.xml"
            Dim fiWaterMeters As FileInfo = New FileInfo(strWaterMeters)
    
            If fiWaterMeters.Exists Then
                Using fsWaterMeters As FileStream = New FileStream(fiWaterMeters.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    xdWaterMeters.Load(fsWaterMeters)
                    Dim xnlWaterMeters As XmlNodeList = xdWaterMeters.DocumentElement.SelectNodes("//meter-number[.='" + MtbMeterNumber.Text + "']")
    
                    For Each xnWaterMeter As XmlNode In xnlWaterMeters
                        TxtWaterMeterId.Text = xnWaterMeter.PreviousSibling.InnerText
                        TxtMake.Text = xnWaterMeter.NextSibling.InnerText
                        TxtModel.Text = xnWaterMeter.NextSibling.NextSibling.InnerText
                        TxtMeterSize.Text = xnWaterMeter.NextSibling.NextSibling.NextSibling.InnerText
                    Next
                End Using
            End If
        End Sub
    End Class
  10. Return to the form and double-click the Close button
  11. Implement the event as follows:
    Imports System.IO
    Imports System.Xml
    
    Public Class Details
        Private Sub BtnFindWateMeter_Click(sender As Object, e As EventArgs) Handles BtnFindWaterMeter.Click
            REM If the user clicks the Find button, 
            REM make sure there Is a meter number in the top text box.
            If String.IsNullOrEmpty(MtbMeterNumber.Text) Then
                REM If the user didn't type a meter number, 
                REM display a message box to inform the user.
                MsgBox("You must type a meter number and then click the Find button.",
                                    "Stellar Water Point", MsgBoxStyle.OkOnly Or MsgBoxStyle.Information)
                REM If the user didn't type a meter number but clicked Find, don't do anything
                Exit Sub
            End If
    
            REM We will need a reference to an XML Dom object as an XmlDocument variable
            Dim xdWaterMeters As XmlDocument = New XmlDocument()
            REM This is the name and path of the file that holds the records of water meters
            Dim strWaterMeters As String = "C:\Stellar Water Point10\WaterMeters.xml"
            REM We will process the file of water meters using a FileInfo object
            Dim fiWaterMeters As FileInfo = New FileInfo(strWaterMeters)
    
            REM We need to find out whether a file for water meters was previously created.
            If fiWaterMeters.Exists Then
                REM If that file exists, create a stream of it. Open that file with a read-only status
                Using fsWaterMeters As FileStream = New FileStream(fiWaterMeters.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    REM Get the list of water meter records and put those records in the XML Dom object created earlier.
                    xdWaterMeters.Load(fsWaterMeters)
                    REM Use XPath to locate the water meter that has 
                    REM the same meter number as the one in the Meter # text box.
                    REM Store the water meter in an XmlNodeList variable.
                    Dim xnlWaterMeters As XmlNodeList = xdWaterMeters.DocumentElement.SelectNodes("//meter-number[.='" + MtbMeterNumber.Text + "']")
    
                    REM If there Is a water meter in the database with 
                    REM the number that the user typed, locate that water meter 
                    REM and display each of its values in the appropriate text box.
                    For Each xnWaterMeter As XmlNode In xnlWaterMeters
                        TxtWaterMeterId.Text = xnWaterMeter.PreviousSibling.InnerText
                        TxtMake.Text = xnWaterMeter.NextSibling.InnerText
                        TxtModel.Text = xnWaterMeter.NextSibling.NextSibling.InnerText
                        TxtMeterSize.Text = xnWaterMeter.NextSibling.NextSibling.NextSibling.InnerText
                    Next
                End Using
            End If
        End Sub
    
        Private Sub BtnClose_Click(sender As Object, e As EventArgs) Handles BtnClose.Click
            Close()
        End Sub
    End Class
  12. In the Solution Explorer, below the WaterMeters folder, double-click MeterCentral.cs to open its form
  13. From the Toolbox, add a button to the form below the list view and to the right of the New Water Meter button
  14. Change the characteristics of the button as follows:

    Stellar Water Point - Water Meters

    Control (Name) Other Properties
    ListView List View LvwWaterMeters No Change
    Button Button BtnNewWaterMeter &New Water Meter...
    Button Button BtnViewWaterMeter &View Water Meter...
  15. Double-click the View Water Meter button
  16. Change the document as follows:
    Imports System.IO
    Imports System.Xml
    
    Public Class MeterCentral
        Private Sub ShowWaterMeters()
            . . .
        End Sub
        Private Sub MeterCentral_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            ShowWaterMeters()
        End Sub
    
        Private Sub BtnNewWaterMeter_Click(sender As Object, e As EventArgs) Handles BtnNewWaterMeter.Click
            . . .
        End Sub
    
        Private Sub BtnWaterMeterDetails_Click(sender As Object, e As EventArgs) Handles BtnWaterMeterDetails.Click
            Dim waterMeterDetails As Details = New Details()
    
            waterMeterDetails.Show()
        End Sub
    End Class
  17. To execute the application, on the main menu, click Debug -> Start Without Debugging

    Stellar Water Point

  18. On the Water Distribution form, click the Water Meters button
  19. On the MeterCentral form of water meters, click the View Water Meter button:

    Stellar Water Point - View Water Meter

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

    Stellar Water Point - View Water Meter

  22. Close the forms and return to your programming environment

Updating a Water Meter Details

One of the routine operations performed on a database is to change the details of a record. To support this operation for a water meter, we will create a form that can be used to update the information of a water meter.

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. Resize the Editor form to have the same size as the Create form
  5. Copy everything from the Create form and paste it in the Editor form
  6. Change the design of the form as follows:

    Stellar Water Point - Water Meter Editor

    Control (Name) Text
    Button Button BtnFindWateMeter &Find Water Meter
    Button Button BtnUpdateWateMeter &Update Water Meter
    Button Button BtnClose &Close
  7. On the form, double-click the Find Water Meter button
  8. Change the document as follows:
    Imports System.IO
    Imports System.Xml
    
    Public Class Editor
        Private Sub BtnFindWaterMeter_Click(sender As Object, e As EventArgs) Handles BtnFindWaterMeter.Click
            If String.IsNullOrEmpty(MtbMeterNumber.Text) Then
                MsgBox("You must type a meter number and then click the Find button.",
                MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                                    "Stellar Water Point")
                Exit Sub
            End If
    
            Dim xdWaterMeters As XmlDocument = New XmlDocument()
            Dim strWaterMeters As String = "C:\Stellar Water Point10\WaterMeters.xml"
            Dim fiWaterMeters As FileInfo = New FileInfo(strWaterMeters)
    
            If fiWaterMeters.Exists Then
                Using fsWaterMeters As FileStream = New FileStream(fiWaterMeters.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    xdWaterMeters.Load(fsWaterMeters)
                    Dim xnlWaterMeters As XmlNodeList = xdWaterMeters.DocumentElement.SelectNodes("//meter-number[.='" + MtbMeterNumber.Text + "']")
    
                    For Each xnWaterMeter As XmlNode In xnlWaterMeters
                        TxtWaterMeterId.Text = xnWaterMeter.PreviousSibling.InnerText
                        TxtMake.Text = xnWaterMeter.NextSibling.InnerText
                        TxtModel.Text = xnWaterMeter.NextSibling.NextSibling.InnerText
                        TxtMeterSize.Text = xnWaterMeter.NextSibling.NextSibling.NextSibling.InnerText
                    Next
                End Using
            End If
        End Sub
    End Class
  9. Return to the form and double-click the Update Water Meter button
  10. Change the document as follows:
    Imports System.IO
    Imports System.Xml
    
    Public Class Editor
        Private Sub BtnFindWaterMeter_Click(sender As Object, e As EventArgs) Handles BtnFindWaterMeter.Click
            . . .
        End Sub
    
        Private Sub BtnUpdateWateMeter_Click(sender As Object, e As EventArgs) Handles BtnUpdateWateMeter.Click
            Dim xdWaterMeters As XmlDocument = New XmlDocument()
            Dim strWaterMeters As String = "C:\Stellar Water Point10\WaterMeters.xml"
    
            Dim fiWaterMeters As FileInfo = New FileInfo(strWaterMeters)
    
            If fiWaterMeters.Exists Then
                Using fsWaterMeters As FileStream = New FileStream(fiWaterMeters.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
    
                    xdWaterMeters.Load(fsWaterMeters)
                    Dim xnlWaterMeters As XmlNodeList = xdWaterMeters.DocumentElement.SelectNodes("//meter-number[.='" + MtbMeterNumber.Text + "']")
    
                    For Each xnWaterMeter As XmlNode In xnlWaterMeters
                        xnWaterMeter.ParentNode.InnerXml = "<water-meter-id>" + TxtWaterMeterId.Text + "</water-meter-id>" +
                                        "<meter-number>" + MtbMeterNumber.Text + "</meter-number>" +
                                        "<make>" + TxtMake.Text + "</make>" +
                                        "<model>" + TxtModel.Text + "</model>" +
                                        "<meter-size>" + TxtMeterSize.Text + "</meter-size>"
                    Next
                End Using
    
                Using fsWaterMeters As FileStream = New FileStream(fiWaterMeters.FullName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite)
                    xdWaterMeters.Save(fsWaterMeters)
                End Using
            End If
    
            Close()
        End Sub
    End Class
  11. Return to the form and double-click the Close button
  12. Change the document as follows:
    Imports System.IO
    Imports System.Xml
    
    Public Class Editor
        Private Sub BtnFindWaterMeter_Click(sender As Object, e As EventArgs) Handles BtnFindWaterMeter.Click
            REM If the user clicks the Find button, 
            REM make sure there is a meter number in the top text box.
            If String.IsNullOrEmpty(MtbMeterNumber.Text) Then
                REM If the user didn't type a meter number, 
                REM display a message box to inform the user.
                MsgBox("You must type a meter number and then click the Find button.",
                MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                                    "Stellar Water Point")
                REM If the user didn't type a meter number but clicked Find, don't do anything
                Exit Sub
            End If
    
            REM We will need a reference to an XML Dom object as an XmlDocument variable
            Dim xdWaterMeters As XmlDocument = New XmlDocument()
            REM This is the name and path of the file that holds the records of water meters
            Dim strWaterMeters As String = "C:\Stellar Water Point11\WaterMeters.xml"
            REM We will process the file of water meters using a FileInfo object
            Dim fiWaterMeters As FileInfo = New FileInfo(strWaterMeters)
    
            REM We need to find out whether a file for water meters was previously created.
            If fiWaterMeters.Exists Then
                REM If that file exists, create a stream of it. Open that file with a read-only status
                Using fsWaterMeters As FileStream = New FileStream(fiWaterMeters.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    REM Get the list of water meter records 
                    REM and put those records in the XML Dom object created earlier.
                    xdWaterMeters.Load(fsWaterMeters)
    
                    REM Use XPath to locate the water meter that has 
                    REM the same meter number as the one in the Meter # text box.
                    REM Store the water meter in an XmlNodeList variable.
                    Dim xnlWaterMeters As XmlNodeList = xdWaterMeters.DocumentElement.SelectNodes("//meter-number[.='" + MtbMeterNumber.Text + "']")
    
                    REM If there is a water meter in the database with 
                    REM the number that the user typed, locate that water meter 
                    REM and display each of its values in the appropriate text box.
                    For Each xnWaterMeter As XmlNode In xnlWaterMeters
                        TxtWaterMeterId.Text = xnWaterMeter.PreviousSibling.InnerText
                        TxtMake.Text = xnWaterMeter.NextSibling.InnerText
                        TxtModel.Text = xnWaterMeter.NextSibling.NextSibling.InnerText
                        TxtMeterSize.Text = xnWaterMeter.NextSibling.NextSibling.NextSibling.InnerText
                    Next
                End Using
            End If
        End Sub
    
        Private Sub BtnUpdateWateMeter_Click(sender As Object, e As EventArgs) Handles BtnUpdateWateMeter.Click
            REM We will need a reference to an XML Dom object as an XmlDocument variable
            Dim xdWaterMeters As XmlDocument = New XmlDocument()
            REM This is the name and path of the file that holds the records of water meters
            Dim strWaterMeters As String = "C:\Stellar Water Point11\WaterMeters.xml"
            REM We will process the file of water meters using a FileInfo object
            Dim fiWaterMeters As FileInfo = New FileInfo(strWaterMeters)
    
            REM We need to find out whether a file for water meters was previously created.
            If fiWaterMeters.Exists Then
                REM If that file exists, create a stream of it. Open that file with a read-only status
                Using fsWaterMeters As FileStream = New FileStream(fiWaterMeters.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    REM Get the list of water meter records 
                    REM and put those records in the XML Dom object created earlier.
                    xdWaterMeters.Load(fsWaterMeters)
    
                    REM Use XPath to locate the water meter that has 
                    REM the same meter number as the one in the Meter # text box.
                    REM Store the water meter in an XmlNodeList variable.
                    Dim xnlWaterMeters As XmlNodeList = xdWaterMeters.DocumentElement.SelectNodes("//meter-number[.='" + MtbMeterNumber.Text + "']")
    
                    REM Check each record of the water meters.
                    For Each xnWaterMeter As XmlNode In xnlWaterMeters
                        REM If you find a record whose water meter is 
                        REM the same as the meter number that the user typed,
                        REM change the values of the Make, the Model, 
                        REM and the Meter Size based on the values 
                        REM the user typed in the corresponding text boxes.
                        xnWaterMeter.ParentNode.InnerXml = "<water-meter-id>" + TxtWaterMeterId.Text + "</water-meter-id>" +
                                        "<meter-number>" + MtbMeterNumber.Text + "</meter-number>" +
                                        "<make>" + TxtMake.Text + "</make>" +
                                        "<model>" + TxtModel.Text + "</model>" +
                                        "<meter-size>" + TxtMeterSize.Text + "</meter-size>"
                    Next
                End Using
    
                REM Now that a water meter has been changed/update 
                REM (and the file of water meters has changed), save the new version of the file.
                Using fsWaterMeters As FileStream = New FileStream(fiWaterMeters.FullName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite)
                    xdWaterMeters.Save(fsWaterMeters)
                End Using
            End If
    
            REM If the user has updated a record, we will assume that, 
            REM in most cases (such as usually in real life), 
            REM a user updates one record and moves to other activities.
            REM For this record, after the user has updated a record, 
            REM we will clode the form.
            Close()
        End Sub
    
        Private Sub BtnClose_Click(sender As Object, e As EventArgs) Handles BtnClose.Click
            Close()
        End Sub
    End Class
  13. In the Solution Explorer, below the WaterMeters folder, double-click MeterCentral.cs
  14. From the Toolbox, add a button to the form below the list view and on the right side of the View Water Meter button
  15. Change the design of the form as follows:

    Stellar Water Point - Water Meters

    Control (Name) Text
    Button Button BtnEditWaterMeter &Edit Water Meter...
  16. Double-click the Delete Water Meter button
  17. Return to the form and double-click the Close button
  18. Change the document as follows:
    Private Sub BtnEditWaterMeter_Click(sender As Object, e As EventArgs) Handles BtnEditWaterMeter.Click
        Dim Editor = New MeterEditor
    
        Editor.ShowDialog()
    
        ShowWaterMeters()
    End Sub
  19. To execute the application, on the main menu, click Debug -> Start Without Debugging
  20. On the MeterCentral form, click the Water Meters button
  21. Click the Edit Water Meter button:

    Stellar Water Point - Water Meter Editor

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

    Stellar Water Point - Water Meter Editor

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

    Stellar Water Point - New Water Meter

  25. Click the Update button:

    Stellar Water Point - Water Meters

  26. Close the forms and return to your programming environment

Removing a Water Meter from the Database

If a water meter has become useless and you want to make sure it is no more available for customer use, you can delete its record. To assist the user, we will create a form for that operation.

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. Resize the Delete form to have the same size as the Editor form
  5. Copy everything from the Editor form and paste it in the Delete form
  6. Change the bottom button as follows:

    Stellar Water Point - New Water Meter

    Control (Name) Text
    Button Button BtnDeleteWateMeter &Delete Water Meter
  7. On the form, double-click the Find Water Meter button
  8. Change the document as tollows:
    Imports System.IO
    Imports System.Xml
    
    Public Class Delete
        Private Sub BtnFindWaterMeter_Click(sender As Object, e As EventArgs) Handles BtnFindWaterMeter.Click
            Dim xdWaterMeters As XmlDocument = New XmlDocument()
            Dim strWaterMeters As String = "C:\Stellar Water Point11\WaterMeters.xml"
    
            Dim fiWaterMeters As FileInfo = New FileInfo(strWaterMeters)
    
            If fiWaterMeters.Exists Then
                Using fsWaterMeters As FileStream = New FileStream(fiWaterMeters.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
    
                    xdWaterMeters.Load(fsWaterMeters)
                    Dim xnlWaterMeters As XmlNodeList = xdWaterMeters.DocumentElement.SelectNodes("//meter-number[.='" + MtbMeterNumber.Text + "']")
    
                    For Each xnWaterMeter As XmlNode In xnlWaterMeters)
                            TxtMake.Text = xnWaterMeter.NextSibling.InnerText
                        TxtModel.Text = xnWaterMeter.NextSibling.NextSibling.InnerText
                        TxtMeterSize.Text = xnWaterMeter.NextSibling.NextSibling.NextSibling.InnerText
                    Next
                End Using
            End If
        End Sub
    End Class
  9. Return to the form and double-click the Delete Water Meter button
  10. Implement the event as tollows:
    Private Sub BtnDeleteWateMeter_Click(sender As Object, e As EventArgs) Handles BtnDeleteWateMeter.Click
        Dim xdWaterMeters As XmlDocument = New XmlDocument()
        Dim strWaterMeters As String = "C:\Stellar Water Point11\WaterMeters.xml"
    
        If String.IsNullOrEmpty(MtbMeterNumber.Text) Then
            MsgBox("You must type a water meter number if you want to delete one.",
            MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                            "Stellar Water Point")
            Exit Sub
        End If
    
        If File.Exists(strWaterMeters) = False Then
            MsgBox("There is no file for the water meters in the system.",
                            MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                            "Stellar Water Point")
            Exit Sub
        End If
    
        xdWaterMeters.Load(strWaterMeters)
    
        Dim xnlWaterMeters As XmlNodeList = xdWaterMeters.DocumentElement.GetElementsByTagName("meter-number")
    
        For Each xnWaterMeter As XmlNode In xnlWaterMeters
            If xnWaterMeter.InnerText = MtbMeterNumber.Text Then
                If MsgBox("Are you sure you want to delete this water meter record from the system?",
                              MsgBoxStyle.YesNo Or MsgBoxStyle.Information,
                              "Stellar Water Point") = MsgBoxResult.Yes Then
    
                    xdWaterMeters.DocumentElement.RemoveChild(xnWaterMeter.ParentNode)
                    Exit For
                End If
            End If
        Next
    
        xdWaterMeters.Save(strWaterMeters)
    
        Close()
    End Sub
  11. Return to the form and double-click the Close button
  12. Change the document as tollows:
    Imports System.IO
    Imports System.Xml
    
    Public Class Delete
        Private Sub BtnFindWaterMeter_Click(sender As Object, e As EventArgs) Handles BtnFindWaterMeter.Click
            ' If the user clicks the Find button, 
            ' make sure there is a meter number in the top text box.
            If String.IsNullOrEmpty(MtbMeterNumber.Text) Then
                ' If the user didn't type a meter number, 
                ' display a message box to inform the user.
                MsgBox("You must type a meter number and then click the Find button.",
                    MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                                    "Stellar Water Point")
                ' If the user didn't type a meter number but clicked Find, don't do anything
            End If
    
            ' We will need a reference to an XML Dom object as an XmlDocument variable
            Dim xdWaterMeters As XmlDocument = New XmlDocument()
            ' This is the name and path of the file that holds the records of water meters
            Dim strWaterMeters As String = "C:\Stellar Water Point11\WaterMeters.xml"
            'We will process the file of water meters using a FileInfo object
            Dim fiWaterMeters As FileInfo = New FileInfo(strWaterMeters)
    
            REM We need to find out whether a file for water meters was previously created.
            If fiWaterMeters.Exists Then
                ' If that file exists, create a stream of it. Open that file with a read-only status
                Using fsWaterMeters As FileStream = New FileStream(fiWaterMeters.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    ' Get the list of water meter records 
                    ' and put those records in the XML Dom object created earlier.
                    xdWaterMeters.Load(fsWaterMeters)
    
                    ' Use XPath to locate the water meter that has 
                    ' the same meter number as the one in the Meter # text box.
                    ' Store the water meter in an XmlNodeList variable.
                    Dim xnlWaterMeters As XmlNodeList = xdWaterMeters.DocumentElement.SelectNodes("//meter-number[.='" + MtbMeterNumber.Text + "']")
    
                    REM If there is a water meter in the database with 
                    REM the number that the user typed, locate that water meter 
                    REM and display each of its values in the appropriate text box.
                    For Each xnWaterMeter As XmlNode In xnlWaterMeters
                        TxtWaterMeterId.Text = xnWaterMeter.PreviousSibling.InnerText
                        TxtMake.Text = xnWaterMeter.NextSibling.InnerText
                        TxtModel.Text = xnWaterMeter.NextSibling.NextSibling.InnerText
                        TxtMeterSize.Text = xnWaterMeter.NextSibling.NextSibling.NextSibling.InnerText
                    Next
                End Using
            End If
        End Sub
    
        Private Sub BtnDeleteWateMeter_Click(sender As Object, e As EventArgs) Handles BtnDeleteWateMeter.Click
            ' If the user clicks the Delete button, make sure that 
            ' the right text box contains a meter number
            If String.IsNullOrEmpty(MtbMeterNumber.Text) Then
                ' If the user didn't provide a meter number, display a message box ...
                MsgBox("You must type a water meter number if you want to delete one.",
                    MsgBoxStyle.OkOnly Or MsgBoxStyle.Information, "Stellar Water Point")
                ' .. and stop the operation.
                Exit Sub
            End If
    
            ' Create an XML Dom object
            Dim xdWaterMeters As XmlDocument = New XmlDocument()
            ' Get the file that holds a list of water meters
            ' and assign that file to a string variable.
            Dim strWaterMeters As String = "C:\Stellar Water Point11\WaterMeters.xml"
    
            ' If the user provided a meter number and clicked the Find button,
            ' check whether a file for water meters was previously created.
            If Not File.Exists(strWaterMeters) Then
                MsgBox("There is no file for the water meters in the system.",
                                MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                                "Stellar Water Point")
                ' .. and stop the operation.
                Exit Sub
            End If
    
            ' Since a file of water meters exists, open it.
            ' Store the list of water meters in the XML Dom object that was previously created.
            xdWaterMeters.Load(strWaterMeters)
    
            ' From the list of XML elements, get a list of elements based one named meter-number.
            Dim xnlWaterMeters As XmlNodeList = xdWaterMeters.DocumentElement.GetElementsByTagName("meter-number")
    
            ' Visit each XML node from the list
            For Each xnWaterMeter As XmlNode In xnlWaterMeters
                ' When you get to an element, check whether its meter number is 
                ' the same number the user had typed.
                If xnWaterMeter.InnerText = MtbMeterNumber.Text Then
                    ' If you find that meter number, enquire from 
                    ' the user if the water meter must be deleted. 
                    ' To get that information, display a message box with a Yes and a No buttons.
                    If MsgBox("Are you sure you want to delete this water meter record from the system?",
                                  MsgBoxStyle.YesNo Or MsgBoxStyle.Information,
                                  "Stellar Water Point") = MsgBoxResult.Yes Then
    
                        ' If the user had clicked Yes, delete the water meter.
                        xdWaterMeters.DocumentElement.RemoveChild(xnWaterMeter.ParentNode)
                        Exit For
                    End If
                End If
            Next
    
            REM Since the list of water meters has been changed, save its new version
            xdWaterMeters.Save(strWaterMeters)
    
            REM After the deletion operation, close the dialog box and
            REM return to the MeterCentral form of water meters.
            Close()
        End Sub
    
        Private Sub BtnClose_Click(sender As Object, e As EventArgs) Handles BtnClose.Click
            Close()
        End Sub
    End Class
  13. In the Solution Explorer, below the WaterMeters folder, double-click MeterCentral.cs
  14. From the Toolbox, add two buttons to the form below the list view and on the right side of the Edit Water Meter button
  15. Change the design of the form as follows:

    Stellar Water Point - Water Meters

    Control (Name) Text Anchor Other Properties
    ListView List View LvwWaterMeters   Top, Bottom, Left, Right FullRowSelect: True
    GridLines: True
    View: Details
    Button Button BtnNewWaterMeter &New Water Meter... Bottom, Right  
    Button Button BtnViewWaterMeter &View Water Meter... Bottom, Right  
    Button Button BtnEditWaterMeter &Edit Water Meter... Bottom, Right  
    Button Button BtnDeleteWaterMeter &Delete Water Meter... Bottom, Right  
  16. In the Solution Explorer, below WaterMeters, double-click MeterCentral.cs to open its form
  17. Double-click the Delete Water Meter button
  18. Return to the MeterCentral form of the water meters and double-click the Close button
  19. Change the document as follows:
    Imports System.IO
    Imports System.Xml
    
    Public Class MeterCentral
        Private Sub ShowWaterMeters()
            Dim xdWaterMeters As XmlDocument = New XmlDocument()
            Dim strFileWaterMeters As String = "C:\Stellar Water Point11\WaterMeters.xml"
    
            If File.Exists(strFileWaterMeters) Then
                Using fsWaterMeters As FileStream = New FileStream(strFileWaterMeters, FileMode.Open,
                                                                     FileAccess.Read, FileShare.Read)
    
                    xdWaterMeters.Load(fsWaterMeters)
    
                    Dim xnlWaterMeters As XmlNodeList = xdWaterMeters.DocumentElement.ChildNodes
    
                    LvwWaterMeters.Items.Clear()
    
                    For Each xnWaterMeter As XmlNode In xnlWaterMeters
                        Dim lviWaterMeter As ListViewItem = New ListViewItem(xnWaterMeter.FirstChild.InnerText)
    
                        lviWaterMeter.SubItems.Add(xnWaterMeter.FirstChild.NextSibling.InnerText)
                        lviWaterMeter.SubItems.Add(xnWaterMeter.FirstChild.NextSibling.NextSibling.InnerText)
                        lviWaterMeter.SubItems.Add(xnWaterMeter.FirstChild.NextSibling.NextSibling.NextSibling.InnerText)
                        lviWaterMeter.SubItems.Add(xnWaterMeter.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.InnerText)
    
                        LvwWaterMeters.Items.Add(lviWaterMeter)
                    Next
                End Using
            End If
        End Sub
    
        Private Sub MeterCentral_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            ShowWaterMeters()
        End Sub
    
        Private Sub BtnNewWaterMeter_Click(sender As Object, e As EventArgs) Handles BtnNewWaterMeter.Click
            Dim wm = New Create
            Dim fiWaterMeters As FileInfo = Nothing
            Dim xdWaterMeters = New XmlDocument
            Dim strWaterMeters = "C:\Stellar Water Point11\WaterMeters.xml"
    
            If wm.ShowDialog = DialogResult.OK Then
                fiWaterMeters = New FileInfo(strWaterMeters)
    
                If fiWaterMeters.Exists Then
                    Using fsWaterMeters = New FileStream(fiWaterMeters.FullName, FileMode.Open,
                                                              FileAccess.Read, FileShare.Read)
    
                        xdWaterMeters.Load(fsWaterMeters)
                    End Using
                Else
                    Using fsWaterMeters = New FileStream(fiWaterMeters.FullName, FileMode.Create,
                                                              FileAccess.Write, FileShare.Write)
    
                        xdWaterMeters.LoadXml("<?xml version=""1.0"" encoding=""utf-8""?>" +
                                              "<water-meters></water-meters>")
                        xdWaterMeters.Save(fsWaterMeters)
                    End Using
                End If
            End If
    
            Using fsWaterMeters = New FileStream(fiWaterMeters.FullName, FileMode.OpenOrCreate,
                                                  FileAccess.ReadWrite, FileShare.ReadWrite)
    
                Dim xeWaterMeter = xdWaterMeters.CreateElement("water-meter")
    
                xeWaterMeter.InnerXml = "<water-meter-id>" + wm.TxtWaterMeterId.Text + "</water-meter-id>" +
                                        "<meter-number>" + wm.MtbMeterNumber.Text + "</meter-number>" +
                                        "<make>" + wm.TxtMake.Text + "</make>" +
                                        "<model>" + wm.TxtModel.Text + "</model>" +
                                        "<meter-size>" + wm.TxtMeterSize.Text + "</meter-size>"
    
                xdWaterMeters.DocumentElement.AppendChild(xeWaterMeter)
                xdWaterMeters.Save(fsWaterMeters)
            End Using
    
            ShowWaterMeters()
        End Sub
    
        Private Sub BtnViewWaterMeter_Click(sender As Object, e As EventArgs) Handles BtnViewWaterMeter.Click
            Dim WaterMeterDetails = New Details
    
            WaterMeterDetails.Show()
        End Sub
    
        Private Sub BtnEditWaterMeter_Click(sender As Object, e As EventArgs) Handles BtnEditWaterMeter.Click
            REM Get a reference to the dialog box that is used 
            REM to update the details of a water meter.
            Dim Edit = New Editor
            REM Display that dialog box
            Editor.ShowDialog()
    
            REM After using the dialog box, make an attempt to display the list of water meters.
            ShowWaterMeters()
        End Sub
    
        Private Sub BtnDeleteWaterMeter_Click(sender As Object, e As EventArgs) Handles BtnDeleteWaterMeter.Click
            Dim Deletion As New Delete
    
            Deletion.ShowDialog()
    
            ShowWaterMeters()
        End Sub
    
        Private Sub BtnClose_Click(sender As Object, e As EventArgs) Handles BtnClose.Click
            Close()
        End Sub
    End Class
  20. To execute the application, on the main menu, click Debug -> Start Without Debugging:

    Stellar Water Point - Water Meters

  21. On the Central form, click the Water Meters button:

    Stellar Water Point - Water Meters

  22. On the Central form of the water meters, click the Delete Water Meter button:

    Stellar Water Point - Water Meter Deletion

  23. In the Meter # text, type 588-279-663
  24. Click the Find button:

    Stellar Water Point - Water Meter Deletion

  25. Click the Delete button:

    Stellar Water Point - Water Meter Deletion

  26. Read the text on the message box and click Yes

    Stellar Water Point - Water Meters

  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

Customers are the entities that use the services of the bussiness whose application we are building. In this seciton, we will createthe forms that can assist a user with customers-based operations.

Customers Accounts

Our application will use a database that contains a list of customers. As seen with water meter records, some time to time, a user will want to view the customers records. To display a list of customers, we will create a form equipped with a list view.

Practical LearningPractical Learning: Displaying Customers Accounts

  1. To create a form, in the Solution Explorer, right-click StellarWaterPoint -> Add -> Form (Windows Forms)...
  2. Type ClientCentral
  3. Click Add
  4. In the Toolbox, click the ListView button and click the form
  5. In the Properties window, change the characteristics of the list view as follows:
    Control (Name) Other Properties
    ListView List View LvwCustomers FullRowSelect: True
    GridLines: True
    View: Details
  6. On the form, right-click the list view and click Edit Columns...
  7. Create the columns as follows:

    Stellar Water Point - Customers

    (Name) Text TextAlign Width
    ColCustomerId Id   40
    ColAccountNumber Account # Center 150
    ColAccountName Account Name   200
    ColMeterNumber Meter # Center 150
    ColAccountType Account Type   575
    ColAddress Address   250
    ColCity City   125
    ColCounty County   125
    ColState State Center  
    ColZIPCode ZIP-Code Center 125
  8. Click OK
  9. Doubte-click an unoccupied area of the form to generate its Load event
  10. Change the document as follows:
    Imports System.IO
    Imports System.Xml
    
    Public Class ClientCentral
        Sub ShowCustomers()
            Dim i As Integer = 1
    
            LvwCustomers.Items.Clear()
    
            Dim xdCustomers As XmlDocument = New XmlDocument()
            Dim strCustomers As String = "C:\Stellar Water Point12\Customers.xml"
    
            Dim fiCustomers As FileInfo = New FileInfo(strCustomers)
    
            If fiCustomers.Exists Then
                Using fsCustomers As FileStream = New FileStream(fiCustomers.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    xdCustomers.Load(fsCustomers)
                    Dim xnlCustomers As XmlNodeList = xdCustomers.DocumentElement.ChildNodes
    
                    For Each xnCustomer As XmlNode In xnlCustomers
                        Dim lviCustomer As ListViewItem = New ListViewItem(i.ToString())
    
                        lviCustomer.SubItems.Add(xnCustomer.FirstChild.InnerText)   ' Account #
                        lviCustomer.SubItems.Add(xnCustomer.FirstChild.NextSibling.InnerText)   ' Account Name
                        lviCustomer.SubItems.Add(xnCustomer.FirstChild.NextSibling.NextSibling.InnerText) REM Meter #
                        lviCustomer.SubItems.Add(xnCustomer.FirstChild.NextSibling.NextSibling.NextSibling.InnerText)   ' Account Type
                        lviCustomer.SubItems.Add(xnCustomer.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.InnerText)   ' Address
                        lviCustomer.SubItems.Add(xnCustomer.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText)   ' City
                        lviCustomer.SubItems.Add(xnCustomer.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText)   ' County
                        lviCustomer.SubItems.Add(xnCustomer.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText)   ' State
                        lviCustomer.SubItems.Add(xnCustomer.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText) REM ZIP-Code
    
                        LvwCustomers.Items.Add(lviCustomer)
    
                        i = i + 1
                    Next
                End Using
            End If
        End Sub
    
        Private Sub ClientCentral_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            ShowCustomers()
        End Sub
    End Class
  11. In the Solution Explorer, double-click WaterDistribution.cs to diaply the primary form of the application
  12. From the Toolbox, add a button to the form
  13. From the Properties window, change the characteristics of the button as follows:

    Stellar Water Point

    Control (Name) Text Font
    Button Button BtnCustomers &Customers... Times New Roman, 24pt, style=Bold
  14. On the form, double-click the Customers button
  15. Implement the event as follows:
    Imports System.IO
    
    Public Class WaterDistribution
        Private Sub Exercise_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            REM If the directory for the database doesn't yet exist, create it
            Directory.CreateDirectory("C:\Stellar Water Point12")
        End Sub
    
        Private Sub BtnCustomers_Click(sender As Object, e As EventArgs) Handles BtnCustomers.Click
            Dim Central As ClientCentral = New ClientCentral()
    
            Central.ShowDialog()
        End Sub
    
        Private Sub BtnWaterMeters_Click(sender As Object, e As EventArgs) Handles BtnWaterMeters.Click
            Dim Central = New MeterCentral
    
            Central.ShowDialog()
        End Sub
    End Class

A Customer's Account

As mentioned already, our application will use a database that contains a list of customers. This means that a customer must have an account. We will create a form to let the user create an account. Each customer account must have an associated water meter.

Practical LearningPractical Learning: Creating a Customer Account

  1. In the Solution Explorer, right-click the Customers folder -> Add -> Form (Windows Forms)...
  2. Type ClientCreate as the name of the file
  3. Click Add
  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. Using the Properties window, change some characteristics of the form as follows:
    FormBorderStyle: FixedDialog
    Text:            Stellar Water Point - Customer Account Setup
    StartPosition:   CenterScreen
    AcceptButton:    BtnSaveCustomerAccount
    CancelButton:    BtnClose
    MinimizeBox:     False
    MaximizeBox:     False
  6. On the form, double-click the Find Water Meter button
  7. Change the document as follows:
    Imports System.IO
    Imports System.Xml
    
    Public Class ClientCreate
        Private Sub BtnFindWaterMeter_Click(sender As Object, e As EventArgs) Handles BtnFindWaterMeter.Click
            REM Create an XML Dom object
            Dim xdWaterMeters As XmlDocument = New XmlDocument()
            REM Declare a string variable and assign the file of water meters to it
            Dim strWaterMeters As String = "C:\Stellar Water Point12\WaterMeters.xml"
            REM Create a FileInfo object to manage the file that has the water meters
            Dim fiWaterMeters As FileInfo = New FileInfo(strWaterMeters)
    
            REM Find out whether a file for water meters exists already
            If fiWaterMeters.Exists Then
                REM If a file for water meters exists already, create a Stream object for it
                Using fsWaterMeters As FileStream = New FileStream(fiWaterMeters.FullName, FileMode.Open,
                                                                  FileAccess.Read, FileShare.Read)
                    REM From the file of water meters, store the list of water meters 
                    REM in the XML Dom that was previously created.
                    xdWaterMeters.Load(fsWaterMeters)
    
                    REM Check the list of water meters. 
                    REM Find a water meter that has the same name as the meter number that the user typed.
                    Dim xnlWaterMeters As XmlNodeList = xdWaterMeters.DocumentElement.SelectNodes("//meter-number[.='" + MtbMeterNumber.Text + "']")
    
                    REM If such a water meter exists...
                    For Each xnWaterMeter As XmlNode In xnlWaterMeters
                        REM ... store its details in the meter details text box.
                        TxtMeterDetails.Text = xnWaterMeter.NextSibling.InnerText + " " +
                                               xnWaterMeter.NextSibling.NextSibling.InnerText + " (Meter Size: " +
                                               xnWaterMeter.NextSibling.NextSibling.NextSibling.InnerText + ")"
                    Next
                End Using
            End If
        End Sub
    End Class
  8. In the Solution Explorer, double-click ClientCentral.cs
  9. From the Toolbox, add a button to the form below the list view
  10. Change the characteristics of the button as follows:

    Stellar Water Point - Water Meters

    Control (Name) Other Properties
    ListView List View LvwCustomers  
    Button Button BtnCreateCustomerAccount &Create Customer Account...
  11. Double-click the Create Customer Account button
  12. Change the document as follows:
    Private Sub BtnCreateCustomerAccount_Click(sender As Object, e As EventArgs) Handles BtnCreateCustomerAccount.Click
        Dim Create As ClientCreate = New ClientCreate()
    
        If create.ShowDialog() = MsgBoxResult.Ok Then
            ' Make sure the user provides an account number for the new account. 
            ' If not, don't create the account.
            If String.IsNullOrEmpty(create.MtbAccountNumber.Text) Then
                MsgBox("You must provide an account number for the new customer. " +
                                "Otherwise, the account cannot be created.",
                                MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                                "Stellar Water Point")
    
    
            End If
    
            ' If the meter details text box is empty, it means the user didn't enter
            ' a meter number, in which case there is no water meter associated 
            ' with the account. The account cannot be created.
            If String.IsNullOrEmpty(create.TxtMeterDetails.Text) Then
                MsgBox("You must enter a water meter to associate with a new customer's account.",
                                MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                                "Stellar Water Point")
            End If
    
            ' Create a FileInfo object that will be used to manage a file
            Dim fiCustomers As FileInfo = Nothing
            ' Create an XML Dom
            Dim xdCustomers As XmlDocument = New XmlDocument()
            ' Declare a string variable for the file that contains a list of customers
            Dim strCustomers As String = "C:\Stellar Water Point12\Customers.xml"
    
            ' Pass the file of customers to the FileInfo object that was started
            fiCustomers = New FileInfo(strCustomers)
    
            ' Find out whether that file was already created
            If fiCustomers.Exists Then
                ' If that file was already created, open it through 
                ' the Stream object that was previously initiated.
                Using fsCustomers = New FileStream(fiCustomers.FullName, FileMode.Open,
                                                    FileAccess.Read, FileShare.Read)
                    ' Pass the Stream object to the XML Dom that was previously created.
                    xdCustomers.Load(fsCustomers)
                End Using
            Else
                ' If the file of customers was not created already, start by 
                ' initializing the Stream object that was previously initiated.
                Using fsCustomers = New FileStream(fiCustomers.FullName, FileMode.Create, FileAccess.Write, FileShare.Write)
                    ' Create a root to start the XML file
                    xdCustomers.LoadXml("<?xml version=""1.0"" encoding=""utf-8""?>" +
                                            "<customers></customers>")
                    ' Once the file has been started, save it
                    xdCustomers.Save(fsCustomers)
                End Using
            End If
    
            ' Now that we have an XML file for customers, open it
            Using fsCustomers = New FileStream(fiCustomers.FullName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite)
                ' We want to create an XML element to be added to the XML file.
                ' To start, create an XML element named "customer".
                Dim xeCustomer As XmlElement = xdCustomers.CreateElement("customer")
    
                ' Create/Format the child nodes of the "customer" element
                xeCustomer.InnerXml = "<account-number>" + Create.MtbAccountNumber.Text + "</account-number>" +
                                      "<account-name>" + Create.TxtAccountName.Text + "</account-name>" +
                                      "<meter-number>" + Create.MtbMeterNumber.Text + "</meter-number>" +
                                      "<account-type>" + Create.CbxAccountsTypes.Text + "</account-type>" +
                                      "<address>" + Create.TxtAddress.Text + "</address>" +
                                      "<city>" + Create.TxtCity.Text + "</city>" +
                                      "<county>" + Create.TxtCounty.Text + "</county>" +
                                      "<state>" + Create.TxtState.Text + "</state>" +
                                      "<zip-code>" + Create.MtbZIPCode.Text + "</zip-code>"
                xdCustomers.DocumentElement.AppendChild(xeCustomer)
                xdCustomers.Save(fsCustomers)
            End Using
        End If
    
        ShowCustomers()
    End Sub
  13. To execute the application, on the main menu, click Debug -> Start Without Debugging:

    Stellar Water Point - New Customer Account

  14. On the Water Distribution form, click the Customers button:

    Stellar Water Point - Customers Accounts

  15. On the Central form of the customers, click the Create Customer Account button:

    Stellar Water Point - Customers Accounts

  16. In the account # text box, type 9279-570-8394
  17. In the meter # text box, type 799-528-461
  18. Click the Find water meter button
  19. 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

    Stellar Water Point - New Customer Account

  20. Click Save Customer Account
  21. 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

  22. Close the forms and return to your programming environment

A Review of a Customer's Account

Some time to time, a user will want to review the details of a customer's account. We will create a form to assist the user with this.

Practical LearningPractical Learning: Creating a Water Meter Record

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

    Stellar Water Point - Customer Account Details

    Control (Name) Text Enabled 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   False  
    Label Label   Meter Details:    
    TextBox Text Box TxtMeterDetails   False  
    Label Label   Account Type:    
    TextBox Text Box TxtAccountType   False  
    Label Label   Address:    
    TextBox Text Box TxtAddress   False  
    Label Label   City:    
    TextBox Text Box TxtCity   False  
    Label Label   County:    
    TextBox Text Box TxtCounty   False  
    Label Label   State:    
    TextBox Text Box TxtState   False  
    Label Label   ZIP-Code:    
    TextBox Masked Text Box TxtZIPCode   False  
    Button Button BtnClose &Close  
  5. Using the Properties window, change some characteristics of the form as follows:
    FormBorderStyle: FixedDialog
    Text:            Stellar Water Point - Customer Account Setup
    StartPosition:   CenterScreen
    MinimizeBox:     False
    MaximizeBox:     False
  6. On the form, double-click the Find Cust&omer Account button
  7. Implement the event as follows:
    Private Sub BtnFindCustomerAccount_Click(sender As Object, e As EventArgs) Handles BtnFindCustomerAccount.Click
        Dim xdCustomers As XmlDocument = New XmlDocument()
        Dim strCustomers = "C:\Stellar Water Point12\Customers.xml"
    
        Dim fiCustomers As FileInfo = New FileInfo(strCustomers)
    
        Dim strMeterNumber As String = Nothing
    
        If fiCustomers.Exists Then
            Using fsCustomers As FileStream = New FileStream(fiCustomers.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                xdCustomers.Load(fsCustomers)
                Dim xnlCustomers As XmlNodeList = xdCustomers.DocumentElement.SelectNodes("//account-number[.='" + MtbAccountNumber.Text + "']")
    
                If xnlCustomers.Count = 0 Then
                        MsgBox("There is no customer with that account number",
                               MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                               "Stellar Water Point")
                        TxtAccountName.Text = String.Empty
                        TxtMeterDetails.Text = String.Empty
                        strMeterNumber = String.Empty
                        TxtAccountType.Text = String.Empty
                        TxtAddress.Text = String.Empty
                        TxtCity.Text = String.Empty
                        TxtCounty.Text = String.Empty
                        TxtState.Text = String.Empty
                        TxtZIPCode.Text = String.Empty
                        Exit Sub
                Else
                        REM Check each node of the XML record and display its values in each Windows control on the form
                        For Each xnCustomer As XmlNode In xnlCustomers
                            ' MtbAccountNumber.Text = xnCustomer.NextSibling.InnerText   ' Meter #
                            TxtAccountName.Text = xnCustomer.NextSibling.InnerText ' Account Name
                            TxtMeterDetails.Text = xnCustomer.NextSibling.NextSibling.InnerText   ' Meter Details
                            strMeterNumber = xnCustomer.NextSibling.NextSibling.InnerText   ' Meter Number
                            TxtAccountType.Text = xnCustomer.NextSibling.NextSibling.NextSibling.InnerText   ' Account Type
                            TxtAddress.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.InnerText   ' Address
                            TxtCity.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText   ' City
                            TxtCounty.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText   ' County
                            TxtState.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText   ' State
                            TxtZIPCode.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText ' ZIP-Code
                        Next
                End If
            End Using
        End If
    
        Dim xdWaterMeters As XmlDocument = New XmlDocument()
        Dim strWaterMeters As String = "C:\Stellar Water Point12\WaterMeters.xml"
    
        Dim fiWaterMeters As FileInfo = New FileInfo(strWaterMeters)
    
        If fiWaterMeters.Exists Then
            Using fsWaterMeters As FileStream = New FileStream(fiWaterMeters.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                xdWaterMeters.Load(fsWaterMeters)
                Dim xnlWaterMeters As XmlNodeList = xdWaterMeters.DocumentElement.SelectNodes("//meter-number[.='" + strMeterNumber + "']")
    
                For Each xnWaterMeter As XmlNode In xnlWaterMeters
                    TxtMeterDetails.Text = xnWaterMeter.NextSibling.InnerText + " " +
                                               xnWaterMeter.NextSibling.NextSibling.InnerText + " (Meter Size: " +
                                               xnWaterMeter.NextSibling.NextSibling.NextSibling.InnerText + ")"
                Next
            End Using
        End If
    End Sub
  8. Return to the form and double-click the Close button
  9. Implement the event as follows:
    Imports System.IO
    Imports System.Xml
    
    Public Class ClientDetails
        Private Sub BtnFindCustomerAccount_Click(sender As Object, e As EventArgs) Handles BtnFindCustomerAccount.Click
            ' Create an XML DOM object for the customers records
            Dim xdCustomers As XmlDocument = New XmlDocument()
            ' Declare a variable for a file that holds the list of customers
            Dim strCustomers = "C:\Stellar Water Point12\Customers.xml"
    
            ' Create a FileInfo object for the customers
            Dim fiCustomers As FileInfo = New FileInfo(strCustomers)
    
            ' We will need to know the water meter associated with this customer account
            Dim strMeterNumber As String = Nothing
    
            ' Check whether the file that holds a list of customers exists
            If fiCustomers.Exists Then
                REM If that exists, open it and pass it to a FileStream object
                Using fsCustomers As FileStream = New FileStream(fiCustomers.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    REM Get the list of customers and pass the records to the XML DOM object created earlier
                    xdCustomers.Load(fsCustomers)
                    REM Create an XmlNodeList list of customers using XPath
                    Dim xnlCustomers As XmlNodeList = xdCustomers.DocumentElement.SelectNodes("//account-number[.='" + MtbAccountNumber.Text + "']")
    
                    If xnlCustomers.Count = 0 Then
                        MsgBox("There is no customer with that account number",
                               MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                               "Stellar Water Point")
                        TxtAccountName.Text = String.Empty
                        TxtMeterDetails.Text = String.Empty
                        strMeterNumber = String.Empty
                        TxtAccountType.Text = String.Empty
                        TxtAddress.Text = String.Empty
                        TxtCity.Text = String.Empty
                        TxtCounty.Text = String.Empty
                        TxtState.Text = String.Empty
                        TxtZIPCode.Text = String.Empty
                        Exit Sub
                    Else
                        REM Check each node of the XML record and display its values in each Windows control on the form
                        For Each xnCustomer As XmlNode In xnlCustomers
                            ' MtbAccountNumber.Text = xnCustomer.NextSibling.InnerText   ' Meter #
                            TxtAccountName.Text = xnCustomer.NextSibling.InnerText ' Account Name
                            TxtMeterDetails.Text = xnCustomer.NextSibling.NextSibling.InnerText   ' Meter Details
                            strMeterNumber = xnCustomer.NextSibling.NextSibling.InnerText   ' Meter Number
                            TxtAccountType.Text = xnCustomer.NextSibling.NextSibling.NextSibling.InnerText   ' Account Type
                            TxtAddress.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.InnerText   ' Address
                            TxtCity.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText   ' City
                            TxtCounty.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText   ' County
                            TxtState.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText   ' State
                            TxtZIPCode.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText ' ZIP-Code
                        Next
                    End If
                End Using
            End If
    
            REM Create an XML DOM object for the water meters records
            Dim xdWaterMeters As XmlDocument = New XmlDocument()
            REM Declare a variable for a file that holds the list of water meters
            Dim strWaterMeters As String = "C:\Stellar Water Point12\WaterMeters.xml"
    
            REM Create a FileInfo object for the customers
            Dim fiWaterMeters As FileInfo = New FileInfo(strWaterMeters)
    
            REM Check whether the file that holds a list of water meters exists
            If fiWaterMeters.Exists Then
                ' Get the list of water meters and pass the records to the XML DOM object
                Using fsWaterMeters As FileStream = New FileStream(fiWaterMeters.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    ' Get the list of water meters and pass the records to the XML DOM object
                    xdWaterMeters.Load(fsWaterMeters)
                    ' Create an XmlNodeList list of water meters using XPath
                    Dim xnlWaterMeters As XmlNodeList = xdWaterMeters.DocumentElement.SelectNodes("//meter-number[.='" + strMeterNumber + "']")
    
                    ' Check each node of the XML record
                    For Each xnWaterMeter As XmlNode In xnlWaterMeters
                        ' Get the values for the water meter.
                        ' Create a sentence and display it in the Meter Details text box.
                        TxtMeterDetails.Text = xnWaterMeter.NextSibling.InnerText + " " +
                                                   xnWaterMeter.NextSibling.NextSibling.InnerText + " (Meter Size: " +
                                                   xnWaterMeter.NextSibling.NextSibling.NextSibling.InnerText + ")"
                    Next
                End Using
            End If
        End Sub
    
        Private Sub BtnClose_Click(sender As Object, e As EventArgs) Handles BtnClose.Click
            Close()
        End Sub
    End Class
  10. In the Solution Explorer, double-click ClientCentral.cs to open its form
  11. From the Toolbox, add a button to the form below the list view and to the right of the Create Customer Account button
  12. Change the characteristics of the button as follows:

    Stellar Water Point - Water Meters

    Control (Name) Other Properties
    Button Button BtnViewCustomerAccount &View Customer Account...
  13. Double-click the View Customer Account button
  14. Change the document as follows:
    Private Sub BtnViewCustomerDetails_Click(sender As Object, e As EventArgs) Handles BtnViewCustomerDetails.Click
        Dim Details As ClientDetails = New ClientDetails
    
        Details.ShowDialog()
    End Sub
  15. To execute the application, on the main menu, click Debug -> Start Without Debugging

    Stellar Water Point

  16. On the Water Distribution form, click the Customers button:

    Stellar Water Point - Customers

  17. On the Central form of customers, click the View Customer Account button:

    Stellar Water Point - View Water Meter

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

    Stellar Water Point - View Water Meter

  20. Close the Details form
  21. Close the forms and return to your programming environment

Updating a Customer's Account

Some time to time, a piece of information changes about a customer's account. When that happens, a user must update such an account. To assist the users in performing such an operation, we will create a form.

Practical LearningPractical Learning: Updating a Water Meter

  1. To create a form, in the Solution Explorer, right-click StellarWaterPoint -> Add -> Form (Windows Forms)...
  2. For the Name of the file, type ClientEditor as the name of the form
  3. Click Add
  4. Resize the ClientEditor form to have the same size as the ClientCreate form
  5. Copy everything from the Create form of the Customers section and paste it in the Editor form of the Customers section
  6. Change the design of the form as follows:

    Stellar Water Point - New Customer Account

    Control (Name) Text Other Properties
    Button Button BtnFindCustomerAccount &Find Customer Account  
    Button Button BtnUpdateWateMeter &Update Water Meter DialogResult: OK
    Button Button BtnClose &Close DialogResult: Cancel
  7. Using the Properties window, change some characteristics of the form as follows:
    FormBorderStyle: FixedDialog
    Text:            Stellar Water Point - Customer Account Editor
    StartPosition:   CenterScreen
    AcceptButton:    BtnUpdateWateMeter
    CancelButton:    BtnClose
    MinimizeBox:     False
    MaximizeBox:     False
  8. On the form, double-click the Find Customer Account button
  9. Change the document as follows:
    Imports System.IO
    Imports System.Xml
    
    Public Class ClientEditor
        Private Sub BtnFindCustomerAccount_Click(sender As Object, e As EventArgs) Handles BtnFindCustomerAccount.Click
            Dim xdCustomers As XmlDocument = New XmlDocument()
            Dim strCustomers = "C:\Stellar Water Point12\Customers.xml"
    
            Dim fiCustomers As FileInfo = New FileInfo(strCustomers)
    
            Dim strMeterNumber = Nothing
    
            If fiCustomers.Exists Then
                Using fsCustomers As FileStream = New FileStream(fiCustomers.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    xdCustomers.Load(fsCustomers)
                    Dim xnlCustomers As XmlNodeList = xdCustomers.DocumentElement.SelectNodes("//account-number[.='" + MtbAccountNumber.Text + "']")
    
                    For Each xnCustomer As XmlNode In xnlCustomers
                        ' MtbAccountNumber.Text = xnCustomer.NextSibling.InnerText   rem Meter #
                        TxtAccountName.Text = xnCustomer.NextSibling.InnerText REM Account Name
                        MtbMeterNumber.Text = xnCustomer.NextSibling.NextSibling.InnerText   REM Meter Number
                        strMeterNumber = xnCustomer.NextSibling.NextSibling.InnerText   REM Meter Number
                        CbxAccountsTypes.Text = xnCustomer.NextSibling.NextSibling.NextSibling.InnerText   REM Account Type
                        TxtAddress.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.InnerText   REM Address
                        TxtCity.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText   REM City
                        TxtCounty.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText   REM County
                        TxtState.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText   REM State
                        MtbZIPCode.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText REM ZIP-Code
                    Next
                End Using
            End If
    
            Dim xdWaterMeters As XmlDocument = New XmlDocument()
            Dim strWaterMeters As String = "C:\Stellar Water Point12\WaterMeters.xml"
    
            Dim fiWaterMeters As FileInfo = New FileInfo(strWaterMeters)
    
            If fiWaterMeters.Exists Then
                Using fsWaterMeters As FileStream = New FileStream(fiWaterMeters.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    xdWaterMeters.Load(fsWaterMeters)
                    Dim xnlWaterMeters As XmlNodeList = xdWaterMeters.DocumentElement.SelectNodes("//meter-number[.='" + strMeterNumber + "']")
    
                    For Each xnWaterMeter As XmlNode In xnlWaterMeters
                        TxtMeterDetails.Text = xnWaterMeter.NextSibling.InnerText + " " +
                                                   xnWaterMeter.NextSibling.NextSibling.InnerText + " (Meter Size: " +
                                                   xnWaterMeter.NextSibling.NextSibling.NextSibling.InnerText + ")"
                    Next
                End Using
            End If
        End Sub
    End Class
  10. Return to the form and double-click the Find Water Meter button
  11. Implement the event as follows:
    Imports System.IO
    Imports System.Xml
    
    Public Class ClientEditor
        Private Sub BtnFindCustomerAccount_Click(sender As Object, e As EventArgs) Handles BtnFindCustomerAccount.Click
            Dim xdCustomers As XmlDocument = New XmlDocument()
            Dim strCustomers = "C:\Stellar Water Point12\Customers.xml"
    
            Dim fiCustomers As FileInfo = New FileInfo(strCustomers)
    
            Dim strMeterNumber = Nothing
    
            If fiCustomers.Exists Then
                Using fsCustomers As FileStream = New FileStream(fiCustomers.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    xdCustomers.Load(fsCustomers)
                    Dim xnlCustomers As XmlNodeList = xdCustomers.DocumentElement.SelectNodes("//account-number[.='" + MtbAccountNumber.Text + "']")
    
                    For Each xnCustomer As XmlNode In xnlCustomers
                        ' MtbAccountNumber.Text = xnCustomer.NextSibling.InnerText   rem Meter #
                        TxtAccountName.Text = xnCustomer.NextSibling.InnerText REM Account Name
                        MtbMeterNumber.Text = xnCustomer.NextSibling.NextSibling.InnerText   REM Meter Number
                        strMeterNumber = xnCustomer.NextSibling.NextSibling.InnerText   REM Meter Number
                        CbxAccountsTypes.Text = xnCustomer.NextSibling.NextSibling.NextSibling.InnerText   REM Account Type
                        TxtAddress.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.InnerText   REM Address
                        TxtCity.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText   REM City
                        TxtCounty.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText   REM County
                        TxtState.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText   REM State
                        MtbZIPCode.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText REM ZIP-Code
                    Next
                End Using
            End If
    
            Dim xdWaterMeters As XmlDocument = New XmlDocument()
            Dim strWaterMeters As String = "C:\Stellar Water Point12\WaterMeters.xml"
    
            Dim fiWaterMeters As FileInfo = New FileInfo(strWaterMeters)
    
            If fiWaterMeters.Exists Then
                Using fsWaterMeters As FileStream = New FileStream(fiWaterMeters.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    xdWaterMeters.Load(fsWaterMeters)
                    Dim xnlWaterMeters As XmlNodeList = xdWaterMeters.DocumentElement.SelectNodes("//meter-number[.='" + strMeterNumber + "']")
    
                    For Each xnWaterMeter As XmlNode In xnlWaterMeters
                        TxtMeterDetails.Text = xnWaterMeter.NextSibling.InnerText + " " +
                                                   xnWaterMeter.NextSibling.NextSibling.InnerText + " (Meter Size: " +
                                                   xnWaterMeter.NextSibling.NextSibling.NextSibling.InnerText + ")"
                    Next
                End Using
            End If
        End Sub
    
        Private Sub BtnFindWaterMeter_Click(sender As Object, e As EventArgs) Handles BtnFindWaterMeter.Click
            Dim xdWaterMeters As XmlDocument = New XmlDocument()
            Dim strWaterMeters As String = "C:\Stellar Water Point12\WaterMeters.xml"
            Dim fiWaterMeters As FileInfo = New FileInfo(strWaterMeters)
    
            If fiWaterMeters.Exists Then
                Using fsWaterMeters As FileStream = New FileStream(fiWaterMeters.FullName, FileMode.Open,
                                                                      FileAccess.Read, FileShare.Read)
                    xdWaterMeters.Load(fsWaterMeters)
    
                    Dim xnlWaterMeters As XmlNodeList = xdWaterMeters.DocumentElement.SelectNodes("//meter-number[.='" + MtbMeterNumber.Text + "']")
    
                    For Each xnWaterMeter As XmlNode In xnlWaterMeters
                        TxtMeterDetails.Text = xnWaterMeter.NextSibling.InnerText + " " +
                                                   xnWaterMeter.NextSibling.NextSibling.InnerText + " (Meter Size: " +
                                                   xnWaterMeter.NextSibling.NextSibling.NextSibling.InnerText + ")"
                    Next
                End Using
            End If
        End Sub
    End Class
  12. In the Solution Explorer, double-click ClientCentral.cs
  13. From the Toolbox, add a button to the form below the list view and on the right side of the View Customer Account button
  14. Change the characteristics of the button as follows:

    Stellar Water Point - Water Meters

    Control (Name) Text Other Properties
    ListView List View LvwCustomers   No Change
    Button Button BtnNewCustomerAccount   No Change
    Button Button BtnViewCustomerAccount   No Change
    Button Button BtnEditCustomerAccount &Edit Water Meter...  
  15. Display the ClientCentral form
  16. Double-click the Edit Water Meter button
  17. Implement the event as follows:
    Private Sub BtnEditCustomerAccount_Click(sender As Object, e As EventArgs) Handles BtnEditCustomerAccount.Click
        Dim Editor As ClientEditor = New ClientEditor()
        Dim xdCustomers As XmlDocument = New XmlDocument()
        Dim strCustomers = "C:\Stellar Water Point12\Customers.xml"
    
        If editor.ShowDialog() = MsgBoxResult.Ok Then
            xdCustomers.Load(strCustomers)
    
            Dim xnlCustomers = xdCustomers.DocumentElement.GetElementsByTagName("account-number")
    
            For Each xnCustomer As XmlNode In xnlCustomers
                If xnCustomer.InnerText.Contains(editor.MtbAccountNumber.Text) Then
                    xnCustomer.ParentNode.InnerXml = "<account-number>" + Editor.MtbAccountNumber.Text + "</account-number>" +
                                          "<account-name>" + Editor.TxtAccountName.Text + "</account-name>" +
                                          "<meter-number>" + Editor.MtbMeterNumber.Text + "</meter-number>" +
                                          "<account-type>" + Editor.CbxAccountsTypes.Text + "</account-type>" +
                                          "<address>" + Editor.TxtAddress.Text + "</address>" +
                                          "<city>" + Editor.TxtCity.Text + "</city>" +
                                          "<county>" + Editor.TxtCounty.Text + "</county>" +
                                          "<state>" + Editor.TxtState.Text + "</state>" +
                                          "<zip-code>" + Editor.MtbZIPCode.Text + "</zip-code>"
    
                    xdCustomers.Save(strCustomers)
                    Exit For
                End If
            Next
        End If
    
        ShowCustomers()
    End Sub
  18. To execute the application, on the main menu, click Debug -> Start Without Debugging

    Stellar Water Point

  19. On the main form of the application, click the Customers button:

    Stellar Water Point - Customers

  20. Click the Edit Customer Account button:

    Stellar Water Point - Water Meter Editor

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

    Stellar Water Point - Water Meter Editor

  23. Change the values as follows:
    Account Name: Bernotte's 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

  24. Click the Update Customer Account button:

    Stellar Water Point - Water Meters

  25. Close the forms and return to your programming environment

Deleting a Customer's Account

If a customer's account is not necessary anymore, the user can remove that account. To assist the user with this operation, we will create a form with necessary buttons.

Practical LearningPractical Learning: Deleting a Customer Account

  1. To create a form, in the Solution Explorer, right-click StellarWaterPoint -> Add -> Form(Windows Forms)...
  2. In the Name text box, replace the string with ClientDelete as the name of the form
  3. Press Enter
  4. Resize the Delete form to have the same size as the Details form
  5. Copy everything from the Details form and paste it in the Delete form
  6. Change the bottom button as follows:

    Stellar Water Point - New Water Meter

    Control (Name) Text Othe Properties
    Button Button BtnDeleteCustomerAccount &Delete Water Meter DialogResult: OK
    Button Button BtnClose &Close DialogResult: Cancel
  7. Using the Properties window, change some characteristics of the form as follows:
    FormBorderStyle: FixedDialog
    Text:            Stellar Water Point - Customer Account Deletion
    StartPosition:   CenterScreen
    AcceptButton:    BtnDeleteCustomerAccount
    CancelButton:    BtnClose
    MinimizeBox:     False
    MaximizeBox:     False
  8. On the form, double-click the Find Customer Account button
  9. Change the document as tollows:
    Imports System.IO
    Imports System.Xml
    
    Public Class ClientDelete
        Private Sub BtnFindCustomerAccount_Click(sender As Object, e As EventArgs) Handles BtnFindCustomerAccount.Click
            ' Create an XML DOM object for the customers records
            Dim xdCustomers As XmlDocument = New XmlDocument()
            ' Declare a variable for a file that holds the list of customers
            Dim strCustomers = "C:\Stellar Water Point12\Customers.xml"
    
            ' Create a FileInfo object for the customers
            Dim fiCustomers As FileInfo = New FileInfo(strCustomers)
    
            ' We will need to know the water meter associated with this customer account
            Dim strMeterNumber = Nothing
    
            ' Check whether the file that holds a list of customers exists
            If fiCustomers.Exists Then
                ' If that exists, open it and pass it to a FileStream object
                Using fsCustomers As FileStream = New FileStream(fiCustomers.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    ' Get the list of customers and pass the records to the XML DOM object created earlier
                    xdCustomers.Load(fsCustomers)
    
                    ' Create an XmlNodeList list of customers using XPath
                    Dim xnlCustomers As XmlNodeList = xdCustomers.DocumentElement.SelectNodes("//account-number[.='" + MtbAccountNumber.Text + "']")
    
                    If xnlCustomers.Count = 0 Then
                        MsgBox("There is no customer with that account number",
                               MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                               "Stellar Water Point")
                        TxtAccountName.Text = String.Empty
                        TxtMeterDetails.Text = String.Empty
                        strMeterNumber = String.Empty
                        TxtAccountType.Text = String.Empty
                        TxtAddress.Text = String.Empty
                        TxtCity.Text = String.Empty
                        TxtCounty.Text = String.Empty
                        TxtState.Text = String.Empty
                        TxtZIPCode.Text = String.Empty
                        Exit Sub
                    Else
                        ' Check each node of the XML record and display its values in each Windows control on the form
                        For Each xnCustomer As XmlNode In xnlCustomers
                            ' MtbAccountNumber.Text = xnCustomer.NextSibling.InnerText
                            TxtAccountName.Text = xnCustomer.NextSibling.InnerText
                            TxtMeterDetails.Text = xnCustomer.NextSibling.NextSibling.InnerText
                            strMeterNumber = xnCustomer.NextSibling.NextSibling.InnerText
                            TxtAccountType.Text = xnCustomer.NextSibling.NextSibling.NextSibling.InnerText
                            TxtAddress.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                            TxtCity.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                            TxtCounty.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                            TxtState.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                            TxtZIPCode.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        Next
                    End If
                End Using
            End If
    
            ' Create an XML DOM object for the water meters records
            Dim xdWaterMeters As XmlDocument = New XmlDocument()
            ' Declare a variable for a file that holds the list of water meters
            Dim strWaterMeters As String = "C:\Stellar Water Point12\WaterMeters.xml"
    
            ' Create a FileInfo object for the customers
            Dim fiWaterMeters As FileInfo = New FileInfo(strWaterMeters)
    
            REM Check whether the file that holds a list of water meters exists
            If fiWaterMeters.Exists Then
                REM Get the list of water meters and pass the records to the XML DOM object
                Using fsWaterMeters As FileStream = New FileStream(fiWaterMeters.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    ' Get the list of water meters and pass the records to the XML DOM object
                    xdWaterMeters.Load(fsWaterMeters)
    
                    ' Create an XmlNodeList list of water meters using XPath
                    Dim xnlWaterMeters As XmlNodeList = xdWaterMeters.DocumentElement.SelectNodes("//meter-number[.='" + strMeterNumber + "']")
    
                    REM Check each node of the XML record
                    For Each xnWaterMeter As XmlNode In xnlWaterMeters
                        '  Get the values for the water meter.
                        '  Create a sentence and display it in the Meter Details text box.
                        TxtMeterDetails.Text = xnWaterMeter.NextSibling.InnerText + " " +
                                                   xnWaterMeter.NextSibling.NextSibling.InnerText + " (Meter Size: " +
                                                   xnWaterMeter.NextSibling.NextSibling.NextSibling.InnerText + ")"
                    Next
                End Using
            End If
        End Sub
    End Class
  10. In the Solution Explorer, double-click ClientCentral.cs
  11. From the Toolbox, add two buttons to the form below the list view and on the right side of the Edit Customer Acount button
  12. Change the characteristics of the new buttons as follows:

    Stellar Water Point - Water Meters

    Control (Name) Text Anchor Other Properties
    ListView List View LvwCustomers   Top, Bottom, Left, Right FullRowSelect: True
    GridLines: True
    View: Details
    Button Button BtnCreateCustomerAcount C&reate Customer Acount... Bottom, Right  
    Button Button BtnViewCustomerAcount &View CustomerAcount... Bottom, Right  
    Button Button BtnEditCustomerAcount &Edit CustomerAcount... Bottom, Right  
    Button Button BtnDeleteCustomerAcount &Delete Customer Acount... Bottom, Right  
    Button Button BtnClose &Close Anchor: Bottom, Right  
  13. Double-click the Delete Customer Account button
  14. Return to the Central form of the water meters and double-click the Close button
  15. Change the document as follows:
    Imports System.IO
    Imports System.Xml
    
    Public Class ClientCentral
        Sub ShowCustomers()
            Dim i As Integer = 1
    
            LvwCustomers.Items.Clear()
    
            Dim xdCustomers As XmlDocument = New XmlDocument()
            Dim strCustomers As String = "C:\Stellar Water Point12\Customers.xml"
    
            Dim fiCustomers As FileInfo = New FileInfo(strCustomers)
    
            If fiCustomers.Exists Then
                Using fsCustomers As FileStream = New FileStream(fiCustomers.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    xdCustomers.Load(fsCustomers)
                    Dim xnlCustomers As XmlNodeList = xdCustomers.DocumentElement.ChildNodes
    
                    For Each xnCustomer As XmlNode In xnlCustomers
                        Dim lviCustomer As ListViewItem = New ListViewItem(i.ToString())
    
                        lviCustomer.SubItems.Add(xnCustomer.FirstChild.InnerText)   ' Account #
                        lviCustomer.SubItems.Add(xnCustomer.FirstChild.NextSibling.InnerText)   ' Account Name
                        lviCustomer.SubItems.Add(xnCustomer.FirstChild.NextSibling.NextSibling.InnerText) REM Meter #
                        lviCustomer.SubItems.Add(xnCustomer.FirstChild.NextSibling.NextSibling.NextSibling.InnerText)   ' Account Type
                        lviCustomer.SubItems.Add(xnCustomer.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.InnerText)   ' Address
                        lviCustomer.SubItems.Add(xnCustomer.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText)   ' City
                        lviCustomer.SubItems.Add(xnCustomer.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText)   ' County
                        lviCustomer.SubItems.Add(xnCustomer.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText)   ' State
                        lviCustomer.SubItems.Add(xnCustomer.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText) REM ZIP-Code
    
                        LvwCustomers.Items.Add(lviCustomer)
    
                        i = i + 1
                    Next
                End Using
            End If
        End Sub
    
        Private Sub ClientCentral_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            ShowCustomers()
        End Sub
    
        Private Sub BtnCreateCustomerAccount_Click(sender As Object, e As EventArgs) Handles BtnCreateCustomerAccount.Click
            Dim Create As ClientCreate = New ClientCreate()
    
            If create.ShowDialog() = MsgBoxResult.Ok Then
                ' Make sure the user provides an account number for the new account. 
                ' If not, don't create the account.
                If String.IsNullOrEmpty(create.MtbAccountNumber.Text) Then
                    MsgBox("You must provide an account number for the new customer. " +
                                    "Otherwise, the account cannot be created.",
                                    MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                                    "Stellar Water Point")
    
    
                End If
    
                ' If the meter details text box is empty, it means the user didn't enter
                ' a meter number, in which case there is no water meter associated 
                ' with the account. The account cannot be created.
                If String.IsNullOrEmpty(create.TxtMeterDetails.Text) Then
                    MsgBox("You must enter a water meter to associate with a new customer's account.",
                                    MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                                    "Stellar Water Point")
                End If
    
                ' Create a FileInfo object that will be used to manage a file
                Dim fiCustomers As FileInfo = Nothing
                ' Create an XML Dom
                Dim xdCustomers As XmlDocument = New XmlDocument()
                ' Declare a string variable for the file that contains a list of customers
                Dim strCustomers As String = "C:\Stellar Water Point12\Customers.xml"
    
                ' Pass the file of customers to the FileInfo object that was started
                fiCustomers = New FileInfo(strCustomers)
    
                ' Find out whether that file was already created
                If fiCustomers.Exists Then
                    ' If that file was already created, open it through 
                    ' the Stream object that was previously initiated.
                    Using fsCustomers = New FileStream(fiCustomers.FullName, FileMode.Open,
                                                        FileAccess.Read, FileShare.Read)
                        ' Pass the Stream object to the XML Dom that was previously created.
                        xdCustomers.Load(fsCustomers)
                    End Using
                Else
                    ' If the file of customers was not created already, start by 
                    ' initializing the Stream object that was previously initiated.
                    Using fsCustomers = New FileStream(fiCustomers.FullName, FileMode.Create, FileAccess.Write, FileShare.Write)
                        ' Create a root to start the XML file
                        xdCustomers.LoadXml("<?xml version=""1.0"" encoding=""utf-8""?>" +
                                                "<customers></customers>")
                        ' Once the file has been started, save it
                        xdCustomers.Save(fsCustomers)
                    End Using
                End If
    
                ' Now that we have an XML file for customers, open it
                Using fsCustomers = New FileStream(fiCustomers.FullName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite)
                    ' We want to create an XML element to be added to the XML file.
                    ' To start, create an XML element named "customer".
                    Dim xeCustomer As XmlElement = xdCustomers.CreateElement("customer")
    
                    ' Create/Format the child nodes of the "customer" element
                    xeCustomer.InnerXml = "<account-number>" + Create.MtbAccountNumber.Text + "</account-number>" +
                                          "<account-name>" + Create.TxtAccountName.Text + "</account-name>" +
                                          "<meter-number>" + Create.MtbMeterNumber.Text + "</meter-number>" +
                                          "<account-type>" + Create.CbxAccountsTypes.Text + "</account-type>" +
                                          "<address>" + Create.TxtAddress.Text + "</address>" +
                                          "<city>" + Create.TxtCity.Text + "</city>" +
                                          "<county>" + Create.TxtCounty.Text + "</county>" +
                                          "<state>" + Create.TxtState.Text + "</state>" +
                                          "<zip-code>" + Create.MtbZIPCode.Text + "</zip-code>"
                    xdCustomers.DocumentElement.AppendChild(xeCustomer)
                    xdCustomers.Save(fsCustomers)
                End Using
            End If
    
            ShowCustomers()
        End Sub
    
        Private Sub BtnViewCustomerDetails_Click(sender As Object, e As EventArgs) Handles BtnViewCustomerDetails.Click
            Dim Details As ClientDetails = New ClientDetails
    
            Details.ShowDialog()
        End Sub
    
        Private Sub BtnEditCustomerAccount_Click(sender As Object, e As EventArgs) Handles BtnEditCustomerAccount.Click
            Dim Editor As ClientEditor = New ClientEditor()
            Dim xdCustomers As XmlDocument = New XmlDocument()
            Dim strCustomers = "C:\Stellar Water Point12\Customers.xml"
    
            If editor.ShowDialog() = MsgBoxResult.Ok Then
                xdCustomers.Load(strCustomers)
    
                Dim xnlCustomers = xdCustomers.DocumentElement.GetElementsByTagName("account-number")
    
                For Each xnCustomer As XmlNode In xnlCustomers
                    If xnCustomer.InnerText.Contains(editor.MtbAccountNumber.Text) Then
                        xnCustomer.ParentNode.InnerXml = "<account-number>" + Editor.MtbAccountNumber.Text + "</account-number>" +
                                              "<account-name>" + Editor.TxtAccountName.Text + "</account-name>" +
                                              "<meter-number>" + Editor.MtbMeterNumber.Text + "</meter-number>" +
                                              "<account-type>" + Editor.CbxAccountsTypes.Text + "</account-type>" +
                                              "<address>" + Editor.TxtAddress.Text + "</address>" +
                                              "<city>" + Editor.TxtCity.Text + "</city>" +
                                              "<county>" + Editor.TxtCounty.Text + "</county>" +
                                              "<state>" + Editor.TxtState.Text + "</state>" +
                                              "<zip-code>" + Editor.MtbZIPCode.Text + "</zip-code>"
    
                        xdCustomers.Save(strCustomers)
                        Exit For
                    End If
                Next
            End If
    
            ShowCustomers()
        End Sub
    
        Private Sub BtnDeleteCustomerAccount_Click(sender As Object, e As EventArgs) Handles BtnDeleteCustomerAccount.Click
            ' Here is the dialog box that the user will use to locate and delete a customer account
            Dim Delete As ClientDelete = New ClientDelete()
            '  Create an XML DOM object
            Dim xdCustomers As XmlDocument = New XmlDocument()
            '  Specify the file that holds a database of customers
            Dim strCustomers = "C:\Stellar Water Point12\Customers.xml"
    
            ' Open the Delete dialog box.
            ' Find out if the user clicked the Delete Customer Account button to close the Delete dialog box.
            If Delete.ShowDialog() = MsgBoxResult.Ok Then
                ' If there is no file for the list of customers, don't do nothing
                If Not File.Exists(strCustomers) Then
                    MsgBox("There is no file for the customers accounts in the system.",
                                        "Stellar Water Point",
                                        MsgBoxStyle.OkOnly Or MsgBoxStyle.Information)
                    Exit Sub
                End If
    
                ' If the user didn't provide a valid account number, don't do nothing
                If String.IsNullOrEmpty(Delete.MtbAccountNumber.Text) Then
                    MsgBox("You must type an account number for the customer whose account you want to delete one.",
                                        "Stellar Water Point", MsgBoxStyle.OkOnly Or MsgBoxStyle.Information)
                    Exit Sub
                End If
    
                ' Open the file of customers records and put those records in our XML DOM object
                xdCustomers.Load(strCustomers)
    
                ' Create an XmlNodeList list of the customers records. 
                ' Use the Account Number node as reference.
                Dim xnlCustomers As XmlNodeList = xdCustomers.DocumentElement.GetElementsByTagName("account-number")
    
                ' Check each customer record as an XML element
                For Each xnCustomer As XmlNode In xnlCustomers
                    ' When you reach an element, find out whether its value is 
                    ' the same as the account number the user typed on the form.
                    If xnCustomer.InnerText = Delete.MtbAccountNumber.Text Then
                        ' If you find a matching record, find whether the user really wants to delete the record.
                        If MsgBox("Are you sure you want to remove this customer's account from the system?",
                                            "Stellar Water Point",
                                            MsgBoxStyle.YesNo Or MsgBoxStyle.Question) = MsgBoxResult.Yes Then
                            ' If the user really wants to delete the record, delete it...
                            xdCustomers.DocumentElement.RemoveChild(xnCustomer.ParentNode)
                            ' and stop searching
                            Exit For
                        End If
                    End If
                Next
    
                ' After removing the record, save the new version of the file 
                xdCustomers.Save(strCustomers)
            End If
    
            ' Now that the user has closed the Delete dialog box (and probably deleted the XML file), 
            ' redisplay the list of customers.
            ShowCustomers()
        End Sub
    
        Private Sub BtnClose_Click(sender As Object, e As EventArgs) Handles BtnClose.Click
            Close()
        End Sub
    End Class
  16. To execute the application, on the main menu, click Debug -> Start Without Debugging:

    Stellar Water Point - Water Meters

  17. On the Central form, click the Customers button:

    Stellar Water Point - Customers

  18. On the Central form of the customers, click the Delete Customer Account button:

    Stellar Water Point - Customer Account Deletion

  19. In the Account # text box, type 7080-583-5947
  20. Click the Find Customer Account button:

    Stellar Water Point - Customer Account Deletion

  21. Click the Delete Customer Account button
  22. Read the text on the message box.
    On the message box, click Yes

    Stellar Water Point - Customers

  23. Close the forms and return to your programming environment
  24. From the Windows Explorer, open the Customers.xml file
  25. Replace the content of the file with the provided file
  26. Save the file
  27. Return to your programming environment

Water Bills

Introduction

A water bill is a summary that indicates how much water a customer consumed and the value of that consumption. Our application will include the forms necessary to process water bills operations.

A List of Water Bills

A water bill must contain as much information as possible. In our application, when displaying a list of water bills, we will show only select pieces of information.

Practical LearningPractical Learning: Viewing Water Bills

  1. To create a form, in the Solution Explorer, right-click StellarWaterPoint -> Add -> Form (Windows Forms)...
  2. Type BillsCentral
  3. Click Add
  4. In the Toolbox, click the ListView button and click the form
  5. In the Properties window, change the characteristics of the list view as follows:
    Control (Name) Text Other Properties
    ListView List View LvwWaterBills   FullRowSelect: True
    GridLines: True
    View: Details
  6. On the form, right-click the list view and click Edit Columns...
  7. Create the columns as follows:

    Stellar Water Point - Water Bills

    (Name) Text TextAlign Width
    ColWaterBillId Id   40
    ColBillNumber Bill # Center 80
    ColAccountNumber Account # Center 150
    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 80
    ColPaymentDueDate Pmt Due Date Center 125
    ColAmountDue Amt Due Right 90
  8. Click OK
  9. Doubte-click an unoccupied area of the form to generate its Load event
  10. Change the document as follows:
    Imports System.IO
    Imports System.Xml
    
    Public Class BillsCentral
    
        Private Sub ShowWaterBills()
            LvwWaterBills.Items.Clear()
    
            Dim xdWaterBills As XmlDocument = New XmlDocument()
            Dim strWaterBills = "C:\Stellar Water Point12\WaterBills.xml"
    
            Dim fiWaterBills As FileInfo = New FileInfo(strWaterBills)
    
            If fiWaterBills.Exists Then
                Using fsWaterBills As New FileStream(fiWaterBills.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    xdWaterBills.Load(fsWaterBills)
    
                    Dim xnlWaterBills As XmlNodeList = xdWaterBills.DocumentElement.ChildNodes
    
                    Dim i As Integer = 1
    
                    For Each xnWaterBill As XmlNode In xnlWaterBills
                        Dim lviWaterBill As ListViewItem = New ListViewItem(i.ToString())
    
                        lviWaterBill.SubItems.Add(xnWaterBill.FirstChild.InnerText)
                        lviWaterBill.SubItems.Add(xnWaterBill.FirstChild.NextSibling.InnerText)
                        lviWaterBill.SubItems.Add(xnWaterBill.FirstChild.NextSibling.NextSibling.InnerText)
                        lviWaterBill.SubItems.Add(xnWaterBill.FirstChild.NextSibling.NextSibling.NextSibling.InnerText)
                        lviWaterBill.SubItems.Add(xnWaterBill.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.InnerText)
                        lviWaterBill.SubItems.Add(xnWaterBill.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText)
                        lviWaterBill.SubItems.Add(xnWaterBill.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText)
                        lviWaterBill.SubItems.Add(xnWaterBill.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText)
                        lviWaterBill.SubItems.Add(xnWaterBill.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText.ToString())
                        lviWaterBill.SubItems.Add(xnWaterBill.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText)
                        lviWaterBill.SubItems.Add(xnWaterBill.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText)
    
                        LvwWaterBills.Items.Add(lviWaterBill)
    
                        i = i + 1
                    Next
                End Using
            End If
        End Sub
    
        Private Sub BillsCentral_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            ShowWaterBills()
        End Sub
    End Class
  11. In the Solution Explorer, double-click WaterDistribution.cs to open the main form of the application
  12. Change the design of the form as follows:

    Stellar Water Point

    Control (Name) Text Font
    Button Button BtnWaterBills Water &Bills... Times New Roman, 24pt, style=Bold
    Button Button BtnClose &Close Times New Roman, 24pt, style=Bold
  13. Double-click the Water &Bills button
  14. Return to the Water Distribution form and double-click the Close button
  15. Change the document as follows:
    Imports System.IO
    
    Public Class WaterDistribution
        Private Sub Exercise_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            REM If the directory for the database doesn't yet exist, create it
            Directory.CreateDirectory("C:\Stellar Water Point12")
        End Sub
    
        Private Sub BtnWaterBills_Click(sender As Object, e As EventArgs) Handles BtnWaterBills.Click
            Dim Central As BillsCentral = New BillsCentral()
    
            Central.Show()
        End Sub
    
        Private Sub BtnCustomers_Click(sender As Object, e As EventArgs) Handles BtnCustomers.Click
            Dim Central = New ClientCentral
    
            Central.Show()
        End Sub
    
        Private Sub BtnWaterMeters_Click(sender As Object, e As EventArgs) Handles BtnWaterMeters.Click
            Dim Central = New MeterCentral
    
            Central.ShowDialog()
        End Sub
    
        Private Sub BtnClose_Click(sender As Object, e As EventArgs) Handles BtnClose.Click
            Close()
        End Sub
    End Class

A Water Bill

A water bill is a collection of information that includes the identification of the customer who consumed the water, the period during which water was consumed, how much water was consumed, how much that consumption is worth, etc. We will create a form hat a user can use to create and process a water bill.

Practical LearningPractical Learning: Processing a Water Bill

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

    Stellar Water Point - New Water Bill

    Control (Name) Text Other Properties
    Label Label   Water Bill #:  
    TextBox Text Box TxtBillNumber    
    GroupBox Label   Customer Information  
    Label Label   Account #:  
    MaskedTextBox Masked Text Box MtbAccountNumber   Masked: 0000-000-0000
    Button Button BtnFindCustomerAccount Find Customer Account  
    Label Label   Customer Name:  
    TextBox Text Box TxtCustomerName    
    Label Label   Meter Details:  
    TextBox Text Box TxtMeterDetails Modifiers: Public  
    Label Label   Address:  
    TextBox Text Box TxtAddress    
    TextBox Text Box TxtCity    
    TextBox Text Box TxtCounty    
    TextBox Text Box TxtState    
    TextBox Masked Text Box TxtZIPCode  
    GroupBox Label   Meter Reading  
    Label Label   Meter Reading Start Date:  
    DateTimePicker Date Time Picker DtpMeterReadingStartDate  
    Label Label   Meter Reading End Date:  
    DateTimePicker Date Time Picker DtpMeterReadingEndDate  
    Label Label   Counter Reading Start:  
    TextBox Text Box TxtCounterReadingStart    
    Label Label   Counter Reading End:  
    TextBox Text Box TxtCounterReadingEnd    
    Button Button BtnEvaluateWaterBill Evaluate Water Bill  
    GroupBox Label   Meter Result  
    Label Label   Billing Days:  
    TextBox Text Box TxtBillingDays   TextAlign: Right
    Label Label   Total HCF:  
    TextBox Text Box TxtTotalHCF   TextAlign: Right
    Label Label   Total Gallons:  
    TextBox Text Box TxtTotalGallons   TextAlign: Right
    Label Label   First Tier Consumption:  
    TextBox Text Box TxtFirstTierConsumption   TextAlign: Right
    Label Label   Second Tier:  
    TextBox Text Box TxtSecondTierConsumption   TextAlign: Right
    Label Label   Last Tier:  
    TextBox Text Box TxtLastTierConsumption   TextAlign: Right
    GroupBox Label   Consumption Charges  
    Label Label   Water Charges:  
    TextBox Text Box TxtWaterCharges   TextAlign: Right
    Label Label   Sewer Charges:  
    TextBox Text Box TxtSewerCharges   TextAlign: Right
    Label Label   Environment Charges:  
    TextBox Text Box TxtEnvironmentCharges   TextAlign: Right
    Label Label   Service Charges:  
    TextBox Text Box TxtServiceCharges   TextAlign: Right
    Label Label   Total Charges:  
    TextBox Text Box TxtTotalCharges   TextAlign: Right
    GroupBox Label   Taxes  
    Label Label   Local Taxes:  
    TextBox Text Box TxtLocalTaxes   TextAlign: Right
    Label Label   State Taxes:  
    TextBox Text Box TxtStateTaxes   TextAlign: Right
    GroupBox Label   Water Bill Payment  
    Label Label   Payment Due Date:  
    DateTimePicker Date Time Picker DtpPaymentDueDate  
    Label Label   Amount Due:  
    TextBox Text Box TxtAmountDue   TextAlign: Right
    Label Label   Late Payment Due Date:  
    DateTimePicker Date Time Picker DtpLatePaymentDueDate  
    Label Label   Late Amount Due:  
    TextBox Text Box TxtLateAmountDue   TextAlign: Right
    Button Button BtnSaveWaterBill Save Water Bill  
    Button Button BtnClose Close  
  5. On the form, double-click the Find Customer Account button
  6. Change the document as follows:
    Imports System.IO
    Imports System.Xml
    
    Public Class BillCreate
        Private Sub BtnFindCustomerAccount_Click(sender As Object, e As EventArgs) Handles BtnFindCustomerAccount.Click
            Dim xdCustomers As XmlDocument = New XmlDocument()
            Dim strCustomers = "C:\Stellar Water Point12\Customers.xml"
    
            Dim fiCustomers As FileInfo = New FileInfo(strCustomers)
    
            Dim strMeterNumber = String.Empty
    
            If fiCustomers.Exists Then
                Using fsCustomers As FileStream = New FileStream(fiCustomers.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    xdCustomers.Load(fsCustomers)
                    Dim xnlCustomers As XmlNodeList = xdCustomers.DocumentElement.SelectNodes("//account-number[.='" + MtbAccountNumber.Text + "']")
    
                    For Each xnCustomer As XmlNode In xnlCustomers
                        TxtAccountName.Text = xnCustomer.NextSibling.InnerText
                        strMeterNumber = xnCustomer.NextSibling.NextSibling.InnerText
                        TxtAccountType.Text = xnCustomer.NextSibling.NextSibling.NextSibling.InnerText
                        TxtAddress.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtCity.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtCounty.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtState.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtZIPCode.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                    Next
                End Using
            End If
    
            Dim xdWaterMeters As XmlDocument = New XmlDocument()
            Dim strWaterMeters As String = "C:\Stellar Water Point12\WaterMeters.xml"
    
            Dim fiWaterMeters As FileInfo = New FileInfo(strWaterMeters)
    
            If fiWaterMeters.Exists Then
                Using fsWaterMeters As FileStream = New FileStream(fiWaterMeters.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    xdWaterMeters.Load(fsWaterMeters)
                    Dim xnlWaterMeters As XmlNodeList = xdWaterMeters.DocumentElement.SelectNodes("//meter-number[.='" + strMeterNumber + "']")
    
                    For Each xnWaterMeter As XmlNode In xnlWaterMeters
                        TxtMeterDetails.Text = xnWaterMeter.NextSibling.InnerText + " " +
                                               xnWaterMeter.NextSibling.NextSibling.InnerText + " (Meter Size: " +
                                               xnWaterMeter.NextSibling.NextSibling.NextSibling.InnerText + ")"
                    Next
                End Using
            End If
        End Sub
    End Class
  7. Return to the Water Bills - Create form and double-click the Meter Reading End Date date time picker
  8. Implement the event as follows:
    Private Sub DtpMeterReadingEndDate_ValueChanged(sender As Object, e As EventArgs) Handles DtpMeterReadingEndDate.ValueChanged
        TxtBillingDays.Text = DateDiff(DateInterval.Day, DtpMeterReadingStartDate.Value, DtpMeterReadingEndDate.Value) + 1
    End Sub
  9. Return to the Water Bills - Create form and double-click the Evaluate Water Bill button
  10. Implement the event as follows:
    Private Function CalculateTiers(acnt As String, total As Double) As (a As Double, b As Double, c As Double)
        Dim Results = (0.00, 0.00, 0.00)
    
        Select Case acnt
            Case "RES"
                Results.Item1 = total * 38.35 / 10000.0
                Results.Item2 = total * 18.25 / 10000.0
                Results.Item3 = total * 11.65 / 10000.0
    
            Case "SGO"
                Results.Item1 = total * 41.38 / 10000.0
                Results.Item2 = total * 15.26 / 10000.0
                Results.Item3 = total * 8.13 / 10000.0
    
            Case "BUS"
                Results.Item1 = total * 51.25 / 10000.0
                Results.Item2 = total * 34.65 / 10000.0
                Results.Item3 = total * 14.1 / 10000.0
    
            Case "UUO"
                Results.Item1 = total * 25 / 10000.0
                Results.Item2 = total * 35 / 10000.0
                Results.Item3 = total * 40 / 10000.0
    
            Case "WAT"
                Results.Item1 = total * 48 / 10000.0
                Results.Item2 = total * 32 / 10000.0
                Results.Item3 = total * 20 / 10000.0
    
            Case Else
                Results.Item1 = total * 25.0 / 10000.0
                Results.Item2 = total * 35.0 / 10000.0
                Results.Item3 = total * 40.0 / 10000.0
        End Select
    
        Return Results
    End Function
    
    Private Function CalculateSewerCharges(acnt As String, total As Double) As Double
        Dim Result As Double
    
        If acnt = "RES" Then
            Result = total * 1.028641 / 100.0
        ElseIf acnt = "SGO" Then
            Result = total * 8.162522 / 100.0
        ElseIf acnt = "BUS" Then
            Result = total * 22.446369 / 100.0
        ElseIf acnt = "UUO" Then
            Result = total * 10.262475 / 100.0
        ElseIf acnt = "WAT" Then
            Result = total * 22.628522 / 100.0
        Else REM if acnt="OTH)"
            Result = total * 10.626147 / 100.0
        End If
    
        Return Result
    End Function
    
    Private Function CalculateEnvironmentCharges(acnt As String, total As Double) As Double
        Dim result As Double
    
        Select Case acnt
            Case "RES"
                result = total * 0.004524
    
            Case "SGO"
                result = total * 0.118524
    
            Case "BUS"
                result = total * 0.086369
    
            Case "UUO"
                result = total * 0.166369
    
            Case "WAT"
                result = total * 0.115368
    
            Case Else
                result = total * 0.115248
    
        End Select
    
        Return result
    End Function
    
    Private Function CalculateServiceCharges(acnt As String, total As Double) As Double
        Select Case acnt
            Case "RES"
                Return total * 0.006248
    
            Case "SGO"
                Return total * 0.102246
    
            Case "BUS"
                Return total * 0.155227
    
            Case "UUO"
                Return total * 0.186692
    
            Case "WAT"
                Return total * 0.128724
    
            Case Else
                Return total * 0.210248
        End Select
    End Function
    
    Private Function CalculateLocalTaxes(acnt As String, total As Double) As Double
        Select Case acnt
            Case "RES"
                Return total * 0.035749
    
            Case "SGO"
                Return total * 0.044026
    
            Case "BUS"
                Return total * 0.162479
    
            Case "UUO"
                Return total * 0.105737
    
            Case "WAT"
                Return total * 0.063648
    
            Case Else
                Return total * 0.125148
        End Select
    End Function
    
    Private Function CalculateStateTaxes(acnt As String, total As Double) As Double
        Select Case acnt
            Case "RES"
                Return total * 0.007124
    
            Case "SGO"
                Return total * 0.008779
    
            Case "BUS"
                Return total * 0.035759
    
            Case "UUO"
                Return total * 0.067958
    
            Case "WAT"
                Return total * 0.026857
    
            Case Else
                Return total * 0.013746
        End Select
    End Function
    
    Private Function SetPaymentDueDate(acnt As String, Datum As Date) As Date
        Dim Days As Integer
    
        If acnt = "RES" Then
            Days = 15
        ElseIf acnt = "SGO" Then
            Days = 40
        ElseIf acnt = "BUS" Then
            Days = 30
        ElseIf acnt = "UUO" Then
            Days = 25
        ElseIf acnt = "WAT" Then
            Days = 45
        Else
            Days = 35
        End If
    
        Return DateAdd(DateInterval.Day, Days, Datum)
    End Function
    
    Private Function SetLatePaymentDueDate(acnt As String, Datum As Date) As Date
        Select Case acnt
            Case "RES"
                Return DateAdd(DateInterval.Day, 25, Datum)
    
            Case "SGO"
                Return DateAdd(DateInterval.Day, 40, Datum)
    
            Case "BUS"
                Return DateAdd(DateInterval.Day, 45, Datum)
    
            Case "UUO"
                Return DateAdd(DateInterval.Day, 30, Datum)
    
            Case "WAT"
                Return DateAdd(DateInterval.Day, 65, Datum)
    
            Case Else
                Return DateAdd(DateInterval.Day, 45, Datum)
        End Select
    End Function
    
    Private Function CalculateLateAmountDue(acnt As String, amt As Double) As Double
        Select Case acnt
            Case "RES"
                Return amt + 8.95
            Case "SGO"
                Return amt + (amt / 4.125)
            Case "BUS"
                Return amt + (amt / 12.315)
            Case "UUO"
                Return amt + (amt / 7.425)
            Case "WAT"
                Return amt + (amt / 12.225)
            Case Else
                Return amt + (amt / 6.735)
        End Select
    End Function
    
    Private Sub BtnEvaluateWaterBill_Click(sender As Object, e As EventArgs) Handles BtnEvaluateWaterBill.Click
        Dim CounterStart = 0
        Dim CounterEnd = 0
    
        Try
            CounterStart = CDbl(TxtCounterReadingStart.Text)
        Catch feCRStart As FormatException
            MsgBox("There was a problem with the value of the " +
                   "Counter Reading Start. The error produced is: " + feCRStart.Message,
                   MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                   "Stellar Water Point")
        End Try
    
        Try
            CounterEnd = CDbl(TxtCounterReadingEnd.Text)
        Catch feCREnd As FormatException
            MsgBox("There was a problem with the value of the " +
                   "Counter Reading End. The error produced is: " + feCREnd.Message,
                   MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                   "Stellar Water Point")
        End Try
    
        Dim Consumption = CounterEnd - CounterStart
        Dim Gallons = Consumption * 748.05
        Dim StrAccountType = Microsoft.VisualBasic.Left(TxtAccountType.Text, 3)
        Dim Tiers As (first As Double, second As Double, last As Double) = CalculateTiers(StrAccountType, Gallons)
    
        Dim waterCharges = Tiers.first + Tiers.second + Tiers.last
        Dim sewerCharges = CalculateSewerCharges(StrAccountType, waterCharges)
        Dim envCharges = CalculateEnvironmentCharges(StrAccountType, waterCharges)
        Dim srvCharges = CalculateServiceCharges(StrAccountType, waterCharges)
        Dim totalCharges = waterCharges + sewerCharges + envCharges + srvCharges
        Dim localTaxes = CalculateLocalTaxes(StrAccountType, totalCharges)
        Dim stateTaxes = CalculateStateTaxes(StrAccountType, totalCharges)
        Dim amtDue = totalCharges + localTaxes + stateTaxes
    
        TxtTotalHCF.Text = CStr(Consumption)
        TxtTotalGallons.Text = CInt(Gallons)
        TxtFirstTierConsumption.Text = FormatNumber(Tiers.first)
        TxtSecondTierConsumption.Text = FormatNumber(Tiers.second)
        TxtLastTierConsumption.Text = FormatNumber(Tiers.last)
        TxtWaterCharges.Text = FormatNumber(waterCharges)
        TxtSewerCharges.Text = FormatNumber(sewerCharges)
        TxtEnvironmentCharges.Text = FormatNumber(envCharges)
        TxtServiceCharges.Text = FormatNumber(srvCharges)
        TxtTotalCharges.Text = FormatNumber(totalCharges)
        TxtLocalTaxes.Text = FormatNumber(localTaxes)
        TxtStateTaxes.Text = FormatNumber(stateTaxes)
        dtpPaymentDueDate.Value = SetPaymentDueDate(StrAccountType, DtpMeterReadingEndDate.Value)
        TxtAmountDue.Text = amtDue.ToString("F")
        dtpLatePaymentDueDate.Value = SetLatePaymentDueDate(StrAccountType, DtpMeterReadingEndDate.Value)
        TxtLateAmountDue.Text = CalculateLateAmountDue(StrAccountType, amtDue).ToString("F")
    End Sub
  11. Return to the Water Bills - Create form and double-click the Save Water Bill button
  12. Return to the form and double-click the Close button
  13. Finalize the document as follows:
    Imports System.IO
    Imports System.Xml
    
    Public Class BillCreate
        Private Sub BtnFindCustomerAccount_Click(sender As Object, e As EventArgs) Handles BtnFindCustomerAccount.Click
            Dim xdCustomers As XmlDocument = New XmlDocument()
            Dim strCustomers = "C:\Stellar Water Point12\Customers.xml"
    
            Dim fiCustomers As FileInfo = New FileInfo(strCustomers)
    
            Dim strMeterNumber = String.Empty
    
            If fiCustomers.Exists Then
                Using fsCustomers As FileStream = New FileStream(fiCustomers.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    xdCustomers.Load(fsCustomers)
                    Dim xnlCustomers As XmlNodeList = xdCustomers.DocumentElement.SelectNodes("//account-number[.='" + MtbAccountNumber.Text + "']")
    
                    For Each xnCustomer As XmlNode In xnlCustomers
                        TxtAccountName.Text = xnCustomer.NextSibling.InnerText
                        strMeterNumber = xnCustomer.NextSibling.NextSibling.InnerText
                        TxtAccountType.Text = xnCustomer.NextSibling.NextSibling.NextSibling.InnerText
                        TxtAddress.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtCity.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtCounty.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtState.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtZIPCode.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                    Next
                End Using
            End If
    
            Dim xdWaterMeters As XmlDocument = New XmlDocument()
            Dim strWaterMeters As String = "C:\Stellar Water Point12\WaterMeters.xml"
    
            Dim fiWaterMeters As FileInfo = New FileInfo(strWaterMeters)
    
            If fiWaterMeters.Exists Then
                Using fsWaterMeters As FileStream = New FileStream(fiWaterMeters.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    xdWaterMeters.Load(fsWaterMeters)
                    Dim xnlWaterMeters As XmlNodeList = xdWaterMeters.DocumentElement.SelectNodes("//meter-number[.='" + strMeterNumber + "']")
    
                    For Each xnWaterMeter As XmlNode In xnlWaterMeters
                        TxtMeterDetails.Text = xnWaterMeter.NextSibling.InnerText + " " +
                                               xnWaterMeter.NextSibling.NextSibling.InnerText + " (Meter Size: " +
                                               xnWaterMeter.NextSibling.NextSibling.NextSibling.InnerText + ")"
                    Next
                End Using
            End If
        End Sub
    
        Private Sub DtpMeterReadingEndDate_ValueChanged(sender As Object, e As EventArgs) Handles DtpMeterReadingEndDate.ValueChanged
            TxtBillingDays.Text = DateDiff(DateInterval.Day, DtpMeterReadingStartDate.Value, DtpMeterReadingEndDate.Value) + 1
        End Sub
    
        Private Function CalculateTiers(acnt As String, total As Double) As (a As Double, b As Double, c As Double)
            Dim Results = (0.00, 0.00, 0.00)
    
            Select Case acnt
                Case "RES"
                    Results.Item1 = total * 38.35 / 10000.0
                    Results.Item2 = total * 18.25 / 10000.0
                    Results.Item3 = total * 11.65 / 10000.0
    
                Case "SGO"
                    Results.Item1 = total * 41.38 / 10000.0
                    Results.Item2 = total * 15.26 / 10000.0
                    Results.Item3 = total * 8.13 / 10000.0
    
                Case "BUS"
                    Results.Item1 = total * 51.25 / 10000.0
                    Results.Item2 = total * 34.65 / 10000.0
                    Results.Item3 = total * 14.1 / 10000.0
    
                Case "UUO"
                    Results.Item1 = total * 25 / 10000.0
                    Results.Item2 = total * 35 / 10000.0
                    Results.Item3 = total * 40 / 10000.0
    
                Case "WAT"
                    Results.Item1 = total * 48 / 10000.0
                    Results.Item2 = total * 32 / 10000.0
                    Results.Item3 = total * 20 / 10000.0
    
                Case Else
                    Results.Item1 = total * 25.0 / 10000.0
                    Results.Item2 = total * 35.0 / 10000.0
                    Results.Item3 = total * 40.0 / 10000.0
            End Select
    
            Return Results
        End Function
    
        Private Function CalculateSewerCharges(acnt As String, total As Double) As Double
            Dim Result As Double
    
            If acnt = "RES" Then
                Result = total * 1.028641 / 100.0
            ElseIf acnt = "SGO" Then
                Result = total * 8.162522 / 100.0
            ElseIf acnt = "BUS" Then
                Result = total * 22.446369 / 100.0
            ElseIf acnt = "UUO" Then
                Result = total * 10.262475 / 100.0
            ElseIf acnt = "WAT" Then
                Result = total * 22.628522 / 100.0
            Else REM if acnt="OTH)"
                Result = total * 10.626147 / 100.0
            End If
    
            Return Result
        End Function
    
        Private Function CalculateEnvironmentCharges(acnt As String, total As Double) As Double
            Dim result As Double
    
            Select Case acnt
                Case "RES"
                    result = total * 0.004524
    
                Case "SGO"
                    result = total * 0.118524
    
                Case "BUS"
                    result = total * 0.086369
    
                Case "UUO"
                    result = total * 0.166369
    
                Case "WAT"
                    result = total * 0.115368
    
                Case Else
                    result = total * 0.115248
    
            End Select
    
            Return result
        End Function
    
        Private Function CalculateServiceCharges(acnt As String, total As Double) As Double
            Select Case acnt
                Case "RES"
                    Return total * 0.006248
    
                Case "SGO"
                    Return total * 0.102246
    
                Case "BUS"
                    Return total * 0.155227
    
                Case "UUO"
                    Return total * 0.186692
    
                Case "WAT"
                    Return total * 0.128724
    
                Case Else
                    Return total * 0.210248
            End Select
        End Function
    
        Private Function CalculateLocalTaxes(acnt As String, total As Double) As Double
            Select Case acnt
                Case "RES"
                    Return total * 0.035749
    
                Case "SGO"
                    Return total * 0.044026
    
                Case "BUS"
                    Return total * 0.162479
    
                Case "UUO"
                    Return total * 0.105737
    
                Case "WAT"
                    Return total * 0.063648
    
                Case Else
                    Return total * 0.125148
            End Select
        End Function
    
        Private Function CalculateStateTaxes(acnt As String, total As Double) As Double
            Select Case acnt
                Case "RES"
                    Return total * 0.007124
    
                Case "SGO"
                    Return total * 0.008779
    
                Case "BUS"
                    Return total * 0.035759
    
                Case "UUO"
                    Return total * 0.067958
    
                Case "WAT"
                    Return total * 0.026857
    
                Case Else
                    Return total * 0.013746
            End Select
        End Function
    
        Private Function SetPaymentDueDate(acnt As String, Datum As Date) As Date
            Dim Days As Integer
    
            If acnt = "RES" Then
                Days = 15
            ElseIf acnt = "SGO" Then
                Days = 40
            ElseIf acnt = "BUS" Then
                Days = 30
            ElseIf acnt = "UUO" Then
                Days = 25
            ElseIf acnt = "WAT" Then
                Days = 45
            Else
                Days = 35
            End If
    
            Return DateAdd(DateInterval.Day, Days, Datum)
        End Function
    
        Private Function SetLatePaymentDueDate(acnt As String, Datum As Date) As Date
            Select Case acnt
                Case "RES"
                    Return DateAdd(DateInterval.Day, 25, Datum)
    
                Case "SGO"
                    Return DateAdd(DateInterval.Day, 40, Datum)
    
                Case "BUS"
                    Return DateAdd(DateInterval.Day, 45, Datum)
    
                Case "UUO"
                    Return DateAdd(DateInterval.Day, 30, Datum)
    
                Case "WAT"
                    Return DateAdd(DateInterval.Day, 65, Datum)
    
                Case Else
                    Return DateAdd(DateInterval.Day, 45, Datum)
            End Select
        End Function
    
        Private Function CalculateLateAmountDue(acnt As String, amt As Double) As Double
            Select Case acnt
                Case "RES"
                    Return amt + 8.95
                Case "SGO"
                    Return amt + (amt / 4.125)
                Case "BUS"
                    Return amt + (amt / 12.315)
                Case "UUO"
                    Return amt + (amt / 7.425)
                Case "WAT"
                    Return amt + (amt / 12.225)
                Case Else
                    Return amt + (amt / 6.735)
            End Select
        End Function
    
        Private Sub BtnEvaluateWaterBill_Click(sender As Object, e As EventArgs) Handles BtnEvaluateWaterBill.Click
            Dim CounterStart = 0
            Dim CounterEnd = 0
    
            Try
                CounterStart = CDbl(TxtCounterReadingStart.Text)
            Catch feCRStart As FormatException
                MsgBox("There was a problem with the value of the " +
                       "Counter Reading Start. The error produced is: " + feCRStart.Message,
                       MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                       "Stellar Water Point")
            End Try
    
            Try
                CounterEnd = CDbl(TxtCounterReadingEnd.Text)
            Catch feCREnd As FormatException
                MsgBox("There was a problem with the value of the " +
                       "Counter Reading End. The error produced is: " + feCREnd.Message,
                       MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                       "Stellar Water Point")
            End Try
    
            Dim Consumption = CounterEnd - CounterStart
            Dim Gallons = Consumption * 748.05
            Dim StrAccountType = Microsoft.VisualBasic.Left(TxtAccountType.Text, 3)
            Dim Tiers As (first As Double, second As Double, last As Double) = CalculateTiers(StrAccountType, Gallons)
    
            Dim waterCharges = Tiers.first + Tiers.second + Tiers.last
            Dim sewerCharges = CalculateSewerCharges(StrAccountType, waterCharges)
            Dim envCharges = CalculateEnvironmentCharges(StrAccountType, waterCharges)
            Dim srvCharges = CalculateServiceCharges(StrAccountType, waterCharges)
            Dim totalCharges = waterCharges + sewerCharges + envCharges + srvCharges
            Dim localTaxes = CalculateLocalTaxes(StrAccountType, totalCharges)
            Dim stateTaxes = CalculateStateTaxes(StrAccountType, totalCharges)
            Dim amtDue = totalCharges + localTaxes + stateTaxes
    
            TxtTotalHCF.Text = CStr(Consumption)
            TxtTotalGallons.Text = CInt(Gallons)
            TxtFirstTierConsumption.Text = FormatNumber(Tiers.first)
            TxtSecondTierConsumption.Text = FormatNumber(Tiers.second)
            TxtLastTierConsumption.Text = FormatNumber(Tiers.last)
            TxtWaterCharges.Text = FormatNumber(waterCharges)
            TxtSewerCharges.Text = FormatNumber(sewerCharges)
            TxtEnvironmentCharges.Text = FormatNumber(envCharges)
            TxtServiceCharges.Text = FormatNumber(srvCharges)
            TxtTotalCharges.Text = FormatNumber(totalCharges)
            TxtLocalTaxes.Text = FormatNumber(localTaxes)
            TxtStateTaxes.Text = FormatNumber(stateTaxes)
            dtpPaymentDueDate.Value = SetPaymentDueDate(StrAccountType, DtpMeterReadingEndDate.Value)
            TxtAmountDue.Text = amtDue.ToString("F")
            dtpLatePaymentDueDate.Value = SetLatePaymentDueDate(StrAccountType, DtpMeterReadingEndDate.Value)
            TxtLateAmountDue.Text = CalculateLateAmountDue(StrAccountType, amtDue).ToString("F")
        End Sub
    
        Private Sub BtnSaveWaterBill_Click(sender As Object, e As EventArgs) Handles BtnSaveWaterBill.Click
            If String.IsNullOrEmpty(TxtWaterBillNumber.Text) Then
                MsgBox("You must type a bill number." +
                       "Otherwise, the account cannot be saved.",
                       MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                       "Stellar Water Point")
                Exit Sub
            End If
    
            If String.IsNullOrEmpty(TxtCounterReadingStart.Text) Then
                MsgBox("You must enter the start value of the water bill counter." +
                       "Otherwise, the account cannot be saved.",
                       MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                       "Stellar Water Point")
                Exit Sub
            End If
    
            If String.IsNullOrEmpty(MtbAccountNumber.Text) Then
                MsgBox("You must type an account number of a customer." +
                       "Otherwise, the account cannot be saved.",
                       MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                       "Stellar Water Point")
                Exit Sub
            End If
    
            Dim xdWaterBills As XmlDocument = New XmlDocument()
            Dim strWaterBills = "C:\Stellar Water Point12\WaterBills.xml"
    
            Dim fiWaterBills = New FileInfo(strWaterBills)
    
            If fiWaterBills.Exists Then
                Using fsWaterBills = New FileStream(fiWaterBills.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    xdWaterBills.Load(fsWaterBills)
                End Using
            Else
                Using fsWaterBills = New FileStream(fiWaterBills.FullName, FileMode.Create, FileAccess.Write, FileShare.Write)
                    xdWaterBills.LoadXml("<?xml version=""1.0"" encoding=""utf-8""?>" +
                                             "<water-bills></water-bills>")
                    xdWaterBills.Save(fsWaterBills)
                End Using
            End If
    
            Using fsWaterBills = New FileStream(fiWaterBills.FullName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite)
                Dim xeWaterBill = xdWaterBills.CreateElement("water-bill")
    
                xeWaterBill.InnerXml = "<bill-number>" + TxtWaterBillNumber.Text + "</bill-number>" +
                                       "<account-number>" + MtbAccountNumber.Text + "</account-number>" +
                                       "<meter-reading-start-date>" + DtpMeterReadingStartDate.Value.ToShortDateString() + "</meter-reading-start-date>" +
                                       "<meter-reading-end-date>" + DtpMeterReadingEndDate.Value.ToShortDateString() + "</meter-reading-end-date>" +
                                       "<billing-days>" + TxtBillingDays.Text + "</billing-days>" +
                                       "<counter-reading-start>" + TxtCounterReadingStart.Text + "</counter-reading-start>" +
                                       "<counter-reading-end>" + TxtCounterReadingEnd.Text + "</counter-reading-end>" +
                                       "<total-hcf>" + TxtTotalHCF.Text + "</total-hcf>" +
                                       "<total-gallons>" + TxtTotalGallons.Text + "</total-gallons>" +
                                       "<first-tier-consumption>" + TxtFirstTierConsumption.Text + "</first-tier-consumption>" +
                                       "<second-tier-consumption>" + TxtSecondTierConsumption.Text + "</second-tier-consumption>" +
                                       "<last-tier-consumption>" + TxtLastTierConsumption.Text + "</last-tier-consumption>" +
                                       "<water-charges>" + TxtWaterCharges.Text + "</water-charges>" +
                                       "<sewer-charges>" + TxtSewerCharges.Text + "</sewer-charges>" +
                                       "<environment-charges>" + TxtEnvironmentCharges.Text + "</environment-charges>" +
                                       "<service-charges>" + TxtEnvironmentCharges.Text + "</service-charges>" +
                                       "<total-charges>" + TxtTotalCharges.Text + "</total-charges>" +
                                       "<state-taxes>" + TxtStateTaxes.Text + "</state-taxes>" +
                                       "<local-taxes>" + TxtLocalTaxes.Text + "</local-taxes>" +
                                       "<payment-due-date>" + DtpPaymentDueDate.Value.ToShortDateString() + "</payment-due-date>" +
                                       "<amount-due>" + TxtAmountDue.Text + "</amount-due>" +
                                       "<late-payment-due-date>" + DtpLatePaymentDueDate.Value.ToShortDateString() + "</late-payment-due-date>" +
                                       "<late-amount-due>" + TxtLateAmountDue.Text + "</late-amount-due>"
    
                xdWaterBills.DocumentElement.AppendChild(xeWaterBill)
                xdWaterBills.Save(fsWaterBills)
            End Using
    
            Close()
        End Sub
    
        Private Sub BtnClose_Click(sender As Object, e As EventArgs) Handles BtnClose.Click
            Close()
        End Sub
    End Class
  14. In the Solution Explorer, double-click ClientCentral.cs
  15. From the Toolbox, add a Button to the form
  16. In the Properties window, change the characteristics of the button as follows:

    Stellar Water Point - Create Water Bill

    Control (Name) Text Other Properties
    ListView List View LvwWaterBills   No Change
    Button Button BtnCreateWaterBill Close &Create Water Bill...
  17. Double-click the Create Water Bill button
  18. Implement the event as follows:
    Private Sub BtnCreateWaterBill_Click(sender As Object, e As EventArgs) Handles BtnCreateCustomerAccount.Click
        Dim Create As New BillCreate
    
        Create.ShowDialog()
    
        ShowWaterBills()
    End Sub
  19. To execute the application, on the main menu, click Debug -> Start Without Debugging:

    Stellar Water Point - New Customer Account

  20. On the Water Distribution form, click the Water Bills button:

    Stellar Water Point - Water Bills

  21. On the Water Bills form, click the Create Water Bill button:

    Stellar Water Point - Create Water Bill

  22. 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 - Customers

  23. Close the forms and return to your programming environment

Details on a Wate Bill

Probably the simplest operation that a user can perform on a water bill to only view its details. To make this happen, we will create and provide a form.

Practical LearningPractical Learning: Creating a Water Meter Record

  1. To create a form, in the Solution Explorer, right-click StellarWaterPoint -> Add -> Form (Windows Forms)...
  2. For the Name of the form, type BillDetails
  3. Press Enter
  4. To make the form design easy, make the ClientDetails form the same size as the ClientCreate. The copy everything from the BillCreate form and paste it in the BillDetails form
  5. Design the form as follows:

    Stellar Water Point - New Customer Account

    Control (Name) Text TextAlign Enabled
    Label Label   Water Bill #:    
    TextBox Text Box TxtBillNumber      
    Button Button BtnFindWaterBill Find Water Bill    
    GroupBox Label   Customer Information    
    Label Label   Account #:    
    TextBox Text Box TxtAccountNumber     False
    Label Label   Customer Name:    
    TextBox Text Box TxtCustomerName     False
    Label Label   Meter Details:    
    TextBox Text Box TxtMeterDetails     False
    Label Label   Address:    
    TextBox Text Box TxtAddress     False
    TextBox Text Box TxtCity     False
    TextBox Text Box TxtCounty     False
    TextBox Text Box TxtState     False
    TextBox Text Box TxtZIPCode     False
    GroupBox Label   Meter Reading    
    Label Label   Meter Reading Start Date:    
    TextBox Text Box TxtMeterReadingStartDate     False
    Label Label   Meter Reading End Date:    
    TextBox Text Box TxtMeterReadingEndDate     False
    Label Label   Counter Reading Start:    
    TextBox Text Box TxtCounterReadingStart     False
    Label Label   Counter Reading End:    
    TextBox Text Box TxtCounterReadingEnd     False
    GroupBox Label   Meter Result    
    Label Label   Billing Days:    
    TextBox Text Box TxtBillingDays   Right False
    Label Label   Total Gallons:    
    TextBox Text Box TxtTotalGallons   Right False
    Label Label   Total HCF:    
    TextBox Text Box TxtTotalHCF   Right False
    Label Label   First Tier Consumption:    
    TextBox Text Box TxtFirstTierConsumption   Right False
    Label Label   Second Tier:    
    TextBox Text Box TxtSecondTierConsumption   Right False
    Label Label   Last Tier:    
    TextBox Text Box TxtLastTierConsumption   Right False
    GroupBox Label   Consumption Charges    
    Label Label   Water Charges:    
    TextBox Text Box TxtWaterCharges   TextAlign: Right Enabled: False
    Label Label   Sewer Charges:    
    TextBox Text Box TxtSewerCharges   TextAlign: Right Enabled: False
    Label Label   Environment Charges:    
    TextBox Text Box TxtEnvironmentCharges   Right False
    Label Label   Total Charges:    
    TextBox Text Box TxtTotalCharges   Right False
    GroupBox Label   Taxes    
    Label Label   Local Taxes:    
    TextBox Text Box TxtLocalTaxes   TextAlign: Right Enabled: False
    Label Label   State Taxes:    
    TextBox Text Box TxtStateTaxes   Right False
    GroupBox Label   Water Bill Payment    
    Label Label   Payment Due Date:    
    TextBox Text Box TxtPaymentDueDate   False  
    Label Label   Amount Due:    
    TextBox Text Box TxtAmountDue   Right False
    Label Label   Late Payment Due Date:    
    TextBox Text Box TxtLatePaymentDueDate   False  
    Label Label   Late Amount Due:    
    TextBox Text Box TxtLateAmountDue   Right False
    Button Button BtnClose Close    
  6. Using the Properties window, change some characteristics of the form as follows:
    FormBorderStyle: FixedDialog
    Text:            Stellar Water Point - Water Bill Details
    StartPosition:   CenterScreen
    MinimizeBox:     False
    MaximizeBox:     False
  7. On the form, double-click the Find Water Bill button
  8. Return to the form and double-click the Close button
  9. Change the document as follows:
    Imports System.IO
    Imports System.Xml
    
    Public Class BillDetails
        Private Sub BtnFindWaterBill_Click(sender As Object, e As EventArgs) Handles BtnFindWaterBill.Click
            ' If the user clicks the Find Water Meter button, 
            ' make sure there Is an invoice number in the top text box.
            If String.IsNullOrEmpty(TxtWaterBillNumber.Text) Then
                MsgBox("You must provide a water bill number and then click the Find Water Bill button.",
                       MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                       "Stellar Water Point")
                ' If the user didn't type a bill number but clicked Find Water Bill, don't do anything
                Exit Sub
            End If
    
            Dim xdWaterBills = New XmlDocument()
            Dim strWaterBills = "C:\Stellar Water Point12\WaterBills.xml"
    
            Dim fiWaterBills = New FileInfo(strWaterBills)
    
            If fiWaterBills.Exists Then
                Using fsWaterBills = New FileStream(fiWaterBills.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    xdWaterBills.Load(fsWaterBills)
    
                    ' Use XPath to locate the water bill that has 
                    ' the same invoice number as the one in the Water Bill Number text box.
                    ' Store the water bill in an XmlNodeList variable.
                    Dim xnlWaterBills = xdWaterBills.DocumentElement.SelectNodes("//bill-number[.='" + TxtWaterBillNumber.Text + "']")
    
                    For Each xnWaterBill As XmlNode In xnlWaterBills
                        TxtWaterBillNumber.Text = xnWaterBill.FirstChild.InnerText
                        TxtAccountNumber.Text = xnWaterBill.NextSibling.InnerText
                        TxtMeterReadingStartDate.Text = CDate(xnWaterBill.NextSibling.NextSibling.InnerText).ToLongDateString()
                        TxtMeterReadingEndDate.Text = CDate(xnWaterBill.NextSibling.NextSibling.NextSibling.InnerText).ToLongDateString()
                        TxtBillingDays.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtCounterReadingStart.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtCounterReadingEnd.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtTotalHCF.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtTotalGallons.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtFirstTierConsumption.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtSecondTierConsumption.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtLastTierConsumption.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtWaterCharges.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtSewerCharges.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtEnvironmentCharges.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtServiceCharges.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtTotalCharges.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtStateTaxes.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtLocalTaxes.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtPaymentDueDate.Text = CDate(xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText).ToLongDateString()
                        TxtAmountDue.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtLatePaymentDueDate.Text = CDate(xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText).ToLongDateString()
                        TxtLateAmountDue.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                    Next
                End Using
            End If
    
            Dim xdCustomers As XmlDocument = New XmlDocument()
            ' Declare a variable for a file that holds the list of customers
            Dim strCustomers = "C:\Stellar Water Point12\Customers.xml"
    
            ' Create a FileInfo object for the customers
            Dim fiCustomers As FileInfo = New FileInfo(strCustomers)
    
            ' We will need to know the water meter associated with this customer account
            Dim strMeterNumber = Nothing
    
            ' Check whether the file that holds a list of customers exists
            If fiCustomers.Exists Then
                ' If that exists, open it and pass it to a FileStream object
                Using fsCustomers As FileStream = New FileStream(fiCustomers.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    ' Get the list of customers and pass the records to the XML DOM object created earlier
                    xdCustomers.Load(fsCustomers)
                    REM Create an XmlNodeList list of customers using XPath
                    Dim xnlCustomers As XmlNodeList = xdCustomers.DocumentElement.SelectNodes("//account-number[.='" + TxtAccountNumber.Text + "']")
    
                    REM Check each node of the XML record and display its values in each Windows control on the form
                    For Each xnCustomer As XmlNode In xnlCustomers
                        ' MtbAccountNumber.Text = xnCustomer.NextSibling.InnerText   rem Meter #
                        TxtAccountName.Text = xnCustomer.NextSibling.InnerText REM Account Name
    
                        strMeterNumber = xnCustomer.NextSibling.NextSibling.InnerText   REM Meter Number
                        TxtAccountType.Text = xnCustomer.NextSibling.NextSibling.NextSibling.InnerText   REM Account Type
                        TxtAddress.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.InnerText   REM Address
                        TxtCity.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText   REM City
                        TxtCounty.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText   REM County
                        TxtState.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText   REM State
                        TxtZIPCode.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText REM ZIP-Code
                    Next
                End Using
            End If
    
            ' Create an XML DOM object for the water meters records
            Dim xdWaterMeters As XmlDocument = New XmlDocument()
            ' Declare a variable for a file that holds the list of water meters
            Dim strWaterMeters As String = "C:\Stellar Water Point12\WaterMeters.xml"
    
            ' Create a FileInfo object for the customers
            Dim fiWaterMeters As FileInfo = New FileInfo(strWaterMeters)
    
            ' Check whether the file that holds a list of water meters exists
            If fiWaterMeters.Exists Then
                ' Get the list of water meters and pass the records to the XML DOM object
                Using fsWaterMeters As FileStream = New FileStream(fiWaterMeters.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    ' Get the list of water meters and pass the records to the XML DOM object
                    xdWaterMeters.Load(fsWaterMeters)
                    ' Create an XmlNodeList list of water meters using XPath
                    Dim xnlWaterMeters As XmlNodeList = xdWaterMeters.DocumentElement.SelectNodes("//meter-number[.='" + strMeterNumber + "']")
    
                    ' Check each node of the XML record
                    For Each xnWaterMeter As XmlNode In xnlWaterMeters
                        ' Get the values for the water meter.
                        ' Create a sentence And display it in the Meter Details text box.
                        TxtMeterDetails.Text = xnWaterMeter.NextSibling.InnerText + " " +
                                               xnWaterMeter.NextSibling.NextSibling.InnerText + " (Meter Size: " +
                                               xnWaterMeter.NextSibling.NextSibling.NextSibling.InnerText + ")"
                    Next
                End Using
            End If
        End Sub
    
        Private Sub BtnClose_Click(sender As Object, e As EventArgs) Handles BtnClose.Click
            Close()
        End Sub
    End Class
  10. In the Solution Explorer, below the WaterBills folder, double-click Details.cs to open its form
  11. From the Toolbox, add a button to the form below the list view and to the right of the Create Water Bill button
  12. Change the characteristics of the button as follows:

    Stellar Water Point - Water Bills

    Control (Name) Text
    Button Button BtnViewWaterBill &View Water Bill...
  13. Double-click the View Water Bill button
  14. Change the document as follows:
    Private Sub BtnViewWaterBill_Click(sender As Object, e As EventArgs) Handles BtnViewCustomerDetails.Click
        Dim Details As New BillDetails
    
        Details.Show()
    End Sub
  15. To execute the application, on the main menu, click Debug -> Start Without Debugging

    Stellar Water Point

  16. On the Water Distribution form, click the Water Bills button:

    Stellar Water Point - Water Bills

  17. On the Water Bills form, click the View Water Bill button:

    Stellar Water Point - View Water Bill

  18. In the Water Bill # text box, type 917829
  19. Click the Find Water Bill button:

    Stellar Water Point - View Water Bill

  20. Close the Details form
  21. Close the forms and return to your programming environment

Water Bill Edition

Although it doesn't happen regularly, some information can change about an existing water bill. If that happens, the user must be able to update the water bill. For this reason, we will create and provide a form that supports that operation.

Practical LearningPractical Learning: Editing a Water Bill

  1. To create a new form, in the Solution Explorer, right-click StellarWaterPoint -> New -> Form (Windows Forms)...
  2. Type BillEditor as the name of the form
  3. Click Add
  4. Make that form the same size as the Create Water Bill form
  5. Select everything on the Create Water Bill form. Copy that selection and paste it in the new Water Bill Editor form
  6. Copy the Find Water Bill button from the Water Bill Details form and paste it on the Water Bill Editor form
  7. Complete the design of the form as follows:

    Stellar Water Point - Water Bill Editor

    Control (Name) Text TextAlign Modifiers Other Properties
    Label Label   Water Bill #:      
    TextBox Text Box TxtBillNumber     Public  
    Button Button BtnFindWaterBill &Find Water Bill      
    GroupBox Label   Customer Information      
    Label Label   Account #:      
    MaskedTextBox Masked Text Box MtbAccountNumber     Public Masked: 0000-000-0000
    Button Button BtnFindCustomerAccount Find Customer Account      
    Label Label   Account Name:      
    TextBox Text Box TxtAccountName       Enabled: False
    Label Label   Address:      
    TextBox Text Box TxtAddress       Enabled: False
    TextBox Text Box TxtCity       Enabled: False
    TextBox Text Box TxtCounty       Enabled: False
    TextBox Text Box TxtState       Enabled: False
    TextBox Text Box MtbZIPCode       Enabled: False
    Label Label   Meter Details:      
    TextBox Text Box TxtMeterDetails     Public  
    GroupBox Label   Meter Reading      
    Label Label   Meter Reading Start Date:      
    DateTimePicker Date Time Picker DtpMeterReadingStartDate     Public  
    Label Label   Meter Reading End Date:      
    DateTimePicker Date Time Picker DtpMeterReadingEndDate     Public  
    Label Label   Counter Reading Start:      
    TextBox Text Box TxtCounterReadingStart       Public  
    Label Label   Counter Reading End:      
    TextBox Text Box TxtCounterReadingEnd     Public  
    Button Button BtnEvaluateWaterBill Evaluate Water Bill      
    GroupBox Label   Meter Result      
    Label Label   Billing Days:      
    TextBox Text Box TxtBillingDays   Right    
    Label Label   Total Gallons:      
    TextBox Text Box TxtTotalGallons   Right    
    Label Label   Total CCF:      
    TextBox Text Box TxtTotalCCF     Right  
    Label Label   First Tier Consumption:      
    TextBox Text Box TxtFirstTierConsumption   Right Public  
    Label Label   Second Tier:    
    TextBox Text Box TxtSecondTierConsumption   Right Public  
    Label Label   Last Tier:      
    TextBox Text Box TxtLastTierConsumption   Right Public  
    GroupBox Label   Consumption Charges      
    Label Label   Water Charges:      
    TextBox Text Box TxtWaterCharges   Right Public  
    Label Label   Sewer Charges:      
    TextBox Text Box TxtSewerCharges   Right Public  
    Label Label   Environment Charges:      
    TextBox Text Box TxtEnvironmentCharges   Right Public  
    Label Label   Total Charges:      
    TextBox Text Box TxtTotalCharges   Right Public  
    GroupBox Label   Taxes      
    Label Label   Local Taxes:      
    TextBox Text Box TxtLocalTaxes   Right Public  
    Label Label   State Taxes:      
    TextBox Text Box TxtStateTaxes   Right Public  
    GroupBox Label   Water Bill Payment      
    Label Label   Payment Due Date:      
    DateTimePicker Date Time Picker DtpPaymentDueDate     Public  
    Label Label   Amount Due:      
    TextBox Text Box TxtAmountDue   Right Public  
    Label Label   Late Payment Due Date:    
    DateTimePicker Date Time Picker DtpLatePaymentDueDate     Public  
    Label Label   Late Amount Due:      
    TextBox Text Box TxtLateAmountDue   Right Public  
    Button Button BtnUpdateWaterBill Update Water Bill     DialogResult: OK
    Button Button BtnClose Close     DialogResult: Cancel
  8. Using the Properties window, change some characteristics of the form as follows:
    FormBorderStyle: FixedDialog
    Text:            Stellar Water Point - Water Bill Editor
    StartPosition:   CenterScreen
    MinimizeBox:     False
    MaximizeBox:     False
    AcceptButton:    BtnUpdateWaterBill
    CancelButton:    BtnClose
  9. On the form, double-click the Find Water Bill button
  10. Change the document as follows:
    Imports System.IO
    Imports System.Xml
    
    Public Class BillEditor
        Private Sub BtnFindWaterBill_Click(sender As Object, e As EventArgs) Handles BtnFindWaterBill.Click
            If String.IsNullOrEmpty(TxtWaterBillNumber.Text) Then
                MsgBox("You must provide a water bill number and then click the Find Water Bill button.",
                       MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                       "Stellar Water Point")
                Exit Sub
            End If
    
            Dim xdWaterBills As New XmlDocument()
            Dim strWaterBills = "C:\Stellar Water Point12\WaterBills.xml"
    
            Dim fiWaterBills As New FileInfo(strWaterBills)
    
            If fiWaterBills.Exists Then
                Using fsWaterBills As New FileStream(fiWaterBills.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    xdWaterBills.Load(fsWaterBills)
    
                    Dim xnlWaterBills = xdWaterBills.DocumentElement.SelectNodes("//bill-number[.='" + TxtWaterBillNumber.Text + "']")
    
                    For Each xnWaterBill As XmlNode In xnlWaterBills
                        TxtWaterBillNumber.Text = xnWaterBill.FirstChild.InnerText
                        MtbAccountNumber.Text = xnWaterBill.NextSibling.InnerText
                        DtpMeterReadingStartDate.Text = CDate(xnWaterBill.NextSibling.NextSibling.InnerText).ToLongDateString()
                        DtpMeterReadingEndDate.Text = CDate(xnWaterBill.NextSibling.NextSibling.NextSibling.InnerText).ToLongDateString()
                        TxtBillingDays.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtCounterReadingStart.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtCounterReadingEnd.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtTotalHCF.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtTotalGallons.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtFirstTierConsumption.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtSecondTierConsumption.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtLastTierConsumption.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtWaterCharges.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtSewerCharges.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtEnvironmentCharges.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtServiceCharges.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtTotalCharges.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtStateTaxes.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtLocalTaxes.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        DtpPaymentDueDate.Text = DateTime.Parse(xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText).ToLongDateString()
                        TxtAmountDue.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        DtpLatePaymentDueDate.Text = DateTime.Parse(xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText).ToLongDateString()
                        TxtLateAmountDue.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                    Next
                End Using
            End If
    
            Dim xdCustomers As XmlDocument = New XmlDocument()
                    Dim strCustomers = "C:\Stellar Water Point12\Customers.xml"
    
                    Dim fiCustomers As FileInfo = New FileInfo(strCustomers)
    
            Dim strMeterNumber = Nothing
    
            If fiCustomers.Exists Then
                Using fsCustomers As FileStream = New FileStream(fiCustomers.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    xdCustomers.Load(fsCustomers)
                    Dim xnlCustomers As XmlNodeList = xdCustomers.DocumentElement.SelectNodes("//account-number[.='" + MtbAccountNumber.Text + "']")
    
                    For Each xnCustomer As XmlNode In xnlCustomers
                        TxtAccountName.Text = xnCustomer.NextSibling.InnerText ' Account Name
    
                        strMeterNumber = xnCustomer.NextSibling.NextSibling.InnerText ' Meter Number
                        TxtAccountType.Text = xnCustomer.NextSibling.NextSibling.NextSibling.InnerText ' Account Type
                        TxtAddress.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.InnerText ' Address
                        TxtCity.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText ' City
                        TxtCounty.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText ' County
                        TxtState.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText   ' State
                        TxtZIPCode.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText ' ZIP-Code
                    Next
                End Using
            End If
    
            Dim xdWaterMeters As XmlDocument = New XmlDocument()
            Dim strWaterMeters As String = "C:\Stellar Water Point12\WaterMeters.xml"
    
            Dim fiWaterMeters As FileInfo = New FileInfo(strWaterMeters)
    
            If fiWaterMeters.Exists Then
                Using fsWaterMeters As FileStream = New FileStream(fiWaterMeters.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    xdWaterMeters.Load(fsWaterMeters)
                    Dim xnlWaterMeters As XmlNodeList = xdWaterMeters.DocumentElement.SelectNodes("//meter-number[.='" + strMeterNumber + "']")
    
                    ' Check each node of the XML record
                    For Each xnWaterMeter As XmlNode In xnlWaterMeters
                        TxtMeterDetails.Text = xnWaterMeter.NextSibling.InnerText + " " +
                                               xnWaterMeter.NextSibling.NextSibling.InnerText + " (Meter Size: " +
                                               xnWaterMeter.NextSibling.NextSibling.NextSibling.InnerText + ")"
                    Next
                End Using
            End If
        End Sub
    End Class
  11. Return to the Water Bill - Editor form and double-click the Find Customer Account button
  12. Implement the event as follows:
    Private Sub BtnFindCustomerAccount_Click(sender As Object, e As EventArgs) Handles BtnFindCustomerAccount.Click
        Dim xdCustomers As XmlDocument = New XmlDocument()
        Dim strCustomers = "C:\Stellar Water Point12\Customers.xml"
    
        Dim fiCustomers As FileInfo = New FileInfo(strCustomers)
    
        Dim strMeterNumber = Nothing
    
        If fiCustomers.Exists Then
            Using fsCustomers As FileStream = New FileStream(fiCustomers.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                xdCustomers.Load(fsCustomers)
                Dim xnlCustomers As XmlNodeList = xdCustomers.DocumentElement.SelectNodes("//account-number[.='" + MtbAccountNumber.Text + "']")
    
                For Each xnCustomer As XmlNode In xnlCustomers
                    TxtAccountName.Text = xnCustomer.NextSibling.InnerText
                    strMeterNumber = xnCustomer.NextSibling.NextSibling.InnerText
                    TxtAccountType.Text = xnCustomer.NextSibling.NextSibling.NextSibling.InnerText
                    TxtAddress.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                    TxtCity.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                    TxtCounty.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                    TxtState.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                    TxtZIPCode.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                Next
            End Using
        End If
    
        Dim xdWaterMeters As XmlDocument = New XmlDocument()
        Dim strWaterMeters As String = "C:\Stellar Water Point12\WaterMeters.xml"
    
        Dim fiWaterMeters As FileInfo = New FileInfo(strWaterMeters)
    
        If fiWaterMeters.Exists Then
            Using fsWaterMeters As FileStream = New FileStream(fiWaterMeters.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                xdWaterMeters.Load(fsWaterMeters)
                Dim xnlWaterMeters As XmlNodeList = xdWaterMeters.DocumentElement.SelectNodes("//meter-number[.='" + strMeterNumber + "']")
    
                For Each xnWaterMeter As XmlNode In xnlWaterMeters
                    TxtMeterDetails.Text = xnWaterMeter.NextSibling.InnerText + " " +
                                               xnWaterMeter.NextSibling.NextSibling.InnerText + " (Meter Size: " +
                                               xnWaterMeter.NextSibling.NextSibling.NextSibling.InnerText + ")"
                Next
            End Using
            End If
    End Sub
  13. Return to the Water Bill - Editor form and double-click the Meter Reading End Date date time picker
  14. Implement the event as follows:
    Private Sub DtpMeterReadingEndDate_ValueChanged(sender As Object, e As EventArgs) Handles DtpMeterReadingEndDate.ValueChanged
        TxtBillingDays.Text = DateDiff("d", DtpMeterReadingStartDate.Value, DtpMeterReadingEndDate.Value) + 1
    End Sub
  15. Return to the Water Bill - Editor form and double-click the Re-Evaluate Water Bill button
  16. Implement the event as follows:
    Private Function CalculateTiers(acnt As String, total As Double) As (a As Double, b As Double, c As Double)
        Dim Results = (0.00, 0.00, 0.00)
    
        Select Case acnt
            Case "RES"
                Results.Item1 = total * 38.35 / 10000.0
                Results.Item2 = total * 18.25 / 10000.0
                Results.Item3 = total * 11.65 / 10000.0
    
            Case "SGO"
                Results.Item1 = total * 41.38 / 10000.0
                Results.Item2 = total * 15.26 / 10000.0
                Results.Item3 = total * 8.13 / 10000.0
    
            Case "BUS"
                Results.Item1 = total * 51.25 / 10000.0
                Results.Item2 = total * 34.65 / 10000.0
                Results.Item3 = total * 14.1 / 10000.0
    
            Case "UUO"
                Results.Item1 = total * 25 / 10000.0
                Results.Item2 = total * 35 / 10000.0
                Results.Item3 = total * 40 / 10000.0
    
            Case "WAT"
                Results.Item1 = total * 48 / 10000.0
                Results.Item2 = total * 32 / 10000.0
                Results.Item3 = total * 20 / 10000.0
    
            Case Else
                Results.Item1 = total * 25.0 / 10000.0
                Results.Item2 = total * 35.0 / 10000.0
                Results.Item3 = total * 40.0 / 10000.0
        End Select
    
        Return Results
    End Function
    
    Private Function CalculateSewerCharges(acnt As String, total As Double) As Double
        Dim Result As Double
    
        If acnt = "RES" Then
            Result = total * 1.028641 / 100.0
        ElseIf acnt = "SGO" Then
            Result = total * 8.162522 / 100.0
        ElseIf acnt = "BUS" Then
            Result = total * 22.446369 / 100.0
        ElseIf acnt = "UUO" Then
            Result = total * 10.262475 / 100.0
        ElseIf acnt = "WAT" Then
            Result = total * 22.628522 / 100.0
        Else REM if acnt="OTH)"
            Result = total * 10.626147 / 100.0
        End If
    
        Return Result
    End Function
    
    Private Function CalculateEnvironmentCharges(acnt As String, total As Double) As Double
        Dim result As Double
    
        Select Case acnt
            Case "RES"
                result = total * 0.004524
    
            Case "SGO"
                result = total * 0.118524
    
            Case "BUS"
                result = total * 0.086369
    
            Case "UUO"
                result = total * 0.166369
    
            Case "WAT"
                result = total * 0.115368
    
            Case Else
                result = total * 0.115248
    
        End Select
    
        Return result
    End Function
    
    Private Function CalculateServiceCharges(acnt As String, total As Double) As Double
        Select Case acnt
            Case "RES"
                Return total * 0.006248
    
            Case "SGO"
                Return total * 0.102246
    
            Case "BUS"
                Return total * 0.155227
    
            Case "UUO"
                Return total * 0.186692
    
            Case "WAT"
                Return total * 0.128724
    
            Case Else
                Return total * 0.210248
        End Select
    End Function
    
    Private Function CalculateLocalTaxes(acnt As String, total As Double) As Double
        Select Case acnt
            Case "RES"
                Return total * 0.035749
    
            Case "SGO"
                Return total * 0.044026
    
            Case "BUS"
                Return total * 0.162479
    
            Case "UUO"
                Return total * 0.105737
    
            Case "WAT"
                Return total * 0.063648
    
            Case Else
                Return total * 0.125148
        End Select
    End Function
    
    Private Function CalculateStateTaxes(acnt As String, total As Double) As Double
        Select Case acnt
            Case "RES"
                Return total * 0.007124
    
            Case "SGO"
                Return total * 0.008779
    
            Case "BUS"
                Return total * 0.035759
    
            Case "UUO"
                Return total * 0.067958
    
            Case "WAT"
                Return total * 0.026857
    
            Case Else
                Return total * 0.013746
        End Select
    End Function
    
    Private Function SetPaymentDueDate(acnt As String, Datum As Date) As Date
        Dim Days As Integer
    
        If acnt = "RES" Then
            Days = 15
        ElseIf acnt = "SGO" Then
            Days = 40
        ElseIf acnt = "BUS" Then
            Days = 30
        ElseIf acnt = "UUO" Then
            Days = 25
        ElseIf acnt = "WAT" Then
            Days = 45
        Else
            Days = 35
        End If
    
        Return DateAdd(DateInterval.Day, Days, Datum)
    End Function
    
    Private Function SetLatePaymentDueDate(acnt As String, Datum As Date) As Date
        Select Case acnt
            Case "RES"
                Return DateAdd(DateInterval.Day, 25, Datum)
    
            Case "SGO"
                Return DateAdd(DateInterval.Day, 40, Datum)
    
            Case "BUS"
                Return DateAdd(DateInterval.Day, 45, Datum)
    
            Case "UUO"
                Return DateAdd(DateInterval.Day, 30, Datum)
    
            Case "WAT"
                Return DateAdd(DateInterval.Day, 65, Datum)
    
            Case Else
                Return DateAdd(DateInterval.Day, 45, Datum)
        End Select
    End Function
    
    Private Function CalculateLateAmountDue(acnt As String, amt As Double) As Double
        Select Case acnt
            Case "RES"
                Return amt + 8.95
            Case "SGO"
                Return amt + (amt / 4.125)
            Case "BUS"
                Return amt + (amt / 12.315)
            Case "UUO"
                Return amt + (amt / 7.425)
            Case "WAT"
                Return amt + (amt / 12.225)
            Case Else
                Return amt + (amt / 6.735)
        End Select
    End Function
    
    Private Sub BtnEvaluateWaterBill_Click(sender As Object, e As EventArgs) Handles BtnEvaluateWaterBill.Click
        Dim CounterStart = 0
        Dim CounterEnd = 0
    
        Try
            CounterStart = CDbl(TxtCounterReadingStart.Text)
        Catch feCRStart As FormatException
            MsgBox("There was a problem with the value of the " +
                   "Counter Reading Start. The error produced is: " + feCRStart.Message,
                   MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                   "Stellar Water Point")
        End Try
    
        Try
            CounterEnd = CDbl(TxtCounterReadingEnd.Text)
        Catch feCREnd As FormatException
            MsgBox("There was a problem with the value of the " +
                   "Counter Reading End. The error produced is: " + feCREnd.Message,
                   MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                   "Stellar Water Point")
        End Try
    
        Dim Consumption = CounterEnd - CounterStart
        Dim Gallons = Consumption * 748.05
        Dim StrAccountType = Microsoft.VisualBasic.Left(TxtAccountType.Text, 3)
        Dim Tiers As (first As Double, second As Double, last As Double) = CalculateTiers(StrAccountType, Gallons)
    
        Dim waterCharges = Tiers.first + Tiers.second + Tiers.last
        Dim sewerCharges = CalculateSewerCharges(StrAccountType, waterCharges)
        Dim envCharges = CalculateEnvironmentCharges(StrAccountType, waterCharges)
        Dim srvCharges = CalculateServiceCharges(StrAccountType, waterCharges)
        Dim totalCharges = waterCharges + sewerCharges + envCharges + srvCharges
        Dim localTaxes = CalculateLocalTaxes(StrAccountType, totalCharges)
        Dim stateTaxes = CalculateStateTaxes(StrAccountType, totalCharges)
        Dim amtDue = totalCharges + localTaxes + stateTaxes
    
        TxtTotalHCF.Text = CStr(Consumption)
        TxtTotalGallons.Text = CInt(Gallons)
        TxtFirstTierConsumption.Text = FormatNumber(Tiers.first)
        TxtSecondTierConsumption.Text = FormatNumber(Tiers.second)
        TxtLastTierConsumption.Text = FormatNumber(Tiers.last)
        TxtWaterCharges.Text = FormatNumber(waterCharges)
        TxtSewerCharges.Text = FormatNumber(sewerCharges)
        TxtEnvironmentCharges.Text = FormatNumber(envCharges)
        TxtServiceCharges.Text = FormatNumber(srvCharges)
        TxtTotalCharges.Text = FormatNumber(totalCharges)
        TxtLocalTaxes.Text = FormatNumber(localTaxes)
        TxtStateTaxes.Text = FormatNumber(stateTaxes)
        DtpPaymentDueDate.Value = SetPaymentDueDate(StrAccountType, DtpMeterReadingEndDate.Value)
        TxtAmountDue.Text = amtDue.ToString("F")
        DtpLatePaymentDueDate.Value = SetLatePaymentDueDate(StrAccountType, DtpMeterReadingEndDate.Value)
        TxtLateAmountDue.Text = CalculateLateAmountDue(StrAccountType, amtDue).ToString("F")
    End Sub
  17. In the Solution Explorer, below the WaterBills folder, double-click Central.cs
  18. From the Toolbox, add a button to the form below the list view and on the right side of the View Water Bill button
  19. Change the characteristics of the button as follows:

    Stellar Water Point - Water Bills

    Control (Name) Text
    ListView List View LvwWaterBills  
    Button Button BtnNewWaterBill  
    Button Button BtnViewWaterBill  
    Button Button BtnEditWaterBill &Edit Water Bill...
  20. Double-click the Edit Water Bill button
  21. Implement the event as follows:
    Private Sub BtnEditWaterBill_Click(sender As Object, e As EventArgs) Handles BtnEditWaterBill.Click
        Dim Editor As New BillEditor
    
        If Editor.ShowDialog() = DialogResult.OK Then
            If String.IsNullOrEmpty(Editor.TxtWaterBillNumber.Text) Then
                MsgBox("You must first type a bill number and then click the Find Water Bill button. " +
                       "You can then optionally change some values on the water bill and save it.",
                       MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                       "Stellar Water Point")
                Exit Sub
            End If
    
            Dim xdWaterBills = New XmlDocument()
            Dim strWaterBills = "C:\Stellar Water Point12\WaterBills.xml"
    
            xdWaterBills.Load(strWaterBills)
    
            Dim xnlWaterBills As XmlNodeList = xdWaterBills.DocumentElement.GetElementsByTagName("bill-number")
    
            For Each xnWaterBill As XmlNode In xnlWaterBills
                If xnWaterBill.InnerText.Contains(Editor.TxtWaterBillNumber.Text) Then
                    xnWaterBill.ParentNode.InnerXml =
                            "<bill-number>" + Editor.TxtWaterBillNumber.Text + "</bill-number>" +
                            "<account-number>" + Editor.MtbAccountNumber.Text + "</account-number>" +
                            "<meter-reading-start-date>" + Editor.DtpMeterReadingStartDate.Value.ToShortDateString() + "</meter-reading-start-date>" +
                            "<meter-reading-end-date>" + Editor.DtpMeterReadingEndDate.Value.ToShortDateString() + "</meter-reading-end-date>" +
                            "<billing-days>" + Editor.TxtBillingDays.Text + "</billing-days>" +
                            "<counter-reading-start>" + Editor.TxtCounterReadingStart.Text + "</counter-reading-start>" +
                            "<counter-reading-end>" + Editor.TxtCounterReadingEnd.Text + "</counter-reading-end>" +
                            "<total-hcf>" + Editor.TxtTotalHCF.Text + "</total-hcf>" +
                            "<total-gallons>" + Editor.TxtTotalGallons.Text + "</total-gallons>" +
                            "<first-tier-consumption>" + Editor.TxtFirstTierConsumption.Text + "</first-tier-consumption>" +
                            "<second-tier-consumption>" + Editor.TxtSecondTierConsumption.Text + "</second-tier-consumption>" +
                            "<last-tier-consumption>" + Editor.TxtLastTierConsumption.Text + "</last-tier-consumption>" +
                            "<water-charges>" + Editor.TxtWaterCharges.Text + "</water-charges>" +
                            "<sewer-charges>" + Editor.TxtSewerCharges.Text + "</sewer-charges>" +
                            "<environment-charges>" + Editor.TxtEnvironmentCharges.Text + "</environment-charges>" +
                            "<service-charges>" + Editor.TxtEnvironmentCharges.Text + "</service-charges>" +
                            "<total-charges>" + Editor.TxtTotalCharges.Text + "</total-charges>" +
                            "<state-taxes>" + Editor.TxtStateTaxes.Text + "</state-taxes>" +
                            "<local-taxes>" + Editor.TxtLocalTaxes.Text + "</local-taxes>" +
                            "<payment-due-date>" + Editor.DtpPaymentDueDate.Value.ToShortDateString() + "</payment-due-date>" +
                            "<amount-due>" + Editor.TxtAmountDue.Text + "</amount-due>" +
                            "<late-payment-due-date>" + Editor.DtpLatePaymentDueDate.Value.ToShortDateString() + "</late-payment-due-date>" +
                            "<late-amount-due>" + Editor.TxtLateAmountDue.Text + "</late-amount-due>"
    
                    xdWaterBills.Save(strWaterBills)
                    Exit For
                End If
            Next
        End If
    
        ShowWaterBills()
    End Sub
  22. To execute the application, on the main menu, click Debug -> Start Without Debugging

    Stellar Water Point

  23. On the main form of the application, click the Water Bills button:

    Stellar Water Point - Water Bills

  24. Click the Edit Water Bill button:

    Stellar Water Point - Water Bill Editor

  25. In the Water Bill # text, type 923633
  26. Click the Find Water Bill button

    Stellar Water Point - Water Bill Editor

  27. 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
  28. Click the Re-Evaluate Water Bill button:

    Stellar Water Point - New Water Bill

  29. Click the Update Water Bill button:

    Stellar Water Point - Water Bills

  30. Close the forms and return to your programming environment

Deleting a Water Bill

If something is completely wrong about a water bill so much that such a water bill must be removed from the application, the water bill must be deleted. To assist the user with such an operation, we will create the necessary form.

Practical LearningPractical Learning: Deleting a Customer Account

  1. To create a new form, in the Solution Explorer, right-click StellarWaterPoint -> New -> Form (Windows Forms)...
  2. Set the name of the file and form to BillDelete
  3. Click Add
  4. Make that form the same size as the BillDetails form
  5. Select everything on the Water Bill - Details form and copy that selection
  6. Paste that selection in the Water Bill - Delete form
  7. Complete the design of the form as follows:

    Stellar Water Point - Water Bill Deletion

    Control (Name) Text
    Button Button BtnDeleteWaterBill &Delete Water Bill
  8. Using the Properties window, change some characteristics of the form as follows:
    FormBorderStyle: FixedDialog
    Text:            Stellar Water Point - Water Bill Deletion
    StartPosition:   CenterScreen
    MinimizeBox:     False
    MaximizeBox:     False
    ShowInTaskbar:   False
  9. On the form, double-click the Find Water Bill button
  10. Change the document as follows:
    Imports System.IO
    Imports System.Xml
    
    Public Class BillDelete
        Private Sub BtnFindWaterBill_Click(sender As Object, e As EventArgs) Handles BtnFindWaterBill.Click
    
            ' If the user clicks the Find Water Meter button, 
            ' make sure there is an invoice number in the top text box.
            If String.IsNullOrEmpty(TxtWaterBillNumber.Text) Then
                MsgBox("You must provide a water bill number and then click the Find Water Bill button.",
                       MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                       "Stellar Water Point")
                ' If the user didn't type a bill number but clicked Find Water Bill, don't do anything
                Exit Sub
            End If
    
            Dim xdWaterBills As New XmlDocument()
            Dim strWaterBills = "C:\Stellar Water Point12\WaterBills.xml"
    
            Dim fiWaterBills As New FileInfo(strWaterBills)
    
            If fiWaterBills.Exists Then
                Using fsWaterBills As New FileStream(fiWaterBills.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    xdWaterBills.Load(fsWaterBills)
    
                    ' Use XPath to locate the water bill that has 
                    ' the same invoice number as the one in the Water Bill Number text box.
                    ' Store the water bill in an XmlNodeList variable.
                    Dim xnlWaterBills As XmlNodeList = xdWaterBills.DocumentElement.SelectNodes("//bill-number[.='" + TxtWaterBillNumber.Text + "']")
    
                    For Each xnWaterBill As XmlNode In xnlWaterBills
                        TxtWaterBillNumber.Text = xnWaterBill.FirstChild.InnerText
                        TxtAccountNumber.Text = xnWaterBill.NextSibling.InnerText
                        TxtMeterReadingStartDate.Text = CDate(xnWaterBill.NextSibling.NextSibling.InnerText).ToLongDateString()
                        TxtMeterReadingEndDate.Text = CDate(xnWaterBill.NextSibling.NextSibling.NextSibling.InnerText).ToLongDateString()
                        TxtBillingDays.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtCounterReadingStart.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtCounterReadingEnd.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtTotalHCF.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtTotalGallons.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtFirstTierConsumption.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtSecondTierConsumption.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtLastTierConsumption.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtWaterCharges.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtSewerCharges.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtEnvironmentCharges.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtServiceCharges.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtTotalCharges.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtStateTaxes.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtLocalTaxes.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtPaymentDueDate.Text = CDate(xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText).ToLongDateString()
                        TxtAmountDue.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtLatePaymentDueDate.Text = CDate(xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText).ToLongDateString()
                        TxtLateAmountDue.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                    Next
                End Using
            End If
    
            Dim xdCustomers As XmlDocument = New XmlDocument()
            ' Declare a variable for a file that holds the list of customers
            Dim strCustomers = "C:\Stellar Water Point12\Customers.xml"
    
            ' Create a FileInfo object for the customers
            Dim fiCustomers As FileInfo = New FileInfo(strCustomers)
    
            ' We will need to know the water meter associated with this customer account
            Dim strMeterNumber = Nothing
    
            ' Check whether the file that holds a list of customers exists
            If fiCustomers.Exists Then
                ' If that exists, open it and pass it to a FileStream object
                Using fsCustomers As FileStream = New FileStream(fiCustomers.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    ' Get the list of customers and pass the records to the XML DOM object created earlier
                    xdCustomers.Load(fsCustomers)
                    ' Create an XmlNodeList list of customers using XPath
                    Dim xnlCustomers As XmlNodeList = xdCustomers.DocumentElement.SelectNodes("//account-number[.='" + TxtAccountNumber.Text + "']")
    
                    ' Check each node of the XML record and display its values in each Windows control on the form
                    For Each xnCustomer As XmlNode In xnlCustomers
                        ' MtbAccountNumber.Text = xnCustomer.NextSibling.InnerText ' Meter #
                        TxtAccountName.Text = xnCustomer.NextSibling.InnerText REM Account Name
    
                        strMeterNumber = xnCustomer.NextSibling.NextSibling.InnerText ' Meter Number
                        TxtAccountType.Text = xnCustomer.NextSibling.NextSibling.NextSibling.InnerText ' Account Type
                        TxtAddress.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.InnerText ' Address
                        TxtCity.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText ' City
                        TxtCounty.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText ' County
                        TxtState.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText ' State
                        TxtZIPCode.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText ' ZIP-Code
                    Next
                End Using
            End If
    
            ' Create an XML DOM object for the water meters records
            Dim xdWaterMeters As XmlDocument = New XmlDocument()
            ' Declare a variable for a file that holds the list of water meters
            Dim strWaterMeters As String = "C:\Stellar Water Point12\WaterMeters.xml"
    
            ' Create a FileInfo object for the customers
            Dim fiWaterMeters As FileInfo = New FileInfo(strWaterMeters)
    
            ' Check whether the file that holds a list of water meters exists
            If fiWaterMeters.Exists Then
                ' Get the list of water meters and pass the records to the XML DOM object
                Using fsWaterMeters As FileStream = New FileStream(fiWaterMeters.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
    
                    ' Get the list of water meters and pass the records to the XML DOM object
                    xdWaterMeters.Load(fsWaterMeters)
                    ' Create an XmlNodeList list of water meters using XPath
                    Dim xnlWaterMeters As XmlNodeList = xdWaterMeters.DocumentElement.SelectNodes("//meter-number[.='" + strMeterNumber + "']")
    
                    ' Check each node of the XML record
                    For Each xnWaterMeter As XmlNode In xnlWaterMeters
                        ' Get the values for the water meter.
                        ' Create a sentence and display it in the Meter Details text box.
                        TxtMeterDetails.Text = xnWaterMeter.NextSibling.InnerText + " " +
                                               xnWaterMeter.NextSibling.NextSibling.InnerText + " (Meter Size: " +
                                               xnWaterMeter.NextSibling.NextSibling.NextSibling.InnerText + ")"
                    Next
                End Using
            End If
        End Sub
    End Class
  11. Return to the BillDelete form and double-click the Delete Water Bill button
  12. Return to the form and double-click the Close button
  13. Change the document as follows:
    Imports System.IO
    Imports System.Xml
    
    Public Class BillDelete
        Private Sub BtnFindWaterBill_Click(sender As Object, e As EventArgs) Handles BtnFindWaterBill.Click
    
            ' If the user clicks the Find Water Meter button, 
            ' make sure there is an invoice number in the top text box.
            If String.IsNullOrEmpty(TxtWaterBillNumber.Text) Then
                MsgBox("You must provide a water bill number and then click the Find Water Bill button.",
                       MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                       "Stellar Water Point")
                ' If the user didn't type a bill number but clicked Find Water Bill, don't do anything
                Exit Sub
            End If
    
            Dim xdWaterBills As New XmlDocument()
            Dim strWaterBills = "C:\Stellar Water Point12\WaterBills.xml"
    
            Dim fiWaterBills As New FileInfo(strWaterBills)
    
            If fiWaterBills.Exists Then
                Using fsWaterBills As New FileStream(fiWaterBills.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    xdWaterBills.Load(fsWaterBills)
    
                    ' Use XPath to locate the water bill that has 
                    ' the same invoice number as the one in the Water Bill Number text box.
                    ' Store the water bill in an XmlNodeList variable.
                    Dim xnlWaterBills As XmlNodeList = xdWaterBills.DocumentElement.SelectNodes("//bill-number[.='" + TxtWaterBillNumber.Text + "']")
    
                    For Each xnWaterBill As XmlNode In xnlWaterBills
                        TxtWaterBillNumber.Text = xnWaterBill.FirstChild.InnerText
                        TxtAccountNumber.Text = xnWaterBill.NextSibling.InnerText
                        TxtMeterReadingStartDate.Text = CDate(xnWaterBill.NextSibling.NextSibling.InnerText).ToLongDateString()
                        TxtMeterReadingEndDate.Text = CDate(xnWaterBill.NextSibling.NextSibling.NextSibling.InnerText).ToLongDateString()
                        TxtBillingDays.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtCounterReadingStart.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtCounterReadingEnd.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtTotalHCF.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtTotalGallons.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtFirstTierConsumption.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtSecondTierConsumption.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtLastTierConsumption.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtWaterCharges.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtSewerCharges.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtEnvironmentCharges.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtServiceCharges.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtTotalCharges.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtStateTaxes.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtLocalTaxes.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtPaymentDueDate.Text = CDate(xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText).ToLongDateString()
                        TxtAmountDue.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                        TxtLatePaymentDueDate.Text = CDate(xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText).ToLongDateString()
                        TxtLateAmountDue.Text = xnWaterBill.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText
                    Next
                End Using
            End If
    
            Dim xdCustomers As XmlDocument = New XmlDocument()
            ' Declare a variable for a file that holds the list of customers
            Dim strCustomers = "C:\Stellar Water Point12\Customers.xml"
    
            ' Create a FileInfo object for the customers
            Dim fiCustomers As FileInfo = New FileInfo(strCustomers)
    
            ' We will need to know the water meter associated with this customer account
            Dim strMeterNumber = Nothing
    
            ' Check whether the file that holds a list of customers exists
            If fiCustomers.Exists Then
                ' If that exists, open it and pass it to a FileStream object
                Using fsCustomers As FileStream = New FileStream(fiCustomers.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    ' Get the list of customers and pass the records to the XML DOM object created earlier
                    xdCustomers.Load(fsCustomers)
                    ' Create an XmlNodeList list of customers using XPath
                    Dim xnlCustomers As XmlNodeList = xdCustomers.DocumentElement.SelectNodes("//account-number[.='" + TxtAccountNumber.Text + "']")
    
                    ' Check each node of the XML record and display its values in each Windows control on the form
                    For Each xnCustomer As XmlNode In xnlCustomers
                        ' MtbAccountNumber.Text = xnCustomer.NextSibling.InnerText ' Meter #
                        TxtAccountName.Text = xnCustomer.NextSibling.InnerText REM Account Name
    
                        strMeterNumber = xnCustomer.NextSibling.NextSibling.InnerText ' Meter Number
                        TxtAccountType.Text = xnCustomer.NextSibling.NextSibling.NextSibling.InnerText ' Account Type
                        TxtAddress.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.InnerText ' Address
                        TxtCity.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText ' City
                        TxtCounty.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText ' County
                        TxtState.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText ' State
                        TxtZIPCode.Text = xnCustomer.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText ' ZIP-Code
                    Next
                End Using
            End If
    
            ' Create an XML DOM object for the water meters records
            Dim xdWaterMeters As XmlDocument = New XmlDocument()
            ' Declare a variable for a file that holds the list of water meters
            Dim strWaterMeters As String = "C:\Stellar Water Point12\WaterMeters.xml"
    
            ' Create a FileInfo object for the customers
            Dim fiWaterMeters As FileInfo = New FileInfo(strWaterMeters)
    
            ' Check whether the file that holds a list of water meters exists
            If fiWaterMeters.Exists Then
                ' Get the list of water meters and pass the records to the XML DOM object
                Using fsWaterMeters As FileStream = New FileStream(fiWaterMeters.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
    
                    ' Get the list of water meters and pass the records to the XML DOM object
                    xdWaterMeters.Load(fsWaterMeters)
                    ' Create an XmlNodeList list of water meters using XPath
                    Dim xnlWaterMeters As XmlNodeList = xdWaterMeters.DocumentElement.SelectNodes("//meter-number[.='" + strMeterNumber + "']")
    
                    ' Check each node of the XML record
                    For Each xnWaterMeter As XmlNode In xnlWaterMeters
                        ' Get the values for the water meter.
                        ' Create a sentence and display it in the Meter Details text box.
                        TxtMeterDetails.Text = xnWaterMeter.NextSibling.InnerText + " " +
                                               xnWaterMeter.NextSibling.NextSibling.InnerText + " (Meter Size: " +
                                               xnWaterMeter.NextSibling.NextSibling.NextSibling.InnerText + ")"
                    Next
                End Using
            End If
        End Sub
    
        Private Sub BtnDeleteWaterBill_Click(sender As Object, e As EventArgs) Handles BtnDeleteWaterBill.Click
            Dim xdWaterMeters As XmlDocument = New XmlDocument()
            Dim strWaterMeters As String = "C:\Stellar Water Point12\WaterBills.xml"
    
            If String.IsNullOrEmpty(TxtWaterBillNumber.Text) Then
                MsgBox("You must provide a bill number for the water bill you want to delete.",
                       MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                       "Stellar Water Point")
                Exit Sub
            End If
    
            If Not File.Exists(strWaterMeters) Then
                MsgBox("There is no file for the water bills in the system.",
                                    MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                                    "Stellar Water Point")
                Exit Sub
            End If
    
            xdWaterMeters.Load(strWaterMeters)
    
            Dim xnlWaterMeters As XmlNodeList = xdWaterMeters.DocumentElement.GetElementsByTagName("bill-number")
    
            For Each xnWaterMeter As XmlNode In xnlWaterMeters
                If xnWaterMeter.InnerText = TxtWaterBillNumber.Text Then
                    If MsgBox("Are you sure you want to delete this water bill from the system?",
                       MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                                            "Stellar Water Point") = MsgBoxResult.Yes Then
                        xdWaterMeters.DocumentElement.RemoveChild(xnWaterMeter.ParentNode)
                        Exit For
                    End If
                End If
            Next
    
            xdWaterMeters.Save(strWaterMeters)
    
            Close()
        End Sub
    
        Private Sub BtnClose_Click(sender As Object, e As EventArgs) Handles BtnClose.Click
            Close()
        End Sub
    End Class
  14. In the Solution Explorer, double-click BillsCentral.cs to open its form
  15. From the Toolbox, add two buttons to the form below the list view and to the right of the Edit Water Bill button
  16. Change the form design as follows:

    Stellar Water Point - Water Bills

    Control (Name) Text Other Properties
    ListView List View LvwWaterBills   Anchor: Bottom, Top, Bottom, Left, Right
    Button Button BtnCreateWaterBill &Create Water Bill... Anchor: Bottom, Right
    Button Button BtnViewWaterBill &View Water Bill... Anchor: Bottom, Right
    Button Button BtnEditWaterBill &Edit Water Bill... Anchor: Bottom, Right
    Button Button BtnDeleteWaterBill &Delete Water Bill... Anchor: Bottom, Right
    Button Button BtnClose &Close Anchor: Bottom, Right
  17. On the form, double-click the Delete Water Bill button
  18. Return to the Water Bills - Central form and double-click the Close button
  19. Implement the events as follows:
    Imports System.IO
    Imports System.Xml
    
    Public Class BillsCentral
    
        Private Sub ShowWaterBills()
            LvwWaterBills.Items.Clear()
    
            Dim xdWaterBills As XmlDocument = New XmlDocument()
            Dim strWaterBills = "C:\Stellar Water Point12\WaterBills.xml"
    
            Dim fiWaterBills As FileInfo = New FileInfo(strWaterBills)
    
            If fiWaterBills.Exists Then
                Using fsWaterBills As New FileStream(fiWaterBills.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)
                    xdWaterBills.Load(fsWaterBills)
    
                    Dim xnlWaterBills As XmlNodeList = xdWaterBills.DocumentElement.ChildNodes
    
                    Dim i As Integer = 1
    
                    For Each xnWaterBill As XmlNode In xnlWaterBills
                        Dim lviWaterBill As ListViewItem = New ListViewItem(CStr(i))
    
                        lviWaterBill.SubItems.Add(xnWaterBill.FirstChild.InnerText)
                        lviWaterBill.SubItems.Add(xnWaterBill.FirstChild.NextSibling.InnerText)
                        lviWaterBill.SubItems.Add(xnWaterBill.FirstChild.NextSibling.NextSibling.InnerText)
                        lviWaterBill.SubItems.Add(xnWaterBill.FirstChild.NextSibling.NextSibling.NextSibling.InnerText)
                        lviWaterBill.SubItems.Add(xnWaterBill.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.InnerText)
                        lviWaterBill.SubItems.Add(xnWaterBill.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText)
                        lviWaterBill.SubItems.Add(xnWaterBill.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText)
                        lviWaterBill.SubItems.Add(xnWaterBill.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText)
                        lviWaterBill.SubItems.Add(xnWaterBill.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText.ToString())
                        lviWaterBill.SubItems.Add(xnWaterBill.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText)
                        lviWaterBill.SubItems.Add(xnWaterBill.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.NextSibling.InnerText)
    
                        LvwWaterBills.Items.Add(lviWaterBill)
    
                        i = i + 1
                    Next
                End Using
            End If
        End Sub
    
        Private Sub BillsCentral_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            ShowWaterBills()
        End Sub
    
        Private Sub BtnCreateWaterBill_Click(sender As Object, e As EventArgs) Handles BtnCreateWaterBill.Click
            Dim Create As New BillCreate
    
            Create.ShowDialog()
    
            ShowWaterBills()
        End Sub
    
        Private Sub BtnViewWaterBill_Click(sender As Object, e As EventArgs) Handles BtnViewWaterBill.Click
            Dim Details As New BillDetails
    
            Details.Show()
        End Sub
    
        Private Sub BtnEditWaterBill_Click(sender As Object, e As EventArgs) Handles BtnEditWaterBill.Click
            Dim Editor As New BillEditor
    
            If Editor.ShowDialog() = DialogResult.OK Then
                If String.IsNullOrEmpty(Editor.TxtWaterBillNumber.Text) Then
                    MsgBox("You must first type a bill number and then click the Find Water Bill button. " +
                           "You can then optionally change some values on the water bill and save it.",
                           MsgBoxStyle.OkOnly Or MsgBoxStyle.Information,
                           "Stellar Water Point")
                    Exit Sub
                End If
    
                Dim xdWaterBills = New XmlDocument()
                Dim strWaterBills = "C:\Stellar Water Point12\WaterBills.xml"
    
                xdWaterBills.Load(strWaterBills)
    
                Dim xnlWaterBills As XmlNodeList = xdWaterBills.DocumentElement.GetElementsByTagName("bill-number")
    
                For Each xnWaterBill As XmlNode In xnlWaterBills
                    If xnWaterBill.InnerText.Contains(Editor.TxtWaterBillNumber.Text) Then
                        xnWaterBill.ParentNode.InnerXml =
                                "<bill-number>" + Editor.TxtWaterBillNumber.Text + "</bill-number>" +
                                "<account-number>" + Editor.MtbAccountNumber.Text + "</account-number>" +
                                "<meter-reading-start-date>" + Editor.DtpMeterReadingStartDate.Value.ToShortDateString() + "</meter-reading-start-date>" +
                                "<meter-reading-end-date>" + Editor.DtpMeterReadingEndDate.Value.ToShortDateString() + "</meter-reading-end-date>" +
                                "<billing-days>" + Editor.TxtBillingDays.Text + "</billing-days>" +
                                "<counter-reading-start>" + Editor.TxtCounterReadingStart.Text + "</counter-reading-start>" +
                                "<counter-reading-end>" + Editor.TxtCounterReadingEnd.Text + "</counter-reading-end>" +
                                "<total-hcf>" + Editor.TxtTotalHCF.Text + "</total-hcf>" +
                                "<total-gallons>" + Editor.TxtTotalGallons.Text + "</total-gallons>" +
                                "<first-tier-consumption>" + Editor.TxtFirstTierConsumption.Text + "</first-tier-consumption>" +
                                "<second-tier-consumption>" + Editor.TxtSecondTierConsumption.Text + "</second-tier-consumption>" +
                                "<last-tier-consumption>" + Editor.TxtLastTierConsumption.Text + "</last-tier-consumption>" +
                                "<water-charges>" + Editor.TxtWaterCharges.Text + "</water-charges>" +
                                "<sewer-charges>" + Editor.TxtSewerCharges.Text + "</sewer-charges>" +
                                "<environment-charges>" + Editor.TxtEnvironmentCharges.Text + "</environment-charges>" +
                                "<service-charges>" + Editor.TxtEnvironmentCharges.Text + "</service-charges>" +
                                "<total-charges>" + Editor.TxtTotalCharges.Text + "</total-charges>" +
                                "<state-taxes>" + Editor.TxtStateTaxes.Text + "</state-taxes>" +
                                "<local-taxes>" + Editor.TxtLocalTaxes.Text + "</local-taxes>" +
                                "<payment-due-date>" + Editor.DtpPaymentDueDate.Value.ToShortDateString() + "</payment-due-date>" +
                                "<amount-due>" + Editor.TxtAmountDue.Text + "</amount-due>" +
                                "<late-payment-due-date>" + Editor.DtpLatePaymentDueDate.Value.ToShortDateString() + "</late-payment-due-date>" +
                                "<late-amount-due>" + Editor.TxtLateAmountDue.Text + "</late-amount-due>"
    
                        xdWaterBills.Save(strWaterBills)
                        Exit For
                    End If
                Next
            End If
    
            ShowWaterBills()
        End Sub
    
        Private Sub BtnDeleteWaterBill_Click(sender As Object, e As EventArgs) Handles BtnDeleteWaterBill.Click
            Dim Deletion = New BillDelete
    
            Deletion.ShowDialog()
    
            ShowWaterBills()
        End Sub
    
        Private Sub BtnClose_Click(sender As Object, e As EventArgs) Handles BtnClose.Click
            Close()
        End Sub
    End Class
  20. To execute, on the main menu, click Debug -> Start Without Debugging:

  21. On the Stellar Water Point form, click the Water Bills button

    Stellar Water Point - Water Bill Processing

  22. On the Water Bills form, click the Delete Water Bill button

    Stellar Water Point - Water Bill Deletion

  23. In the Water Bill # text box, type 917829
  24. Click Find Water Bill

    Stellar Water Point - Water Bill Deletion

  25. Click Delete Water Bill
  26. Read the message in the message box and click Yes:

    Stellar Water Point - Water Bills

    Stellar Water Point - Water Bills

  27. Close the forms and return to your programming environment
  28. From the Windows Explorer, open the WaterBills.xml file
  29. Replace the content of the file with the provided file
  30. Save the file
  31. Return to your programming environment
  32. Close Microsoft Visual Studio

Application


Home Copyright © 2010-2026, FunctionX Sunday 30 March 2025, 13:50 Home