Practical
Learning: Introducing Dictionary Collections
|
|
- Start Microsoft Visual C#
- Create a new Windows Application named BethesdaCarRental1
- To add a new form to the project, in the Solution Explorer, right-click
BethesdaCarRental1 -> Add -> Windows Form...
- Set the Name to RentalRates and press Enter
- 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 |
|
- 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 |
- Complete the design of the form as follows:

- To add a new form to the application, in the Solution Explorer, right-click
BethesdaCarRental1 -> Add -> Windows Form...
- Set the Name to Employees and click Add
- From the Toolbox, add a ListView to the form
- 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 |
- Design the form as follows:
 |
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 |
|
|
- To add another form to the application, in the Solution Explorer, right- click
BethesdaCarRental1
-> Add ->
Windows Form...
- Set the Name to EmployeeEditor and click Add
- Design the form as follows:
 |
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 |
|
- Click the Last Name text box
- In the Properties window, click the Events button and double-click Leave
- 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;
}
|
- To add a new class to the project, in the Class View, right- click
BethesdaCarRental1
-> Add -> Class...
- Set the Class Name to Employee and click Add
- 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;
}
}
}
|
- To add a new form to the application, on the main menu, click Project
-> Add Windows Forms
- Set the Name to Customers and press Enter
- From the Toolbox, add a ListView to the form
- 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 |
|
- Design the form as follows:
 |
Control |
Text |
Name |
Other Properties |
ListView |
|
lvwCustomers |
View: Details
GridLines: True
FullRowSelect: True |
Button |
New Customer... |
btnNewCustomer |
|
Button |
Close |
btnClose |
|
|
- To add another form to the application, on the main menu, click Project
-> Add Windows Forms
- Set the Name to CustomerEditor and click Add
- Design the form as follows:
 |
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 |
|
- To add a new class to the project, in the Class View, right-click
BethesdaCarRental1 -> Add -> Class...
- Set the Class Name to Customer and click Finish
- 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;
}
}
}
|
- Save all
- 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):
 |
 |
BMW: 335i |
Chevrolet Avalanche |
 |
 |
Honda Accord |
Mazda Miata |
 |
 |
Chevrolet Aveo |
Ford E150XL |
 |
 |
Buick Lacrosse |
Honda Civic |
 |
 |
Ford F-150 |
Mazda Mazda5 |
 |
 |
Volvo S40 |
Land Rover LR3 |
- Return to your programming environment
- To add a new form to the application, in the Solution Explorer, right-click
BethesdaCarRental1
-> Add -> Windows Forms
- Set the Name to CarEditor and click Add
- Design the form as follows:
 |
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 |
|
- 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);
}
}
|
- To add a new class to the project, in the Class View, right-click
BethedaCarRental1 -> Add -> Class...
- Set the Class Name to Car and click Add
- 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;
}
}
}
|
- To add a new class to the project, in the Class View, right-click
BethesdaCarRental -> Add -> Class...
- Set the Class Name to RentalOrder and press Enter
- 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()
{
}
}
}
|
- To add a new form to the project, in the Solution Explorer, right-click
BethesdaCarRenatl -> Add -> Windows Form...
- Set the Name to OrderProcessing and press Enter
- Design the form as follows:
 |
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 |
|
|
- On to the Order Processing form, double-click the Start Date date time picker control
- Implement the event as follows:
private void dtpStartDate_ValueChanged(object sender, EventArgs e)
{
dtpEndDate.Value = dtpStartDate.Value;
}
|
- Return to the Order Processing form and double-click the End Date control
- 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
}
|
- Return to the Order Processing form and double-click the Rental Rates button
- Implement its event as follows:
private void btnRentalRates_Click(object sender, EventArgs e)
{
RentalRates wndRates = new RentalRates();
wndRates.Show();
}
|
- Return to the Order Processing form and double-click the Calculate button
- 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");
}
|
- Return to the Order Processing form
- From the Printing section of the Toolbox, click PrintDocument and click
the form
- In the Properties window, set its (Name) to docPrint and press Enter
- 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);
}
|
- Return to the Order Processing form
- From the Printing section of the Toolbox, click PrintDialog and click the
form
- In the Properties window, change its Name to dlgPrint
- Still in the Properties windows, set its Document property to docPrint
- 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();
}
|
- Return to the Order Processing form
- From the Printing section of the Toolbox, click PrintPreviewDialog and
click the form
- In the Properties window, change its (Name) to dlgPrintPreview
- Still in the Properties windows, set its Document property to docPrint
- On the Order Processing form, double-click the Print Preview button
- Implement the event as follows:
private void btnPrintPreview_Click(object sender, EventArgs e)
{
dlgPrintPreview.ShowDialog();
}
|
- In the Solution Explorer, right-click Form1.cs and click Rename
- Type Central.cs and press Enter twice
- 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 |
|
- 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();
}
|
- Return to the Central form
- 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();
}
|
- Return to the Central form
- 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();
}
|
- Return to the Central form
- 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();
}
|
- Return to the Central form
- Double-click the Close button and implement its event as follows:
private void btnClose_Click(object sender, EventArgs e)
{
Close();
}
|
- 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
Learning: Creating a Dictionary Variable
|
|
- Access the CarEditor form and double-click an unoccupied area of its body
- 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>();
}
}
}
|
- Display the Order Processing form
- Right-click the Order Processing form and click View Code
- 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
}
}
|
- 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
Learning: Adding Items to the Collection
|
|
- Display the CarEditor form
- 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();
}
}
|
- Display the Customers form and double-click an unoccupied area of its body
- 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();
}
}
}
|
- Return to the Customers form and double-click the New Customer button
- 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();
}
}
|
- Display the Employees form and double-click an unoccupied area of its body
- 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();
}
}
}
|
- Return to the Employees form and double-click the New Employee button
- 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();
}
}
|
- 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
Learning: Enumerating the Members of a Collection
|
|
- Display the Order Processing form
- On the form, click the Driver's Lic # text box
- In the Properties window, click the Events button and, in the Events
section, double-click Leave
- 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();
}
}
}
|
- 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++;
}
}
|
- 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++;
}
}
|
- Execute the application
- Click the Cars button and create the
cars
- Close the Car Editor form
- 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 |
|
 |
- Close the Customers form
- On the Central form, click the Employees button
- 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 |
|
 |
- 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
Learning: Using the Keys of a Collection
|
|
- Display the Order Processing form and double-click the New Rental Order/Reset
button
- 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();
}
|
- Return to the Order Processing form and double-click an unoccupied area of
its body
- Implement the Load event as follows:
private void OrderProcessing_Load(object sender, EventArgs e)
{
btnNewRentalOrder_Click(sender, e);
}
|
- 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
Learning: Checking the Existence of a Key
|
|
- 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();
}
}
|
- 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
Learning: Getting the Value of a Key
|
|
- On the Order Processing form, click the Employee Number text box
- 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();
}
}
}
|
- Return to the Order Processing form and click the Tag Number text box
- 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();
}
}
}
|
- Display the Order Processing form and double-click the Open button
- 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;
}
}
|
- Return to the Order Processing form
- Double-click the Close button and implement the event as follows:
private void btnClose_Click(object sender, EventArgs e)
{
Close();
}
|
- Execute the application
- Create a few rental orders and print them
- Close the forms and return to your programming environment
- Execute the application again
- 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
- Also click the Calculate button to get the final evaluation
- Print the rental orders
- Close the forms and return to your programming environment
Download |
|