Home

Example Application:
Bethesda Car Rental

Bethesda Car Rental: Rental Order

Description

This is a file-based application that uses the dictionary-types of the .NET Framework's built-in collection classes.

The application is used by a car rental company. To start, a list of cars and the employees of the company are created. When a customer comes to rent a car, an account is created. This would be used for a rental order. To make this application simple, only the most basic pieces of information are collected. These include the customer's full name and the driver's license number.

During rental order processing, a clerk selects the customer and the type of car he or she wants to rent.

Practical LearningPractical Learning: Introducing Dictionary Collections

  1. Start Microsoft Visual C#
  2. Create a new Windows Application named BethesdaCarRental1
  3. To add a new form to the project, in the Solution Explorer, right-click BethesdaCarRental1 -> Add -> Windows Form...
  4. Set the Name to RentalRates and press Enter
  5. Add a ListView to the form and create its Columns as follows:
     
    (Name) Text TextAlign Width
    colCategory Category   90
    colDaily Daily Right  
    colWeekly Weekly Right  
    colMonthly Monthly Right  
    colWeekend Weekend Right  
  6. Create its Items as follows:
     
    ListViewItem SubItems SubItems SubItems SubItems
      Text Text Text Text
    Economy 35.95 32.75 28.95 24.95
    Compact 39.95 35.75 32.95 28.95
    Standard 45.95 39.75 35.95 32.95
    Full Size 49.95 42.75 38.95 35.95
    Mini Van 55.95 50.75 45.95 42.95
    SUV 55.95 50.75 45.95 42.95
    Truck 42.75 38.75 35.95 32.95
    Van 69.95 62.75 55.95 52.95
  7. Complete the design of the form as follows:
     
    Rental Rates
  8. To add a new form to the application, in the Solution Explorer, right-click BethesdaCarRental1 -> Add -> Windows Form...
  9. Set the Name to Employees and click Add
  10. From the Toolbox, add a ListView to the form
  11. While the new list view is still selected, in the Properties window, click the ellipsis button of the Columns field and create the columns as follows:
     
    (Name) Text TextAlign Width
    colEmployeeNumber Empl #   45
    colFirstName First Name   65
    colLastName Last Name   65
    colFullName Full Name   140
    colTitle Title   120
    colHourlySalary Hourly Salary Right 75
  12. Design the form as follows: 
     
    Bethesda Car Rental: Employees
     
    Control Text Name Other Properties
    ListView   lvwEmployees Anchor: Top, Bottom, Left, Right
    FullRowSelect: True
    GridLines: True
    View: Details
    Button New Employee... btnNewEmployee  
    Button Close btnClose  
  13. To add another form to the application, in the Solution Explorer, right- click BethesdaCarRental1 -> Add -> Windows Form...
  14. Set the Name to EmployeeEditor and click Add
  15. Design the form as follows: 
     
    Bethesda Car Rental: Employees
     
    Control Text Name Properties
    Label &Employee #:    
    MaskedTextBox   txtEmployeeNumber Mask: 00-000
    Modifiers: public
    Label First Name:    
    TextBox   txtFirstName Modifiers: public
    Label Last Name:    
    TextBox   txtLastName Modifiers: public
    Label Full Name:    
    TextBox   txtFullName Enabled: False
    Modifiers: public
    Label Title:    
    TextBox   txtTitle Modifiers: public
    Label Hourly Salary:    
    TextBox   txtHourlySalary Modifiers: public
    TextAlign: Right
    Button OK btnOK DialogResult: OK
    Button Cancel btnCancel DialogResult: Cancel
    Form     AcceptButton: btnOK
    CancelButton: btnCancel
    FormBorderStyle: FixedDialog
    MaximizeBox: False
    MinimizeBox: False
    ShowInTaskbar: False
  16. Click the Last Name text box
  17. In the Properties window, click the Events button and double-click Leave
  18. Implement the event as follows:
     
    // This code is used to create and display the customer's full name
    private void txtLastName_Leave(object sender, EventArgs e)
    {
        string strFirstName = txtFirstName.Text;
        string strLastName = txtLastName.Text;
        string strFullName;
    
        if (strFirstName.Length == 0)
            strFullName = strLastName;
        else
            strFullName = strLastName + ", " + strFirstName;
    
        txtFullName.Text = strFullName;
    }
  19. To add a new class to the project, in the Class View, right- click BethesdaCarRental1 -> Add -> Class...
  20. Set the Class Name to Employee and click Add
  21. Change the Employee.cs file as follows:
     
    using System;
    
    namespace BethesdaCarRental1
    {
        [Serializable]
        public class Employee
        {
            public string FirstName;
            public string LastName;
            public string Title;
            public double HourlySalary;
    
            public string FullName
            {
                get { return LastName + ", " + FirstName; }
            }
    
            // This default constructor says that
    	// the employee is not defined
            public Employee()
            {
                FirstName = "Unknown";
                LastName = "Unknown";
                Title = "N/A";
                HourlySalary = 0.00;
            }
    
            // This constructor completely defines an employee
            public Employee(string fname, string lname,
                            string title, double salary)
            {
                FirstName = fname;
                LastName = lname;
                Title = title;
                HourlySalary = salary;
            }
        }
    }
  22. To add a new form to the application, on the main menu, click Project -> Add Windows Forms
  23. Set the Name to Customers and press Enter
  24. From the Toolbox, add a ListView to the form
  25. While the new list view is still selected, in the Properties window, click the ellipsis button of the Columns field and create the columns as follows:
     
    (Name) Text Width
    colDrvLicNbr Driver's Lic. # 100
    colFullName Full Name 100
    colAddress Address 160
    colCity City 100
    colState State 38
    colZIPCode ZIPCode  
  26. Design the form as follows: 
     
    Bethesda Car Rental: Customers
     
    Control Text Name Other Properties
    ListView   lvwCustomers View: Details
    GridLines: True
    FullRowSelect: True
    Button New Customer... btnNewCustomer  
    Button Close btnClose  
  27. To add another form to the application, on the main menu, click Project -> Add Windows Forms
  28. Set the Name to CustomerEditor and click Add
  29. Design the form as follows: 
     
    Bethesda Car Rental: Customers
     
    Control Text Name Properties
    Label Driver's Lic. #:    
    TextBox   txtDrvLicNbr Modifiers: Public
    Label State:    
    ComboBox   cbxStates Modifiers: Public
    Items: AL, AK, AZ, AR, CA, CO, CT, DE, DC, FL, GA, HI, ID, IL, IN, IA, KS, KY, LA, ME, MD, MA, MI, MN, MS, MO, MT, NE, NV, NH, NJ, NM, NY, NC, ND, OH, OK, OR, PA, RI, SC, SD, TN, TX, UT, VT, VA, WA, WV, WI, WY
    Label Full Name:    
    TextBox   txtFullName Modifiers: Public
    Label Address:    
    TextBox   txtAddress Modifiers: Public
    Label City:    
    TextBox   txtCity Modifiers: Public
    Label ZIP Code:    
    TextBox   txtZIPCode Modifiers: Public
    Button OK btnOK DialogResult: OK
    Button Close btnCancel DialogResult: Cancel
    Form     AcceptButton: btnOK
    CancelButton: btnCancel
    FormBorderStyle: FixedDialog
    MaximizeBox: False
    MinimizeBox: False
    ShowInTaskbar: False
  30. To add a new class to the project, in the Class View, right-click BethesdaCarRental1 -> Add -> Class...
  31. Set the Class Name to Customer and click Finish
  32. Change the Customer.cs file as follows:
     
    using System;
    
    namespace BethesdaCarRental1
    {
        [Serializable]
        public class Customer
        {
            public string FullName;
            public string Address;
            public string City;
            public string State;
            public string ZIPCode;
    
            public Customer()
            {
                FullName = "";
                Address = "";
                City = "";
                State = "";
                ZIPCode = "";
            }
    
            // This constructor defines a customer
            public Customer(string fName,
                            string adr, string ct,
                            string ste, string zip)
            {
                FullName = fName;
                Address = adr;
                City = ct;
                State = ste;
                ZIPCode = zip;
            }
        }
    }
  33. Save all
  34. Copy the following pictures to any folder somewhere on your computer (this is simply an example of preparing the pictures of cars you would include in your database application):
     
    Chevrolet Avalanche
    BMW: 335i Chevrolet Avalanche
    Mazda Miata
    Honda Accord Mazda Miata
    Chevrolet Aveo Ford E150XL
    Chevrolet Aveo Ford E150XL
    Buick LaCrosse Honda Civic
    Buick Lacrosse Honda Civic
    Ford F-150 Mazda Mazda5
    Ford F-150 Mazda Mazda5
    Volvo S40 Land Rover LR3
    Volvo S40 Land Rover LR3
  35. Return to your programming environment
  36. To add a new form to the application, in the Solution Explorer, right-click BethesdaCarRental1 -> Add -> Windows Forms
  37. Set the Name to CarEditor and click Add
  38. Design the form as follows: 
     
    Bethesda Car Rental - Car Editor
    Control Text Name Other Properties
    Label Text #    
    TextBox   txtTagNumber  
    Label Make:    
    TextBox   txtMake  
    Label Model:    
    TextBox   txtModel  
    Label Year:    
    TextBox   txtYear  
    Label Category:    
    ComboBox   cboCategories DropDownStyle: DropDownList
    Items: Economy
    Compact
    Standard
    Full Size
    Mini Van
    SUV
    Truck
    Van
    PictureBox   pbxCar SizeMode: Zoom
    CheckBox CD Player chkCDPlayer CheckAlign: MiddleRight
    CheckBox DVD Player chkDVDPlayer CheckAlign: MiddleRight
    Button Select Car Picture... btnSelectPicture  
    CheckBox Available chkAvailable CheckAlign: MiddleRight
    Label Picture Name lblPictureName  
    Button Submit btnSubmit  
    Button Close btnClose DialogResult: Cancel
    OpenFileDialog (Name): dlgOpen
    Title: Select Item Picture
    DefaultExt: jpg
    Filter: JPEG Files (*.jpg,*.jpeg)|*.jpg|GIF Files (*.gif)|*.gif|Bitmap Files (*.bmp)|*.bmp|PNG Files (*.png)|*.png
    Form     FormBorderStyle: FixedDialog
    MaximizeBox: False
    MinimizeBox: False
    ShowInTaskbar: False
  39. Double-click the Select Car Picture button and implement its event as follows:
     
    private void btnSelectPicture_Click(object sender, EventArgs e)
    {
        if (dlgPicture.ShowDialog() == DialogResult.OK)
        {
            lblPictureName.Text = dlgPicture.FileName;
            pbxCar.Image = Image.FromFile(lblPictureName.Text);
        }
    }
  40. To add a new class to the project, in the Class View, right-click BethedaCarRental1 -> Add -> Class...
  41. Set the Class Name to Car and click Add
  42. Change the file as follows:
     
    using System;
    
    namespace BethesdaCarRental1
    {
        [Serializable]
        public class Car
        {
            public string Make;
            public string Model;
            public int Year;
            public string Category;
            public bool HasCDPlayer;
            public bool HasDVDPlayer;
            public bool IsAvailable;
    
            public Car()
            {
                Make = "";
                Model = "";
                Year = 0;
                Category = "";
                HasCDPlayer = false;
                HasDVDPlayer = false;
                IsAvailable = false;
            }
    
            public Car(string mk, string mdl,
                       int yr, string cat, bool cd,
                       bool  dvd, bool avl)
            {
                Make = mk;
                Model = mdl;
                Year = yr;
                Category = cat;
                HasCDPlayer = cd;
                HasDVDPlayer = dvd;
                IsAvailable = avl;
            }
        }
    }
  43. To add a new class to the project, in the Class View, right-click BethesdaCarRental -> Add -> Class...
  44. Set the Class Name to RentalOrder and press Enter
  45. Access the RentalOrder.h file and change it as follows:
     
    using System;
    
    namespace BethesdaCarRental1
    {
        [Serializable]
        public class RentalOrder
        {
            public string EmployeeNumber;
            // The following flag will allow us to update/know whether
            // * The car is currently being used by the customer.
            //   That is, if the car has been picked up by the customer
            // * The customer has brought the car back
            public string OrderStatus;
            // Because every car has a tag number
            // and that tag number will not change
            // during the lifetime of a car (while the car remains with our
    	// car rental company, we will 
            // use only the tag number here.
            // The other pieces of information will 
            // be retrieved from the list of cars
            public string CarTagNumber;
            // We will identify the customer by the number
            // and the name on his or her driver's license
            public string CustomerDrvLicNbr;
            public string CustomerName;
            // Although he or she may keep the same driver's 
            // license number for a lifetime, a customer who 
            // rents cars at different times with this company 
    	// over months or years may have different addresses.
            // Therefore, although we will primarily retrieve the 
            // customer's address from the list of customers,
            // we will give the clerk the ability to change this 
            // information on a rental order. This means that the 
            // same customer could have different information on 
            // different rental orders.
    	// For this reason, each rental order will its own set
    	// of these pieces of information
            public string CustomerAddress;
            public string CustomerCity;
            public string CustomerState;
            public string CustomerZIPCode;
            public string CarCondition;
            public string TankLevel;
            // This information will be entered when the car is being rented
            public int MileageStart;
            // This information will be entered when the car is brought back
            public int MileageEnd;
            // This information will be entered when the car is being rented
            public DateTime DateStart;
            // This information will be entered when the car is brought back
            public DateTime DateEnd;
            public int Days;
            // This information will be entered when the car is being rented
            public double RateApplied;
            // This calculation should occur when the car is brought back
            public double SubTotal;
            public double TaxRate;
            public double TaxAmount;
            public double OrderTotal;
    
            public RentalOrder()
            {
            }
        }
    }
  46. To add a new form to the project, in the Solution Explorer, right-click BethesdaCarRenatl -> Add -> Windows Form...
  47. Set the Name to OrderProcessing and press Enter
  48. Design the form as follows:
     
    Rental Orders
    Control Text Name Other Properties
    Label Processed By:   AutoSize: False
    BackColor: Gray
    BorderStyle: FixedSingle
    ForeColor: White
    TextAlign: MiddleLeft
    Label Employee #:    
    MaskedTextBox   txtEmployeeNumber Mask: 00-000
    Label Employee Name:    
    TextBox   txtEmployeeName  
    Label Processed For   AutoSize: False
    BackColor: Gray
    BorderStyle: FixedSingle
    ForeColor: White
    TextAlign: MiddleLeft
    Label Driver's Lic #:    
    TextBox   txtDrvLicNumber  
    Label Cust Name:    
    TextBox   txtCustomerName  
    Label Address:    
    TextBox   txtCustomerAddress  
    Label City:    
    TextBox   txtCustomerCity  
    Label State:    
    ComboBox   cbxCustomerStates DropDownStyle: DropDownList
    Sorted: True
    Items: AL, AK, AZ, AR, CA, CO, CT, DE, DC, FL, GA, HI, ID, IL, IN, IA, KS, KY, LA, ME, MD, MA, MI, MN, MS, MO, MT, NE, NV, NH, NJ, NM, NY, NC, ND, OH, OK, OR, PA, RI, SC, SD, TN, TX, UT, VT, VA, WA, WV, WI, WY
    Label ZIP Code    
    TextBox   txtCustomerZIPCode  
    Label Car Selected   AutoSize: False
    BackColor: Gray
    BorderStyle: FixedSingle
    ForeColor: White
    TextAlign: MiddleLeft
    Label Tag Number:    
    TextBox   txtTagNumber  
    Label Car Condition:    
    ComboBox   cbxCarConditions Sorted: True
    Items:
    Needs Repair
    Drivable
    Excellent
    Label Make:    
    TextBox   txtMake  
    Label Model:    
    TextBox   txtModel  
    Label Year:    
    TextBox   txtCarYear  
    label Tank Level:    
    ComboBox   cbxTankLevels Empty
    1/4 Empty
    1/2 Full
    3/4 Full
    Full
    Label Mileage Start:    
    TextBox   txtMileageStart TextAlign: Right
    Label Mileage End:    
    TextBox   txtMileageEnd TextAlign: Right
    Label Order Timing   AutoSize: False
    BackColor: Gray
    BorderStyle: FixedSingle
    ForeColor: White
    TextAlign: MiddleLeft
    Label Start Date:    
    DateTimePicker   dtpStartDate  
    Label End Date:    
    DateTimePicker   dtpEndDate  
    Label Days:    
    TextBox 0 txtDays TextAlign: Right
    Label Order Status    
    ComboBox   cbxOrderStatus Items:
    Car On Road
    Car Returned
    Order Reserved
    Label Order Evaluation   AutoSize: False
    BackColor: Gray
    BorderStyle: FixedSingle
    ForeColor: White
    TextAlign: MiddleLeft
    Label Rate Applied:    
    TextBox 0.00 txtRateApplied TextAlign: Right
    Button Rental Rates btnRentalRates  
    Label Sub-Total:    
    TextBox 0.00 txtSubTotal TextAlign: Right
    Button Calculate btnCalculate  
    Label Tax Rate:    
    TextBox 7.75 txtTaxRate TextAlign: Right
    Label %    
    Button Save btnSave  
    Label Tax Amount:    
    TextBox 0.00 txtTaxAmount TextAlign: Right
    Button Print... btnPrint  
    Label Order Total:    
    TextBox 0.00 txtOrderTotal TextAlign: Right
    Button Print Preview... btnPrintPreview  
    Label Receipt #:    
    TextBox 0 txtReceiptNumber  
    Button Open btnOpen  
    Button New Rental Order/Reset btnNewRentalOrder  
    Button Close btnClose  
  49. On to the Order Processing form, double-click the Start Date date time picker control
  50. Implement the event as follows:
     
    private void dtpStartDate_ValueChanged(object sender, EventArgs e)
    {
        dtpEndDate.Value = dtpStartDate.Value;
    }
  51. Return to the Order Processing form and double-click the End Date control
  52. Implement its Click event as follows:
     
    // This event approximately evaluates the number of days as a
    // difference between the end date and the starting date
    private void dtpEndDate_ValueChanged(object sender, EventArgs e)
    {
        int days;
    
        DateTime dteStart = this.dtpStartDate.Value;
        DateTime dteEnd = this.dtpEndDate.Value;
    
        // Let's calculate the difference in days
        TimeSpan tme = dteEnd - dteStart;
        days = tme.Days;
    
        // If the customer returns the car the same day, 
        // we consider that the car was rented for 1 day
        if (days == 0)
            days = 1;
    
        txtDays.Text = days.ToString();
        // At any case, we will let the clerk specify the actual number of days
    }
  53. Return to the Order Processing form and double-click the Rental Rates button
  54. Implement its event as follows:
     
    private void btnRentalRates_Click(object sender, EventArgs e)
    {
        RentalRates wndRates = new RentalRates();
        wndRates.Show();
    }
  55. Return to the Order Processing form and double-click the Calculate button
  56. Implement its event as follows:
     
    private void btnCalculate_Click(object sender, EventArgs e)
    {
        int    Days = 0;
        double RateApplied = 0.00;
        double SubTotal = 0.00;
        double TaxRate = 0.00;
        double TaxAmount = 0.00;
        double OrderTotal = 0.00;
    
        try
        {
            Days = int.Parse(this.txtDays.Text);
        }
        catch (FormatException)
        {
            MessageBox.Show("Invalid Number of Days");
        }
    
        try
        {
            RateApplied = double.Parse(txtRateApplied.Text);
        }
        catch (FormatException)
        {
            MessageBox.Show("Invalid Amount for Rate Applied");
        }
    
        SubTotal = Days * RateApplied;
        txtSubTotal.Text = SubTotal.ToString("F");
    
        try
        {
            TaxRate = double.Parse(txtTaxRate.Text);
        }
        catch (FormatException)
        {
            MessageBox.Show("Invalid Tax Rate");
        }
    
        TaxAmount = SubTotal * TaxRate / 100;
        txtTaxAmount.Text = TaxAmount.ToString("F");
    
        OrderTotal = SubTotal + TaxAmount;
        txtOrderTotal.Text = OrderTotal.ToString("F");
    }
  57. Return to the Order Processing form
  58. From the Printing section of the Toolbox, click PrintDocument and click the form
  59. In the Properties window, set its (Name) to docPrint and press Enter
  60. Under the form, double-click docPrint and implement its event as follows:
     
    private void docPrint_PrintPage(object sender,
    	System.Drawing.Printing.PrintPageEventArgs e)
    {
        e.Graphics.DrawLine(new Pen(Color.Black, 2), 80, 90, 750, 90);
        e.Graphics.DrawLine(new Pen(Color.Black, 1), 80, 93, 750, 93);
    
        string strDisplay = "Bethesda Car Rental";
        System.Drawing.Font fntString = new Font("Times New Roman", 28,
                            FontStyle.Bold);
        e.Graphics.DrawString(strDisplay, fntString,
                            Brushes.Black, 240, 100);
    
        strDisplay = "Car Rental Order";
        fntString = new System.Drawing.Font("Times New Roman", 22,
                            FontStyle.Regular);
        e.Graphics.DrawString(strDisplay, fntString,
                            Brushes.Black, 320, 150);
    
        e.Graphics.DrawLine(new Pen(Color.Black, 1), 80, 187, 750, 187);
        e.Graphics.DrawLine(new Pen(Color.Black, 2), 80, 190, 750, 190);
    
        fntString = new System.Drawing.Font("Times New Roman", 12,
                    FontStyle.Bold);
        e.Graphics.DrawString("Receipt #:  ", fntString,
                    Brushes.Black, 100, 220);
        fntString = new System.Drawing.Font("Times New Roman", 12,
                    FontStyle.Regular);
        e.Graphics.DrawString(txtReceiptNumber.Text, fntString,
                                      Brushes.Black, 260, 220);
        e.Graphics.DrawLine(new Pen(Color.Black, 1), 100, 240, 380, 240);
    
        fntString = new System.Drawing.Font("Times New Roman", 12,
                    FontStyle.Bold);
        e.Graphics.DrawString("Processed By:  ", fntString,
                    Brushes.Black, 420, 220);
        fntString = new System.Drawing.Font("Times New Roman", 12,
                    FontStyle.Regular);
        e.Graphics.DrawString(txtEmployeeName.Text, fntString,
                                      Brushes.Black, 550, 220);
        e.Graphics.DrawLine(new Pen(Color.Black, 1), 420, 240, 720, 240);
    
        fntString = new Font("Times New Roman", 12, FontStyle.Bold);
    
        e.Graphics.FillRectangle(Brushes.Gray,
    			 new Rectangle(100, 260, 620, 20));
        e.Graphics.DrawRectangle(Pens.Black,
    			 new Rectangle(100, 260, 620, 20));
    
        e.Graphics.DrawString("Customer", fntString,
                                      Brushes.White, 100, 260);
    
        fntString = new Font("Times New Roman", 12, FontStyle.Bold);
        e.Graphics.DrawString("Driver's License #: ", fntString,
                                      Brushes.Black, 100, 300);
        e.Graphics.DrawString("Name: ", fntString,
                                     Brushes.Black, 420, 300);
        fntString = new Font("Times New Roman", 12, FontStyle.Regular);
        e.Graphics.DrawString(txtDrvLicNumber.Text, fntString,
                                      Brushes.Black, 260, 300);
        e.Graphics.DrawString(txtCustomerName.Text, fntString,
                                      Brushes.Black, 540, 300);
        e.Graphics.DrawLine(new Pen(Color.Black, 1), 100, 320, 720, 320);
    
        fntString = new Font("Times New Roman", 12, FontStyle.Bold);
        e.Graphics.DrawString("Address: ", fntString,
                                      Brushes.Black, 100, 330);
        fntString = new Font("Times New Roman", 12, FontStyle.Regular);
        e.Graphics.DrawString(txtCustomerAddress.Text, fntString,
                                      Brushes.Black, 260, 330);
        e.Graphics.DrawLine(new Pen(Color.Black, 1), 100, 350, 720, 350);
    
        strDisplay = txtCustomerCity.Text + " " +
                             cbxCustomerStates.Text + " " +
                             txtCustomerZIPCode.Text;
        fntString = new System.Drawing.Font("Times New Roman",
     		12, FontStyle.Regular);
        e.Graphics.DrawString(strDisplay, fntString,
                                      Brushes.Black, 260, 360);
        e.Graphics.DrawLine(new Pen(Color.Black, 1), 260, 380, 720, 380);
    
        fntString = new Font("Times New Roman", 12, FontStyle.Bold);
    
        e.Graphics.FillRectangle(Brushes.Gray,
    		new Rectangle(100, 410, 620, 20));
        e.Graphics.DrawRectangle(Pens.Black,
    		new Rectangle(100, 410, 620, 20));
    
        e.Graphics.DrawString("Car Information", fntString,
                                      Brushes.White, 100, 410);
    
        fntString = new Font("Times New Roman", 12, FontStyle.Bold);
        e.Graphics.DrawString("Tag #: ", fntString,
                                      Brushes.Black, 100, 450);
        fntString = new Font("Times New Roman", 12, FontStyle.Regular);
        e.Graphics.DrawString(txtTagNumber.Text, fntString,
                                      Brushes.Black, 260, 450);
        e.Graphics.DrawLine(new Pen(Color.Black, 1), 100, 470, 380, 470);
    
        fntString = new Font("Times New Roman", 12, FontStyle.Bold);
        e.Graphics.DrawString("Year: ", fntString,
                                      Brushes.Black, 420, 450);
        fntString = new Font("Times New Roman", 12, FontStyle.Regular);
        e.Graphics.DrawString(txtCarYear.Text, fntString,
                                      Brushes.Black, 530, 450);
        e.Graphics.DrawLine(new Pen(Color.Black, 1), 420, 470, 720, 470);
    
        fntString = new Font("Times New Roman", 12, FontStyle.Bold);
        e.Graphics.DrawString("Make: ", fntString,
                                      Brushes.Black, 100, 480);
        fntString = new Font("Times New Roman", 12, FontStyle.Regular);
        e.Graphics.DrawString(txtMake.Text, fntString,
                                      Brushes.Black, 260, 480);
        e.Graphics.DrawLine(new Pen(Color.Black, 1), 100, 500, 380, 500);
    
        fntString = new Font("Times New Roman", 12, FontStyle.Bold);
        e.Graphics.DrawString("Model: ", fntString,
                                      Brushes.Black, 420, 480);
        fntString = new Font("Times New Roman", 12, FontStyle.Regular);
        e.Graphics.DrawString(txtModel.Text, fntString,
                                      Brushes.Black, 530, 480);
        e.Graphics.DrawLine(new Pen(Color.Black, 1), 420, 500, 720, 500);
    
        fntString = new Font("Times New Roman", 12, FontStyle.Bold);
        e.Graphics.DrawString("Car Condition: ", fntString,
                                      Brushes.Black, 100, 510);
        fntString = new Font("Times New Roman", 12, FontStyle.Regular);
        e.Graphics.DrawString(cbxCarConditions.Text, fntString,
                                      Brushes.Black, 260, 510);
        e.Graphics.DrawLine(new Pen(Color.Black, 1), 100, 530, 380, 530);
    
        fntString = new Font("Times New Roman", 12, FontStyle.Bold);
        e.Graphics.DrawString("Tank Level: ", fntString,
                                      Brushes.Black, 420, 510);
        fntString = new Font("Times New Roman", 12, FontStyle.Regular);
        e.Graphics.DrawString(cbxTankLevels.Text, fntString,
                                      Brushes.Black, 530, 510);
        e.Graphics.DrawLine(new Pen(Color.Black, 1), 420, 530, 720, 530);
    
        fntString = new Font("Times New Roman", 12, FontStyle.Bold);
        e.Graphics.DrawString("Mileage Start:", fntString,
                                      Brushes.Black, 100, 540);
        fntString = new Font("Times New Roman", 12, FontStyle.Regular);
        e.Graphics.DrawString(txtMileageStart.Text, fntString,
                                      Brushes.Black, 260, 540);
        e.Graphics.DrawLine(new Pen(Color.Black, 1), 
    				100, 560, 380, 560);
    
        fntString = new Font("Times New Roman", 12, FontStyle.Bold);
        e.Graphics.DrawString("Mileage End:", fntString,
                              Brushes.Black, 420, 540);
        fntString = new Font("Times New Roman", 12, FontStyle.Regular);
        e.Graphics.DrawString(txtMileageEnd.Text, fntString,
                              Brushes.Black, 530, 540);
        e.Graphics.DrawLine(new Pen(Color.Black, 1),
    			420, 560, 720, 560);
    
        e.Graphics.FillRectangle(Brushes.Gray,
    			 new Rectangle(100, 590, 620, 20));
        e.Graphics.DrawRectangle(Pens.Black,
    			 new Rectangle(100, 590, 620, 20));
    
        fntString = new Font("Times New Roman", 12, FontStyle.Bold);
        e.Graphics.DrawString("Order Timing Information", fntString,
                              Brushes.White, 100, 590);
    
        fntString = new Font("Times New Roman", 12, FontStyle.Bold);
        e.Graphics.DrawString("Start Date:", fntString,
                               Brushes.Black, 100, 620);
        fntString = new Font("Times New Roman", 12, FontStyle.Regular);
        e.Graphics.DrawString(dtpStartDate.Value.ToString("D"),
    			  fntString, Brushes.Black, 260, 620);
        e.Graphics.DrawLine(new Pen(Color.Black, 1),
    			100, 640, 720, 640);
    
        fntString = new Font("Times New Roman", 12, FontStyle.Bold);
        e.Graphics.DrawString("End Date:", fntString,
                              Brushes.Black, 100, 650);
        fntString = new Font("Times New Roman", 12, FontStyle.Regular);
        e.Graphics.DrawString(dtpEndDate.Value.ToString("D"), fntString,
                              Brushes.Black, 260, 650);
        e.Graphics.DrawLine(new Pen(Color.Black, 1),
    			100, 670, 520, 670);
    
        fntString = new Font("Times New Roman", 12, FontStyle.Bold);
        e.Graphics.DrawString("Days:", fntString,
                              Brushes.Black, 550, 650);
        fntString = new Font("Times New Roman", 12, FontStyle.Regular);
        e.Graphics.DrawString(txtDays.Text, fntString,
                                      Brushes.Black, 640, 650);
        e.Graphics.DrawLine(new Pen(Color.Black, 1),
    			550, 670, 720, 670);
    
        e.Graphics.FillRectangle(Brushes.Gray,
    			new Rectangle(100, 700, 620, 20));
        e.Graphics.DrawRectangle(Pens.Black,
    			 new Rectangle(100, 700, 620, 20));
    
        fntString = new Font("Times New Roman", 12, FontStyle.Bold);
        e.Graphics.DrawString("Order Evaluation", fntString,
                              Brushes.White, 100, 700);
    
        StringFormat fmtString = new StringFormat();
        fmtString.Alignment = StringAlignment.Far;
    
        fntString = new Font("Times New Roman", 12, FontStyle.Bold);
        e.Graphics.DrawString("Rate Applied:", fntString,
                              Brushes.Black, 100, 740);
        fntString = new Font("Times New Roman", 12, FontStyle.Regular);
        e.Graphics.DrawString(txtRateApplied.Text, fntString,
                              Brushes.Black, 300, 740, fmtString);
        e.Graphics.DrawLine(new Pen(Color.Black, 1),
    			100, 760, 380, 760);
    
        fntString = new Font("Times New Roman", 12, FontStyle.Bold);
        e.Graphics.DrawString("Tax Rate:", fntString,
                              Brushes.Black, 420, 740);
        fntString = new Font("Times New Roman", 12, FontStyle.Regular);
        e.Graphics.DrawString(txtTaxRate.Text, fntString,
                              Brushes.Black, 640, 740, fmtString);
        e.Graphics.DrawString("%", fntString,
                              Brushes.Black, 640, 740);
        e.Graphics.DrawLine(new Pen(Color.Black, 1),
    			420, 760, 720, 760);
    
        fntString = new Font("Times New Roman", 12, FontStyle.Bold);
        e.Graphics.DrawString("Sub-Total:", fntString,
                              Brushes.Black, 100, 770);
        fntString = new Font("Times New Roman", 12, FontStyle.Regular);
        e.Graphics.DrawString(txtSubTotal.Text, fntString,
                              Brushes.Black, 300, 770, fmtString);
        e.Graphics.DrawLine(new Pen(Color.Black, 1),
    			100, 790, 380, 790);
    
        fntString = new Font("Times New Roman", 12, FontStyle.Bold);
        e.Graphics.DrawString("Tax Amount:", fntString,
                                      Brushes.Black, 420, 770);
        fntString = new Font("Times New Roman", 12, FontStyle.Regular);
        e.Graphics.DrawString(txtTaxAmount.Text, fntString,
                              Brushes.Black, 640, 770, fmtString);
        e.Graphics.DrawLine(new Pen(Color.Black, 1),
    			420, 790, 720, 790);
    
        fntString = new Font("Times New Roman", 12, FontStyle.Bold);
        e.Graphics.DrawString("Order Total:", fntString,
                                      Brushes.Black, 420, 800);
        fntString = new Font("Times New Roman", 12, FontStyle.Regular);
        e.Graphics.DrawString(txtOrderTotal.Text, fntString,
                              Brushes.Black, 640, 800, fmtString);
        e.Graphics.DrawLine(new Pen(Color.Black, 1),
    			420, 820, 720, 820);
    }
  61. Return to the Order Processing form
  62. From the Printing section of the Toolbox, click PrintDialog and click the form
  63. In the Properties window, change its Name to dlgPrint
  64. Still in the Properties windows, set its Document property to docPrint
  65. On the Order Processing form, double-click the Print button and implement its event as follows:
     
    private void btnPrint_Click(object sender, EventArgs e)
    {
        if (dlgPrint.ShowDialog() == DialogResult.OK)
            docPrint.Print();
    }
  66. Return to the Order Processing form
  67. From the Printing section of the Toolbox, click PrintPreviewDialog and click the form
  68. In the Properties window, change its (Name) to dlgPrintPreview
  69. Still in the Properties windows, set its Document property to docPrint
  70. On the Order Processing form, double-click the Print Preview button
  71. Implement the event as follows:
     
    private void btnPrintPreview_Click(object sender, EventArgs e)
    {
        dlgPrintPreview.ShowDialog();
    }
  72. In the Solution Explorer, right-click Form1.cs and click Rename
  73. Type Central.cs and press Enter twice
  74. Design the form as follows:
     
    Control Text Name
    Button Customers &Rental Orders btnRentalOrders
    Button C&ars btnCars
    Button &Employees btnEmployees
    Button &Customers btnCustomers
    Button C&lose btnClose
  75. Double-click the Rental Orders button and implement its event as follows:
     
    private void btnRentalOrders_Click(object sender, EventArgs e)
    {
        OrderProcessing dlgOrder = new OrderProcessing();
        dlgOrder.ShowDialog();
    }
  76. Return to the Central form
  77. Double-click the Cars button and implement its event as follows:
     
    private void btnCars_Click(object sender, EventArgs e)
    {
        CarEditor dlgCars = new CarEditor();
        dlgCars.ShowDialog();
    }
  78. Return to the Central form
  79. Double-click the Employees button and implement its event as follows:
     
    private void btnEmployees_Click(object sender, EventArgs e)
    {
        Employees dlgEmployees = new Employees();
        dlgEmployees.ShowDialog();
    }
  80. Return to the Central form
  81. Double-click the Customers button and implement its event as follows:
     
    private void btnCustomers_Click(object sender, EventArgs e)
    {
        Customers dlgCustomers = new Customers();
        dlgCustomers.ShowDialog();
    }
  82. Return to the Central form
  83. Double-click the Close button and implement its event as follows:
     
    private void btnClose_Click(object sender, EventArgs e)
    {
        Close();
    }
  84. Save all

Creating a Dictionary-Based Collection Class

To support dictionary-based lists, the .NET Framework provides support for dictionary-based collection through two classes: Hashtable and SortedList. Both classes implement:

  • the IDictionary: This makes it possible to use the DictionaryEntry class to access a key/value item
  • the ICollection: This makes it possible to know the number of items in the list
  • the IEnumerable: This makes it possible to use the foreach loop to enumerate the members of the list
  • and the ICloneable interfaces.

Practical LearningPractical Learning: Creating a Dictionary Variable

  1. Access the CarEditor form and double-click an unoccupied area of its body
  2. Implement the Load event as follows:
     
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.IO;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace BethesdaCarRental1a
    {
        public partial class CarEditor : Form
        {
            Dictionary<string, Car> lstCars;
    
            public CarEditor()
            {
                InitializeComponent();
            }
    
            private void btnSelectPicture_Click(object sender, EventArgs e)
            {
                if (dlgPicture.ShowDialog() == DialogResult.OK)
                {
                    lblPictureName.Text = dlgPicture.FileName;
                    pbxCar.Image = Image.FromFile(lblPictureName.Text);
                }
            }
    
            private void CarEditor_Load(object sender, EventArgs e)
            {
                Car vehicle = new Car();
                BinaryFormatter bfmCars = new BinaryFormatter();
    
                // This is the file that holds the list of items
                string FileName = @"C:\Bethesda Car Rental\Cars.crs";
                lblPictureName.Text = ".";
    
                if (File.Exists(FileName))
                {
                    FileStream stmCars = new FileStream(FileName,
                                                        FileMode.Open,
                                                        FileAccess.Read,
                                                        FileShare.Read);
                    try
                    {
                        // Retrieve the list of cars
                        lstCars  =
    		 (Dictionary<string, Car>)bfmCars.Deserialize(stmCars);
                    }
                    finally
                    {
                        stmCars.Close();
                    }
                }
                else
                    lstCars = new Dictionary<string, Car>();
            }
        }
    }
  3. Display the Order Processing form
  4. Right-click the Order Processing form and click View Code
  5. Make the following changes:
     
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.IO;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace BethesdaCarRental1a
    {
        public partial class RentalOrders : Form
        {
            int ReceiptNumber;
            SortedList<int, RentalOrder> lstRentalOrders;
    
            public RentalOrders()
            {
                InitializeComponent();
            }
    
    	. . . No Change
        }
    }
  6. Save all

Adding Items to the Collection

To add an item to the list, you can call the Add() method. The syntax of the System.Collections.Hashtable.Add() and the System.Collections.SortedList.Add() methods is:

public virtual void Add(object Key, object Value);

The syntax of the System.Collections.Generic.Dictionary.Add(), the System.Collections.Generic.SortedDictionary.Add(), and the System.Collections.Generic.SortedList.Add() method is:

public void Add(TKey key, TValue value);

As you can see, you must provide the key and the value as the first and second arguments to the method respectively.

Practical LearningPractical Learning: Adding Items to the Collection

  1. Display the CarEditor form
  2. On the CarEditor form, double-click the Submit button and implement its Click event as follows:
     
    private void btnSubmit_Click(object sender, EventArgs e)
    {
        Car vehicle = new Car();
        FileStream stmCars = null;
        BinaryFormatter bfmCars = new BinaryFormatter();
        Directory.CreateDirectory(@"C:\Bethesda Car Rental");
        string strFilename = @"C:\Bethesda Car Rental\Cars.crs";
    
        if (txtTagNumber.Text.Length == 0)
        {
            MessageBox.Show("You must enter the car's tag number");
            return;
        }
    
        if (txtMake.Text.Length == 0)
        {
            MessageBox.Show("You must specify the car's manufacturer");
            return;
        }
    
        if (txtModel.Text.Length == 0)
        {
            MessageBox.Show("You must enter the model of the car");
            return;
        }
    
        if (txtYear.Text.Length == 0)
        {
            MessageBox.Show("You must enter the year of the car");
            return;
        }
    
        // Create a car
        vehicle.Make = txtMake.Text;
        vehicle.Model = txtModel.Text;
        vehicle.Year = int.Parse(txtYear.Text);
        vehicle.Category = cbxCategories.Text;
        vehicle.HasCDPlayer = chkCDPlayer.Checked;
        vehicle.HasDVDPlayer = chkDVDPlayer.Checked;
        vehicle.IsAvailable = chkAvailable.Checked;
    
        // Call the Add method of our collection class to add the car
        lstCars.Add(txtTagNumber.Text, vehicle);
    
        // Save the list
        stmCars = new FileStream(strFilename,
                                 FileMode.Create,
                                 FileAccess.Write,
                                 FileShare.Write);
    
        try
        {
            bfmCars.Serialize(stmCars, lstCars);
    
            if (lblPictureName.Text.Length != 0)
            {
                FileInfo flePicture = new FileInfo(lblPictureName.Text);
                flePicture.CopyTo(@"C:\Bethesda Car Rental\" +
                                  txtTagNumber.Text +
                                  flePicture.Extension);
            }
    
            txtTagNumber.Text = "";
            txtMake.Text = "";
            txtModel.Text = "";
            txtYear.Text = "";
            cbxCategories.Text = "Economy";
            chkCDPlayer.Checked = false;
            chkDVDPlayer.Checked = false;
            chkAvailable.Checked = false;
            lblPictureName.Text = ".";
            pbxCar.Image = null;
        }
        finally
        {
            stmCars.Close();
        }
    }
  3. Display the Customers form and double-click an unoccupied area of its body
  4. Change the file as follows:
     
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.IO;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace BethesdaCarRental1a
    {
        public partial class Customers : Form
        {
            Dictionary<string, Customer> lstCustomers;
    
            public Customers()
            {
                InitializeComponent();
            }
    
            internal void ShowCustomers()
            {
            }
    
            private void Customers_Load(object sender, EventArgs e)
            {
                lstCustomers = new Dictionary<string, Customer>();
                BinaryFormatter bfmCustomers = new BinaryFormatter();
    
                // This is the file that holds the list of parts
                string strFilename = @"C:\Bethesda Car Rental\Customers.crc";
    
                if (File.Exists(strFilename))
                {
                    FileStream stmCustomers = new FileStream(strFilename,
                                                             FileMode.Open,
                                                             FileAccess.Read,
                                                             FileShare.Read);
    
                    try
                    {
                        // Retrieve the list of employees from file
                        lstCustomers =
                (Dictionary<string,
                         Customer>)
                    bfmCustomers.Deserialize(stmCustomers);
                    }
                    finally
                    {
                        stmCustomers.Close();
                    }
                }
    
                ShowCustomers();
            }
        }
    }
  5. Return to the Customers form and double-click the New Customer button
  6. Implement its event as follows:
     
    private void btnNewCustomer_Click(object sender, EventArgs e)
    {
        CustomerEditor editor = new CustomerEditor();
        Directory.CreateDirectory(@"C:\Bethesda Car Rental");
    
        if (editor.ShowDialog() == DialogResult.OK)
        {
            if (editor.txtDrvLicNbr.Text == "")
            {
                MessageBox.Show("You must provide the driver's " +
                                "license number of the customer");
                return;
            }
    
            if (editor.txtFullName.Text == "")
            {
                MessageBox.Show("You must provide the employee's full name");
                return;
            }
    
            string strFilename = @"C:\Bethesda Car Rental\Customers.crc";
    
            Customer cust = new Customer();
    
            cust.FullName = editor.txtFullName.Text;
            cust.Address = editor.txtAddress.Text;
            cust.City = editor.txtCity.Text;
            cust.State = editor.cbxStates.Text;
            cust.ZIPCode = editor.txtZIPCode.Text;
            lstCustomers.Add(editor.txtDrvLicNbr.Text, cust);
    
            FileStream bcrStream = new FileStream(strFilename,
                                                  FileMode.Create,
                                                  FileAccess.Write,
                                                  FileShare.Write);
            BinaryFormatter bcrBinary = new BinaryFormatter();
            bcrBinary.Serialize(bcrStream, lstCustomers);
            bcrStream.Close();
    
            ShowCustomers();
        }
    }
  7. Display the Employees form and double-click an unoccupied area of its body
  8. Change the file as follows:
     
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.IO;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace BethesdaCarRental1a
    {
        public partial class Employees : Form
        {
            SortedDictionary<string, Employee> lstEmployees;
    
            public Employees()
            {
                InitializeComponent();
            }
    
            internal void ShowEmployees()
            {
            }
    
            private void Employees_Load(object sender, EventArgs e)
            {
                lstEmployees = new SortedDictionary<string, Employee>();
                BinaryFormatter bfmEmployees = new BinaryFormatter();
    
                // This is the file that holds the list of parts
                string strFilename = @"C:\Bethesda Car Rental\Employees.cre";
    
                if (File.Exists(strFilename))
                {
                    FileStream stmEmployees = new FileStream(strFilename,
                                                             FileMode.Open,
                                                             FileAccess.Read,
                                                             FileShare.Read);
    
                    try
                    {
                        // Retrieve the list of employees from file
                        lstEmployees =
    			(SortedDictionary<string,
    					 Employee>)
    				bfmEmployees.Deserialize(stmEmployees);
                    }
                    finally
                    {
                        stmEmployees.Close();
                    }
                }
    
                ShowEmployees();
            }
        }
    }
  9. Return to the Employees form and double-click the New Employee button
  10. Implement its event as follows:
     
    private void btnNewEmployee_Click(object sender, EventArgs e)
    {
        EmployeeEditor editor = new EmployeeEditor();
        Directory.CreateDirectory(@"C:\Bethesda Car Rental");
    
        if (editor.ShowDialog() == DialogResult.OK)
        {
            if (editor.txtEmployeeNumber.Text == "")
            {
                MessageBox.Show("You must provide an employee number");
                return;
            }
    
            if (editor.txtLastName.Text == "")
            {
                MessageBox.Show("You must provide the employee's last name");
                return;
            }
    
            string strFilename = @"C:\Bethesda Car Rental\Employees.cre";
    
            Employee empl = new Employee();
    
            empl.FirstName = editor.txtFirstName.Text;
            empl.LastName = editor.txtLastName.Text;
            empl.Title = editor.txtTitle.Text;
            empl.HourlySalary = double.Parse(editor.txtHourlySalary.Text);
            lstEmployees.Add(editor.txtEmployeeNumber.Text, empl);
    
            FileStream bcrStream = new FileStream(strFilename,
                                                  FileMode.Create,
                                                  FileAccess.Write,
                                                  FileShare.Write);
            BinaryFormatter bcrBinary = new BinaryFormatter();
            bcrBinary.Serialize(bcrStream, lstEmployees);
            bcrStream.Close();
    
            ShowEmployees();
        }
    }
  11. Save all

Accessing the Items of a Dictionary-Type of List

Although, or because, the key and value are distinct, to consider their combination as a single object, if you are using either the System.Collections.Hasthtable or the System.Collections.SortedList class, the .NET Framework provides the DictionaryEntry structure. To access an item, you can use the foreach loop to visit each item.

To support the foreach loop, the System.Collections.Hashtable and the System.Collections.SortedList classes implement the IEnumerable.GetEnumerator() method. In this case, the item is of type DictionaryEntry: it contains a Key and a Value in combination.

Practical LearningPractical Learning: Enumerating the Members of a Collection

  1. Display the Order Processing form
  2. On the form, click the Driver's Lic # text box
  3. In the Properties window, click the Events button and, in the Events section, double-click Leave
  4. Implement the event as follows:
     
    private void txtDrvLicNumber_Leave(object sender, EventArgs e)
    {
        Customer renter = null;
        string strDrvLicNumber = txtDrvLicNumber.Text;
    
        if (strDrvLicNumber.Length == 0)
        {
            MessageBox.Show("You must enter the renter's " +
                            "driver's license number");
            txtDrvLicNumber.Focus();
            return;
        }
    
        Dictionary<string, Customer>  lstCustomers =
                    new Dictionary<string, Customer>();
        BinaryFormatter bfmCustomers = new BinaryFormatter();
    
        string strFilename = @"C:\Bethesda Car Rental\Customers.crc";
    
        if (File.Exists(strFilename))
        {
             FileStream stmCustomers = new FileStream(strFilename,
                                                      FileMode.Open,
                                                      FileAccess.Read,
                                                      FileShare.Read);
    
            try
            {
                // Retrieve the list of customers
                lstCustomers =
                            (Dictionary<string, Customer>)
                                bfmCustomers.Deserialize(stmCustomers);
                if (lstCustomers.ContainsKey(strDrvLicNumber) == true)
                {
                    foreach (KeyValuePair<string, Customer> cust in lstCustomers)
                    {
    		    if (cust.Key == strDrvLicNumber)
                        {
                            renter = cust.Value;
                            txtCustomerName.Text = renter.FullName;
                            txtCustomerAddress.Text = renter.Address;
                            txtCustomerCity.Text = renter.City;
                            cbxCustomerStates.Text = renter.State;
                            txtCustomerZIPCode.Text = renter.ZIPCode;
                        }
    		}
                }
                else
                {
                    txtCustomerName.Text = "";
                    txtCustomerAddress.Text = "";
                    txtCustomerCity.Text = "";
                    cbxCustomerStates.Text = "";
                    txtCustomerZIPCode.Text = "";
                    MessageBox.Show("There is no customer with that driver's " +
                                    "license number in our database");
                    return;
                }
            }
            finally
            {
                stmCustomers.Close();
            }
        }
    }
  5. Access the Employees.cs file and implement the ShowEmployees() method as follows:
     
    internal void ShowEmployees()
    {
        if( lstEmployees.Count == 0)
            return;
    
        // Before displaying the employees, empty the list view
        lvwEmployees.Items.Clear();
        // This variable will allow us to identify the odd and even indexes
        int i = 1;
    
        // Use the KeyValuePair class to visit each key/value item
        foreach(KeyValuePair<string, Employee> kvp in lstEmployees )
        {
            ListViewItem lviEmployee = new ListViewItem(kvp.Key);
    
            Employee empl = kvp.Value;
    
            lviEmployee.SubItems.Add(empl.FirstName);
            lviEmployee.SubItems.Add(empl.LastName);
            lviEmployee.SubItems.Add(empl.FullName);
            lviEmployee.SubItems.Add(empl.Title);
            lviEmployee.SubItems.Add(empl.HourlySalary.ToString("F"));
    
            if( i % 2 == 0 )
            {
                lviEmployee.BackColor = Color.FromArgb(255, 128, 0);
                lviEmployee.ForeColor = Color.White;
            }
            else
            {
                lviEmployee.BackColor = Color.FromArgb(128, 64, 64);
                lviEmployee.ForeColor = Color.White;
            }
    
            lvwEmployees.Items.Add(lviEmployee);
    
            i++;
        }
    }
  6. Access the Customers.cs file and implement the ShowEmployees() method as follows:
     
    internal void ShowCustomers()
    {
        if (lstCustomers.Count == 0)
            return;
    
        lvwCustomers.Items.Clear();
        int i = 1;
    
        foreach (KeyValuePair<string, Customer> kvp in lstCustomers)
        {
            ListViewItem lviCustomer = new ListViewItem(kvp.Key);
    
            Customer cust = kvp.Value;
    
            lviCustomer.SubItems.Add(cust.FullName);
            lviCustomer.SubItems.Add(cust.Address);
            lviCustomer.SubItems.Add(cust.City);
            lviCustomer.SubItems.Add(cust.State);
            lviCustomer.SubItems.Add(cust.ZIPCode);
    
            if (i % 2 == 0)
            {
                lviCustomer.BackColor = Color.Navy;
                lviCustomer.ForeColor = Color.White;
            }
            else
            {
                lviCustomer.BackColor = Color.Blue;
                lviCustomer.ForeColor = Color.White;
            }
    
            lvwCustomers.Items.Add(lviCustomer);
    
            i++;
        }
    }
  7. Execute the application
  8. Click the Cars button and create the cars
     
    Bethesda Car Rental - Car Editor
  9. Close the Car Editor form
  10. Click the Customers button then click the New Customer button continually and create a few customers as follows:
     
    Driver's Lic. # State Full Name Address City ZIP Code
    M-505-862-575 MD Lynda Melman 4277 Jamison Avenue Silver Spring 20904
    379-82-7397 DC John Villard 108 Hacken Rd NE Washington 20012
    J-938-928-274 MD Chris Young 8522 Aulage Street Rockville 20852
    497-22-0614 PA Pamela Ulmreck 12075 Famina Rd Blain 17006
    922-71-8395 VA Helene Kapsco 806 Hyena Drive Alexandria 22231
    C-374-830-422 MD Hermine Crasson 6255 Old Georgia Ave Silver Spring 20910
    836-55-2279 NY Alan Pastore 4228 Talion Street Amherst 14228
    397-59-7487 TN Phillis Buster 724 Cranston Circle Knoxville 37919
    115-80-2957 FL Elmus Krazucki 808 Rasters Ave Orlando 32810
    294-90-7744 VA Helena Weniack 10448 Great Pollard Hwy Arlington 22232
  11. Close the Customers form
  12. On the Central form, click the Employees button
  13. Create a few employees as follows:
     
    Employee # First Name Last Name Title Hourly Salary
    62-845 Patricia Katts General Manager 42.25
    92-303 Henry Larson Sales Representative 12.50
    25-947 Gertrude Monay Sales Representative 14.05
    73-947 Helene Sandt Intern 8.85
    40-508 Melanie Karron Sales Representative 12.75
    22-580 Ernest Chisen Sales Manager 22.95
    20-308 Melissa Roberts Administrative Assistant 15.45
    Bethesda Car Rental: Employees
  14. Notice that the list of employees is automatically sorted based on the employees numbers.
    Close the forms and return to your programming environment

The Keys and the Values of a Collection

After adding one or more items to the list, they are stored in two collections. The keys are stored in a collection represented by a property named Keys. The values are stored in the Values property. In the System.Collections classes, the Keys and the Values properties are of type ICollection.

Practical LearningPractical Learning: Using the Keys of a Collection

  1. Display the Order Processing form and double-click the New Rental Order/Reset button
  2. Implement the event as follows:
     
    private void btnNewRentalOrder_Click(object sender, EventArgs e)
    {
        txtEmployeeNumber.Text = "";
        txtEmployeeName.Text = "";
        txtDrvLicNumber.Text = "";
        txtCustomerName.Text = "";
        txtCustomerAddress.Text = "";
        txtCustomerCity.Text = "";
        cbxCustomerStates.Text = "";
        txtCustomerZIPCode.Text = "";
        txtTagNumber.Text = "";
        cbxCarConditions.Text = "";
        txtMake.Text = "";
        txtModel.Text = "";
        txtCarYear.Text = "";
        cbxTankLevels.Text = "Empty";
        txtMileageStart.Text = "0";
        txtMileageEnd.Text = "0";
        dtpStartDate.Value = DateTime.Today;
        dtpEndDate.Value = DateTime.Today;
        txtDays.Text = "";
        cbxOrderStatus.Text = "";
        txtRateApplied.Text = "0.00";
        txtSubTotal.Text = "0.00";
        txtTaxRate.Text = "7.75";
        txtTaxAmount.Text = "0.00";
        txtOrderTotal.Text = "0.00";
    
        BinaryFormatter bfmRentalOrders = new BinaryFormatter();
    
        string strFilename = @"C:\Bethesda Car Rental\RentalOrders.cro";
    
        if (File.Exists(strFilename))
        {
            FileStream stmRentalOrders = new FileStream(strFilename,
                                                        FileMode.Open,
                                                        FileAccess.Read,
                                                        FileShare.Read);
    
            try
            {
                lstRentalOrders =
                    (SortedList<int, RentalOrder>)
                        bfmRentalOrders.Deserialize(stmRentalOrders);
                ReceiptNumber =
    		lstRentalOrders.Keys[lstRentalOrders.Count - 1] + 1;
            }
            finally
            {
                stmRentalOrders.Close();
            }
        }
        else
        {
            ReceiptNumber = 100001;
            lstRentalOrders = new SortedList<int, RentalOrder>();
        }
    
        txtReceiptNumber.Text = ReceiptNumber.ToString();
    }
  3. Return to the Order Processing form and double-click an unoccupied area of its body
  4. Implement the Load event as follows:
     
    private void OrderProcessing_Load(object sender, EventArgs e)
    {
        btnNewRentalOrder_Click(sender, e);
    }
  5. Return to the Order Processing form

Checking the Existence of an Item

Locating an item in a dictionary type of list consists of looking for either a key, a value, or a combination of Key=Value. The Hashtable, the Dictionary, and the SortedList classes are equipped to handle these operations with little effort on your part. If you know the key of an item but want to find a value, you can use the indexed property because it produces it.

Checking the Existence of a Key

We have seen that the System.Collections.Hashtable.Contains() and the System.Collections.SortedList.Contains() methods allow you to find out whether a collection contains a certain specific key. An alternative is to call a method named ContainsKey.

The syntax of the System.Collections.Hashtable.ContainsKey() and the System.Collections.SortedList.ContainsKey() method is:

public virtual bool ContainsKey(object key);

The syntax of the System.Collections.Generic.Dictionary.ContainsKey() and the System.Collections.Generic.SortedList.ContainsKey() method is:

public bool ContainsKey(TKey key);

Practical LearningPractical Learning: Checking the Existence of a Key

  1. On the Order Processing form, double-click the Save button and implement its event as follows:
     
    private void btnSave_Click(object sender, EventArgs e)
    {
        if (txtReceiptNumber.Text == "")
        {
            MessageBox.Show("The receipt number is missing");
            return;
        }
    
        // Don't save this rental order if we don't
        // know who processed it
        if (txtEmployeeNumber.Text == "")
        {
            MessageBox.Show("You must enter the employee number of the " +
                            "clerk who processed this order.");
            return;
        }
    
        // Don't save this rental order if we don't
        // know who is renting the car
        if (txtDrvLicNumber.Text == "")
        {
            MessageBox.Show("You must specify the driver's license number " +
                            "of the customer who is renting the car");
            return;
        }
    
        // Don't save the rental order if we don't
        // know what car is being rented
        if (txtTagNumber.Text == "")
        {
            MessageBox.Show("You must enter the tag number " +
                            "of the car that is being rented");
            return;
        }
    
        // Create a rental order based on the information on the form
        RentalOrder CurrentOrder = new RentalOrder();
    
        CurrentOrder.EmployeeNumber = txtEmployeeNumber.Text;
        CurrentOrder.OrderStatus = cbxOrderStatus.Text;
        CurrentOrder.CarTagNumber = txtTagNumber.Text;
        CurrentOrder.CustomerDrvLicNbr = txtDrvLicNumber.Text;
        CurrentOrder.CustomerName = txtCustomerName.Text;
        CurrentOrder.CustomerAddress = txtCustomerAddress.Text;
        CurrentOrder.CustomerCity = txtCustomerCity.Text;
        CurrentOrder.CustomerState = cbxCustomerStates.Text;
        CurrentOrder.CustomerZIPCode = txtCustomerZIPCode.Text;
        CurrentOrder.CarCondition = cbxCarConditions.Text;
        CurrentOrder.TankLevel = cbxTankLevels.Text;
    
        try
        {
            CurrentOrder.MileageStart = int.Parse(txtMileageStart.Text);
        }
        catch (FormatException)
        {
            MessageBox.Show("Invalid mileage start value");
        }
    
        try
        {
            CurrentOrder.MileageEnd = int.Parse(txtMileageEnd.Text);
        }
        catch (FormatException)
        {
            MessageBox.Show("Invalid mileage end value");
        }
    
        try
        {
            CurrentOrder.DateStart = dtpStartDate.Value;
        }
        catch (FormatException)
        {
            MessageBox.Show("Invalid start date");
        }
    
                try
                {
                    CurrentOrder.DateEnd = dtpEndDate.Value;
                }
                catch (FormatException)
                {
                    MessageBox.Show("Invalid end date");
                }
    
                try
                {
                    CurrentOrder.Days = int.Parse(txtDays.Text);
                }
                catch (FormatException)
                {
                    MessageBox.Show("Invalid number of days");
                }
    
                try
                {
                    CurrentOrder.RateApplied = double.Parse(txtRateApplied.Text);
                }
                catch (FormatException)
                {
                    MessageBox.Show("Invalid rate value");
                }
    
                CurrentOrder.SubTotal = double.Parse(txtSubTotal.Text);
    
                try
                {
                    CurrentOrder.TaxRate = double.Parse(txtTaxRate.Text);
                }
                catch (FormatException)
                {
                    MessageBox.Show("Inavlid tax rate");
                }
    
                CurrentOrder.TaxAmount = double.Parse(txtTaxAmount.Text);
                CurrentOrder.OrderTotal = double.Parse(txtOrderTotal.Text);
                // The rental order is ready
    
                // Get the receipt number from its text box
                try
                {
                    ReceiptNumber = int.Parse(txtReceiptNumber.Text);
                }
                catch (FormatException)
                {
                    MessageBox.Show("You must provide a receipt number");
                }
    
                // Get the list of rental orders and 
                // check if there is already one with the current receipt number
                // If there is already a receipt number like that...
                if (lstRentalOrders.ContainsKey(ReceiptNumber) == true)
                {
                    // Simply update its value
                    lstRentalOrders[ReceiptNumber] = CurrentOrder;
                }
                else
                {
                    // If there is no order with that receipt,
                    // then create a new rental order
                    lstRentalOrders.Add(ReceiptNumber, CurrentOrder);
                }
        
        // The list of rental orders
        string strFilename = @"C:\Bethesda Car Rental\RentalOrders.cro";
        FileStream bcrStream = new FileStream(strFilename,
                                              FileMode.Create,
                                              FileAccess.Write,
                                              FileShare.Write);
        BinaryFormatter bcrBinary = new BinaryFormatter();
    
        try
        {
            bcrBinary.Serialize(bcrStream, lstRentalOrders);
        }
        finally
        {
            bcrStream.Close();
        }
    }
  2. Save the file

Checking the Existence of a Value

To find out whether a particular value exists in the list, you can call the ContainsValue() method. The syntax of the System.Collections.Hashtable.ContainsValue() and the System.Collections.SortedList.ContainsValue() method is::

public virtual bool ContainsValue(object key);

The syntax of the System.Collections.Generic.Dictionary.ContainsValue() and the System.Collections.Generic.SortedList.ContainsValue() method is:

public bool ContainsValue(TKey key);

Practical LearningPractical Learning: Getting the Value of a Key

  1. On the Order Processing form, click the Employee Number text box
  2. In the Events section of the Properties window, double-click Leave and implement the event as follows:
     
    private void txtEmployeeNumber_Leave(object sender, EventArgs e)
    {
        Employee clerk;
        string strEmployeeNumber = txtEmployeeNumber.Text;
    
        if (strEmployeeNumber.Length == 0)
        {
            MessageBox.Show("You must enter the employee's number");
                    txtEmployeeNumber.Focus();
                    return;
        }
    
        SortedDictionary<string, Employee> lstEmployees =
                    new SortedDictionary<string, Employee>();
        BinaryFormatter bfmEmployees = new BinaryFormatter();
    
        string strFilename = @"C:\Bethesda Car Rental\Employees.cre";
    
        if (File.Exists(strFilename))
        {
            FileStream stmEmployees = new FileStream(strFilename,
                                                     FileMode.Open,
                                                     FileAccess.Read,
                                                     FileShare.Read);
            try
            {
               // Retrieve the list of employees
                lstEmployees =
                            (SortedDictionary<string, Employee>)
                                bfmEmployees.Deserialize(stmEmployees);
                if (lstEmployees.TryGetValue(strEmployeeNumber, out clerk))
                {
                    txtEmployeeName.Text = clerk.FullName;
                }
                else
                {
                    txtEmployeeName.Text = "";
                    MessageBox.Show("There is no employee with that number");
                    return;
                }
            }
            finally
            {
                stmEmployees.Close();
            }
        }
    }
  3. Return to the Order Processing form and click the Tag Number text box
  4. In the Events section of the Properties window, double-click Leave and implement the event as follows:
     
    private void txtTagNumber_Leave(object sender, EventArgs e)
    {
        Car selected;
        string strTagNumber = txtTagNumber.Text;
    
        if (strTagNumber.Length == 0)
        {
            MessageBox.Show("You must enter the car's tag number");
            txtTagNumber.Focus();
            return;
        }
    
        Dictionary<string, Car> lstCars =
                    new Dictionary<string, Car>();
        BinaryFormatter bfmCars = new BinaryFormatter();
    
        string strFilename = @"C:\Bethesda Car Rental\Cars.crs";
    
        if (File.Exists(strFilename))
        {
            FileStream stmCars = new FileStream(strFilename,
                                                FileMode.Open,
                                                FileAccess.Read,
                                                FileShare.Read);
            try
            {
                // Retrieve the list of employees from file
                lstCars =
                    (Dictionary<string, Car>)
                            bfmCars.Deserialize(stmCars);
                if (lstCars.TryGetValue(strTagNumber, out selected))
                {
                    txtMake.Text = selected.Make;
                    txtModel.Text = selected.Model;
                    txtCarYear.Text = selected.Year.ToString();
                }
                else
                {
                    txtMake.Text = "";
                    txtModel.Text = "";
                    txtCarYear.Text = "";
                    MessageBox.Show("There is no car with that tag " +
                                    "number in our database");
                    return;
                }
            }
            finally
            {
                stmCars.Close();
            }
        }
    }
  5. Display the Order Processing form and double-click the Open button
  6. Implement its event as follows:
      
    private void btnOpen_Click(object sender, EventArgs e)
    {
        RentalOrder order = null;
    
        if (txtReceiptNumber.Text == "")
        {
            MessageBox.Show("You must enter a receipt number");
            return;
        }
    
        ReceiptNumber = int.Parse( txtReceiptNumber.Text);
    
        if (lstRentalOrders.TryGetValue(ReceiptNumber, out order))
        {
            txtEmployeeNumber.Text = order.EmployeeNumber;
            txtEmployeeNumber_Leave(sender, e);
            cbxOrderStatus.Text = order.OrderStatus;
            txtTagNumber.Text = order.CarTagNumber;
            txtTagNumber_Leave(sender, e);
            txtDrvLicNumber.Text = order.CustomerDrvLicNbr;
            txtCustomerName.Text = order.CustomerName;
            txtCustomerAddress.Text = order.CustomerAddress;
            txtCustomerCity.Text = order.CustomerCity;
            cbxCustomerStates.Text = order.CustomerState;
            txtCustomerZIPCode.Text = order.CustomerZIPCode;
            cbxCarConditions.Text = order.CarCondition;
            cbxTankLevels.Text = order.TankLevel;
            txtMileageStart.Text = order.MileageStart.ToString();
            txtMileageEnd.Text = order.MileageEnd.ToString();
            dtpStartDate.Value = order.DateStart;
            dtpEndDate.Value = order.DateEnd;
            txtDays.Text = order.Days.ToString();
            txtRateApplied.Text = order.RateApplied.ToString("F");
            txtSubTotal.Text = order.SubTotal.ToString("F");
            txtTaxRate.Text = order.TaxRate.ToString("F");
            txtTaxAmount.Text = order.TaxAmount.ToString("F");
            txtOrderTotal.Text = order.OrderTotal.ToString("F");
        }
        else
        {
            MessageBox.Show("There is no rental order with that receipt number");
            return;
        }
    }
  7. Return to the Order Processing form
  8. Double-click the Close button and implement the event as follows:
     
    private void btnClose_Click(object sender, EventArgs e)
    {
        Close();
    }
  9. Execute the application
  10. Create a few rental orders and print them
     
    Bethesda Car Rental: Rental Order
  11. Close the forms and return to your programming environment
  12. Execute the application again
  13. Open a previously created order to simulate a customer returning a car and change some values on the form such as the return date, the mileage end, and the order status
  14. Also click the Calculate button to get the final evaluation
     
    Bethesda Car Rental: Rental Order
  15. Print the rental orders
  16. Close the forms and return to your programming environment

Download

 

Home Copyright © 2007-2012 FunctionX