|
.NET Framwork Collections: The Collection Class |
|
Fundamentals of the Collection Class |
|
|
Besides the System.Collections and the
System.Collections.Generic namespaces, the .NET Framework
provides additional collection classes in various other namespaces. One of
those namespaces is System.Collections.ObjectModel. That
namespace provides techniques of creating collections that emanate from
other, existing, collections. For example, suppose you have a collection
already but have a particular scenario in which you want to use that
collection.
|
Instead of creating a new collection, you can simply
transfer the existing values to the new collection. To state it another way,
or to make it a little clearer, suppose you have a list of students whose
records must be passed to a review. You can create another list and transfer
the students records to that new list but block it, that is, make it
read-only so that whoever accesses those records cannot change them. As
another scenario, suppose you have a list of employees from one company that
is merging with another company, you can easily transfer the existing
employees records to a new list (for whatever reason) without creating a new
collection. You can then modify the new collection from the existing
records.
The System.Collections.ObjectModel
namespace provides (two) abstract classes and other additional classes. The
abstraction classes are named Collection and
KeyedCollection.
Practical Learning: Introducing the Collection Class
|
|
- Start Microsoft Visual C#
- To create a new application, on the main menu, click File -> New
Project
- In the middle list, click Windows Forms Application
- Change the Name to CeilInn2
- Click OK
- To create a new class, on the main menu, click Project -> Add
Class...
- Set the Name to Customer
- Click Add
- Change the file as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CeilInn2
{
[Serializable]
public class Customer
{
public string AccountNumber { get; set; }
public string FullName { get; set; }
public string PhoneNumber { get; set; }
public string EmergencyName { get; set; }
public string EmergencyPhone { get; set; }
public override bool Equals(object obj)
{
Customer client = (Customer)obj;
if (client.AccountNumber.Equals(this.AccountNumber))
return true;
else
return false;
}
}
}
- To create a new form, on the main menu, click Project -> Add Windows
Form...
- Set the name to CustomerEditor
- Click Add
- Design the form as follows:
|
Control |
(Name) |
Text |
Modifiers |
Other Properties |
Label |
|
|
Account Number: |
|
|
MaskTextBox |
|
txtAccountNumber |
|
Public |
Mask: 000-000 |
Label |
|
|
Full Name: |
|
|
TextBox |
|
txtFullName |
|
Public |
|
Label |
|
|
Phone Number: |
|
|
TextBox |
|
txtPhoneNumber |
|
Public |
|
Label |
|
|
Emergency Name: |
|
|
TextBox |
|
txtEmergencyName |
|
Public |
|
Label |
|
|
Emergency Phone: |
|
|
TextBox |
|
txtEmergencyPhone |
|
Public |
|
Button |
|
btnOK |
OK |
|
DialogResult: OK |
Button |
|
btnCancel |
Cancel |
|
DialogResult: Cancel |
|
Form |
FormBorderStyle: |
FixedDialog |
Text: |
Ceil Inn - Customer Editor |
StartPosition: |
CenterScreen |
AcceptButton: |
btnOK |
CancelButton: |
btnCancel |
MaximizeBox: |
False |
MinimizeBox: |
False |
ShowInTaskBar: |
False |
- To create a new class, on the main menu, click Project -> Add
Class...
- Set the Name to Employee
- Click Add
- Change the file as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CeilInn2
{
[Serializable]
public class Employee
{
public string EmployeeNumber { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Title { get; set; }
public override bool Equals(object obj)
{
Employee clerk = (Employee)obj;
if( clerk.EmployeeNumber.Equals(this.EmployeeNumber))
return true;
else
return false;
}
}
}
- To create a new form, on the main menu, click Project -> Add Windows
Form...
- Set the name to EmployeeEditor
- Click Add
- Design the form as follows:
|
Control |
(Name) |
Text |
Modifiers |
Other Properties |
Label |
|
|
Employee Number: |
|
|
MaskTextBox |
|
txtEmployeeNumber |
|
Public |
Mask: 00-000 |
Label |
|
|
First Name: |
|
|
TextBox |
|
txtFirstName |
|
Public |
|
Label |
|
|
Last Name: |
|
|
TextBox |
|
txtLastName |
|
Public |
|
Label |
|
|
Title: |
|
|
TextBox |
|
txtTitle |
|
Public |
|
Button |
|
btnOK |
OK |
|
DialogResult: OK |
Button |
|
btnCancel |
Cancel |
|
DialogResult: Cancel |
|
Form |
FormBorderStyle: |
FixedDialog |
Text: |
Ceil Inn - Employee Editor |
StartPosition: |
CenterScreen |
AcceptButton: |
btnOK |
CancelButton: |
btnCancel |
MaximizeBox: |
False |
MinimizeBox: |
False |
ShowInTaskBar: |
False |
- To create a new class, on the main menu, click Project -> Add
Class...
- Set the Name to Room
- Click Add
- Change the file as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CeilInn2
{
[Serializable]
public class Room
{
public string RoomNumber { get; set; }
public string RoomType { get; set; }
public string BedType { get; set; }
public double Rate { get; set; }
public bool Available { get; set; }
public override bool Equals(object obj)
{
Room rm = (Room)obj;
if (rm.RoomNumber == this.RoomNumber)
return true;
else
return false;
}
}
}
- To create a new form, on the main menu, click Project -> Add Windows
Form...
- Set the name to RoomEditor
- Click Add
- Design the form as follows:
|
Control |
(Name) |
Text |
Modifiers |
Other Properties |
Label |
|
|
Room Number: |
|
|
TextBox |
|
txtRoomNumber |
|
|
|
Label |
|
|
Room Type: |
|
|
ComboBox |
|
cbxRoomTypes |
|
Public |
Items: Bedroom Conference Room Other |
Label |
|
|
Bed Type: |
|
|
ComboBox |
|
cbxBedTypes |
|
Public |
Items: King Queen Double Other |
Label |
|
|
Rate: |
|
|
TextBox |
|
txtRate |
0.00 |
Public |
TextAlign: Right |
CheckBox |
|
chkAvailable |
Available |
Public |
CheckAlign: MiddleRight |
Button |
|
btnOK |
OK |
|
DialogResult: OK |
Button |
|
btnCancel |
Cancel |
|
DialogResult: Cancel |
|
Form |
FormBorderStyle: |
FixedDialog |
Text: |
Ceil Inn - Employee Editor |
StartPosition: |
CenterScreen |
AcceptButton: |
btnOK |
CancelButton: |
btnCancel |
MaximizeBox: |
False |
MinimizeBox: |
False |
ShowInTaskBar: |
False |
- To create a new class, on the main menu, click Project -> Add
Class...
- Set the Name to Occupancy
- Click Add
- Change the file as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CeilInn2
{
[Serializable]
public class Occupancy
{
public string OccupancyNumber { get; set; }
public DateTime DateOccupied { get; set; }
public string ProcessedBy { get; set; }
public string ProcessedFor { get; set; }
public string RoomOccupied { get; set; }
public double RateApplied { get; set; }
public double PhoneUse { get; set; }
public override bool Equals(object obj)
{
Occupancy rental = (Occupancy)obj;
if( rental.OccupancyNumber == this.OccupancyNumber)
return true;
else
return false;
}
}
}
- To create a new form, on the main menu, click Project -> Add Windows
Form...
- Set the name to OccupancyEditor
- Click Add
- Design the form as follows:
|
Control |
(Name) |
Text |
Modifiers |
Other Properties |
Label |
|
|
Date Occupied: |
|
|
DateTimePicker |
|
dtpDateOccupied |
|
Public |
|
Label |
|
|
Processed by ____ |
|
|
Label |
|
|
Employee #: |
|
|
MaskTextBox |
|
txtEmployeNumber |
|
Public |
Mask: 00-000 |
TextBox |
|
txtEmployeNme |
|
Public |
|
Label |
|
|
Processed for ___ |
|
|
Label |
|
|
Customer #: |
|
|
MaskTextBox |
|
txtCustomerNumber |
|
Public |
Mask: 000-000 |
TextBox |
|
txtCustomerName |
|
Public |
|
Label |
|
|
Room Rented ____ |
|
|
Label |
|
|
Room Number: |
|
|
ComboBox |
|
cbxRoomNumbers |
|
Public |
|
TextBox |
|
txtRoomDescription |
|
Public |
|
Label |
|
|
Rate Applied: |
|
|
TextBox |
|
txtRateApplied |
0.00 |
Public |
TextAlign: Right |
Label |
|
|
Phone Use: |
|
|
TextBox |
|
txtPhoneUse |
0.00 |
Public |
TextAlign: Right |
Label |
|
|
_______________ |
|
|
MaskTextBox |
|
txtOccupanyNumber |
|
|
Mask: 000-000-0000 |
Button |
|
btnOK |
OK |
|
DialogResult: OK |
Button |
|
btnCancel |
Cancel |
|
DialogResult: Cancel |
|
Form |
FormBorderStyle: |
FixedDialog |
Text: |
Ceil Inn - Employee Editor |
StartPosition: |
CenterScreen |
AcceptButton: |
btnOK |
CancelButton: |
btnCancel |
MaximizeBox: |
False |
MinimizeBox: |
False |
ShowInTaskBar: |
False |
Using the Collection Class
|
|
The Collection<> class is one of the
semi-complete classes of the .NET Framework. It is announced as follows:
public class Collection<T> : IList<T>,
ICollection<T>,
IEnumerable<T>,
IList, ICollection,
IEnumerable
As you can see, this is primarily a normal collection
class that implements the IList<>, the
ICollection<>, and the IEnumerable<> interfaces.
This makes it possible to add items to a collection and to manage the list.
Normally, you can use the Collection<> class "as is". It is
equipped with all the regular properties and methods.
The Collection<> class is mostly useful
if you want to create a class that impliments some particular behavior you
want, in which case you would first create a class based on
Collection<>. Here is an example:
// References Needed: System.dll,
// System.Drawing,
// System.Windows.Form
using System;
using System.Windows.Forms;
using System.Collections.ObjectModel;
public class Algebra : Form
{
public Algebra()
{
InitializeComponent();
}
private void InitializeComponent()
{
Text = "Algebra";
StartPosition = FormStartPosition.CenterScreen;
}
}
public class Series<T> : Collection<T>
{
}
public class Exercise
{
public static int Main()
{
Application.Run(new Algebra());
return 0;
}
}
Remember that the Collection<> class
receives the ability to add a new item from the ICollection
interface. Here are examples of calling it:
private void btnNumbersClicked(object sender, EventArgs e)
{
numbers = new Series<int>();
numbers.Add(2);
numbers.Add(937);
numbers.Add(49);
numbers.Add(8);
numbers.Add(64);
}
Remember that the Collection<> class
inherits the Item and the Count
properties. Here are examples of using them:
// References Needed: System.dll,
// System.Drawing,
// System.Windows.Form
using System;
using System.Windows.Forms;
using System.Collections.ObjectModel;
public class Algebra : Form
{
Button btnNumbers;
ListBox lbxNumbers;
Series<int> numbers;
public Algebra()
{
InitializeComponent();
}
private void InitializeComponent()
{
btnNumbers = new Button();
btnNumbers.Text = "Numbers";
btnNumbers.Location = new System.Drawing.Point(12, 12);
btnNumbers.Click += new EventHandler(btnNumbersClicked);
lbxNumbers = new ListBox();
lbxNumbers.Location = new System.Drawing.Point(12, 44);
Text = "Algebra";
Size = new System.Drawing.Size(150, 180);
StartPosition = FormStartPosition.CenterScreen;
Controls.Add(btnNumbers);
Controls.Add(lbxNumbers);
}
private void btnNumbersClicked(object sender, EventArgs e)
{
numbers = new Series<int>();
numbers.Add(2);
numbers.Add(937);
numbers.Add(49);
numbers.Add(8);
numbers.Add(64);
for(int i = 0; i < numbers.Count; i++)
lbxNumbers.Items.Add(numbers[i]);
}
}
public class Series<T> : Collection<T>
{
}
public class Exercise
{
public static int Main()
{
Application.Run(new Algebra());
return 0;
}
}
As an inheritor of the ICollection<>
interface, the Collection<> class has functionalities:
- To insert a new item inside the collection
- To get the index of an existing item
- check the availability of an item (using the Contains()
method)
- To delete an item from the collection by calling either the
Remove() or the RemoveAt() method
- To remove all items from the collection by calling the
Clear() method
Here are example of calling these methods (in the
following examples, to make code easier, there was no error checking and
exception handling was ignored):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections.ObjectModel;
namespace Algebra4
{
public partial class Exercise : Form
{
Collection<int> numbers;
public Exercise()
{
InitializeComponent();
}
private void Exercise_Load(object sender, EventArgs e)
{
numbers = new Collection<int>();
}
private void FillListBox()
{
lbxNumbers.Items.Clear();
foreach(int nbr in numbers)
lbxNumbers.Items.Add(nbr);
}
private void btnAdd_Click(object sender, EventArgs e)
{
numbers.Add(int.Parse(txtNumber.Text));
txtNumber.Text = "";
txtNumber.Focus();
FillListBox();
}
private void btnInsert_Click(object sender, EventArgs e)
{
numbers.Insert(int.Parse(txtIndex.Text), int.Parse(txtNumber.Text));
txtNumber.Text = "";
txtIndex.Text = "";
txtNumber.Focus();
FillListBox();
}
private void btnCheckIndexOf_Click(object sender, EventArgs e)
{
if (numbers.Contains(int.Parse(txtIndexOf.Text)) )
MessageBox.Show("The index of " + txtIndexOf.Text +
" is " + numbers.IndexOf(int.Parse(txtIndexOf.Text)),
"Algebra", MessageBoxButtons.OK,
MessageBoxIcon.Information);
else
MessageBox.Show("The collection doesn't contain " + txtIndexOf.Text + ". ",
"Algebra", MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
private void btnRemove_Click(object sender, EventArgs e)
{
numbers.Remove(int.Parse(txtRemove.Text));
FillListBox();
}
private void btnRemoveAllNumbers_Click(object sender, EventArgs e)
{
numbers.Clear();
FillListBox();
}
private void btnClose_Click(object sender, EventArgs e)
{
Close();
}
}
}
Practical Learning: Using a Collection Class
|
|
- To create a new form, in the Solution Explorer, right-click CeilInn2
-> Add -> Windows Form...
- Set the name to Customers
- Click Add
- In the Toolbox, click ListView and click the form
- Right-click it and click Edit Columns
- Create the columns as follows:
(Name) |
Text |
Width |
colAccountNumber |
Account # |
70 |
colFullName |
Full Name |
120 |
colPhoneNumber |
Phone # |
80 |
colEmergencyName |
Emergency Name |
100 |
colEmergencyPhone |
Emergency Phone |
100 |
- Click OK
- Design the form as follows:
|
Control |
(Name) |
Text |
Other Properties |
ListView |
|
lvwCustomers |
|
FullRowSelect: True GridLines: True View:
Details |
Button |
|
btnNewCustomer |
New Customer... |
|
Button |
|
btnClose |
Close |
|
|
- Double-click an unoccupied area of the form and make the following
changes:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Collections.ObjectModel;
using System.Runtime.Serialization.Formatters.Binary;
namespace CeilInn2
{
public partial class Customers : Form
{
Collection<Customer> lstCustomers;
public Customers()
{
InitializeComponent();
}
private void ShowCustomers()
{
// Check that the directory exists already. If not, create it
Directory.CreateDirectory(@"C:\Ceil Inn");
// Get a reference to the file that holds the records of properties
string Filename = @"C:\Ceil Inn\customers.cst";
// Make sure the file exists
if (File.Exists(Filename) == true)
{
// if so, create a file stream
FileStream stmCustomers = new FileStream(Filename,
FileMode.Open,
FileAccess.Read);
// Create a SOAP formatter
BinaryFormatter bfmCustomers = new BinaryFormatter();
// If some customers records were created already,
// get them and store them in the collection
lstCustomers = (Collection<Customer>)bfmCustomers.Deserialize(stmCustomers);
// First, empty the list view
lvwCustomers.Items.Clear();
// Visit each property in the collection and add it to the list view
foreach (Customer client in lstCustomers)
{
ListViewItem lviCustomer = new ListViewItem(client.AccountNumber);
lviCustomer.SubItems.Add(client.FullName);
lviCustomer.SubItems.Add(client.PhoneNumber);
lviCustomer.SubItems.Add(client.EmergencyName);
lviCustomer.SubItems.Add(client.EmergencyPhone);
lvwCustomers.Items.Add(lviCustomer);
}
// Close the file stream
stmCustomers.Close();
}
}
private void CustomersRecords_Load(object sender, EventArgs e)
{
lstCustomers = new Collection<Customer>();
ShowCustomers();
}
}
}
- Return to the form
- Double-click the New Customer button
- Implement its event as follows:
private void btnNewCustomer_Click(object sender, EventArgs e)
{
CustomerEditor editor = new CustomerEditor();
// Check that the directory for this business exists already.
// If it doesn't exist, create it
DirectoryInfo dirInfo = Directory.CreateDirectory(@"C:\Ceil Inn");
// Get a reference to the file that holds the customers records
string Filename = @"C:\Ceil Inn\customers.cst";
// First check if the file was previously created
if (File.Exists(Filename) == true)
{
// If the list of customers exists already,
// get it and store it in a file stream
FileStream stmCustomers = new FileStream(Filename,
FileMode.Open,
FileAccess.Read);
BinaryFormatter bfmCustomers = new BinaryFormatter();
// Store the list of customers in the collection
lstCustomers = (Collection<Customer>)bfmCustomers.Deserialize(stmCustomers);
// Close the file stream
stmCustomers.Close();
}
if( editor.ShowDialog() == DialogResult.OK)
{
Customer client = new Customer();
client.AccountNumber = editor.txtAccountNumber.Text;
client.FullName = editor.txtFullName.Text;
client.PhoneNumber = editor.txtPhoneNumber.Text;
client.EmergencyName = editor.txtEmergencyName.Text;
client.EmergencyPhone = editor.txtEmergencyPhone.Text;
// Add the property in the collection
lstCustomers.Add(client);
// Get a reference to the properties file
string strFilename = dirInfo.FullName + "\\customers.cst";
// Create a file stream to hold the list of properties
FileStream stmCustomers = new FileStream(strFilename,
FileMode.Create,
FileAccess.Write);
BinaryFormatter bfmCustomers = new BinaryFormatter();
// Serialize the list of properties
bfmCustomers.Serialize(stmCustomers, lstCustomers);
// Close the file stream
stmCustomers.Close();
// Show the list of properties
ShowCustomers();
}
}
- Return to the form and double-click the Close button
- Implement it as follows:
private void btnClose_Click(object sender, EventArgs e)
{
Close();
}
- To create a new form, on the main menu, click Project -> Add Windows
Form...
- Set the name to Employees
- Click Add
- Add a list viiew to the form and create the columns as follows:
(Name) |
Text |
Width |
colEmployeeNumber |
Employee # |
70 |
colFirstName |
First Name |
80 |
colLastName |
Last Name |
80 |
colTitle |
Title |
120 |
- Click OK
- Design the form as follows:
|
Control |
(Name) |
Text |
Other Properties |
ListView |
|
lvwEmployeess |
|
FullRowSelect: True GridLines: True View:
Details |
Button |
|
btnNewEmployee |
New Employee... |
|
Button |
|
btnClose |
Close |
|
|
- Double-click an unoccupied area of the form and make the following
changes:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Collections.ObjectModel;
using System.Runtime.Serialization.Formatters.Binary;
namespace CeilInn2
{
public partial class Employees : Form
{
Collection<Employee> lstEmployees;
public Employees()
{
InitializeComponent();
}
private void ShowEmployees()
{
Directory.CreateDirectory(@"C:\Ceil Inn");
string Filename = @"C:\Ceil Inn\employees.mpl";
if (File.Exists(Filename) == true)
{
FileStream stmEmployees = new FileStream(Filename,
FileMode.Open,
FileAccess.Read);
BinaryFormatter bfmEmployees = new BinaryFormatter();
lstEmployees = (Collection<Employee>)bfmEmployees.Deserialize(stmEmployees);
lvwCustomers.Items.Clear();
foreach (Employee clerk in lstEmployees)
{
ListViewItem lviEmployee = new ListViewItem(clerk.EmployeeNumber);
lviEmployee.SubItems.Add(clerk.FirstName);
lviEmployee.SubItems.Add(clerk.LastName);
lviEmployee.SubItems.Add(clerk.Title);
lvwCustomers.Items.Add(lviEmployee);
}
stmEmployees.Close();
}
}
private void Employees_Load(object sender, EventArgs e)
{
lstEmployees = new Collection<Employee>();
ShowEmployees();
}
}
}
- Return to the 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();
DirectoryInfo dirInfo = Directory.CreateDirectory(@"C:\Ceil Inn");
string Filename = @"C:\Ceil Inn\employees.mpl";
if (File.Exists(Filename) == true)
{
FileStream stmEmployees = new FileStream(Filename,
FileMode.Open,
FileAccess.Read);
BinaryFormatter bfmEmployees = new BinaryFormatter();
lstEmployees = (Collection<Employee>)bfmEmployees.Deserialize(stmEmployees);
stmEmployees.Close();
}
if (editor.ShowDialog() == DialogResult.OK)
{
Employee clerk = new Employee();
clerk.EmployeeNumber = editor.txtEmployeeNumber.Text;
clerk.FirstName = editor.txtFirstName.Text;
clerk.LastName = editor.txtLastName.Text;
clerk.Title = editor.txtTitle.Text;
lstEmployees.Add(clerk);
string strFilename = dirInfo.FullName + "\\employees.mpl";
FileStream stmEmployees = new FileStream(strFilename,
FileMode.Create,
FileAccess.Write);
BinaryFormatter bfmEmployees = new BinaryFormatter();
bfmEmployees.Serialize(stmEmployees, lstEmployees);
stmEmployees.Close();
ShowEmployees();
}
}
- Return to the form and double-click the Close button
- Implement it as follows:
private void btnClose_Click(object sender, EventArgs e)
{
Close();
}
- To create a new form, on the main menu, click Project -> Add Windows
Form...
- Set the name to Occupancies
- Click Add
- Add a list viiew to the form and create the columns as follows:
(Name) |
Text |
TextAlign |
Width |
colOccupancyNumber |
Occupancy # |
|
80 |
colDateOccupied |
Date Occupied |
|
100 |
colProcessedBy |
Processed By |
Center |
80 |
colProcessedFor |
Processed For |
Center |
80 |
colRoomOccupied |
Room Occupied |
Center |
90 |
colRateApplied |
Rate Applied |
Right |
80 |
colPhoneUse |
Phone Use |
Right |
65 |
- Click OK
- Design the form as follows:
|
Control |
(Name) |
Text |
Other Properties |
ListView |
|
lvwOccupancies |
|
FullRowSelect: True GridLines: True View:
Details |
Button |
|
btnNewOccupancy |
New Occupancy... |
|
Button |
|
btnClose |
Close |
|
|
- Double-click an unoccupied area of the form and make the following
changes:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Collections.ObjectModel;
using System.Runtime.Serialization.Formatters.Binary;
namespace CeilInn2
{
public partial class Occupancies : Form
{
Collection<Occupancy> lstOccupancies;
public Occupancies()
{
InitializeComponent();
}
private void ShowOccupancies()
{
Directory.CreateDirectory(@"C:\Ceil Inn");
string Filename = @"C:\Ceil Inn\occupancies.ocp";
if (File.Exists(Filename) == true)
{
FileStream stmOccupancies = new FileStream(Filename,
FileMode.Open,
FileAccess.Read);
BinaryFormatter bfmRooms = new BinaryFormatter();
lstOccupancies = (Collection<Occupancy>)bfmRooms.Deserialize(stmOccupancies);
lvwOccupancies.Items.Clear();
foreach (Occupancy order in lstOccupancies)
{
ListViewItem lviOccupancy = new ListViewItem(order.OccupancyNumber);
lviOccupancy.SubItems.Add(order.DateOccupied.ToLongDateString());
lviOccupancy.SubItems.Add(order.ProcessedBy);
lviOccupancy.SubItems.Add(order.ProcessedFor);
lviOccupancy.SubItems.Add(order.RoomOccupied);
lviOccupancy.SubItems.Add(order.RateApplied.ToString("F"));
lviOccupancy.SubItems.Add(order.PhoneUse.ToString("F"));
lvwOccupancies.Items.Add(lviOccupancy);
}
stmOccupancies.Close();
}
}
private void Occupancies_Load(object sender, EventArgs e)
{
lstOccupancies = new RoomManagement<Occupancy>();
ShowOccupancies();
}
}
}
- Return to the form and double-click the New Occupancy button
- Implement its event as follows:
private void btnNewOccupancy_Click(object sender, EventArgs e)
{
OccupancyEditor editor = new OccupancyEditor();
DirectoryInfo dirInfo = Directory.CreateDirectory(@"C:\Ceil Inn");
string Filename = @"C:\Ceil Inn\occupancies.ocp";
if (File.Exists(Filename) == true)
{
FileStream stmOccupancies = new FileStream(Filename,
FileMode.Open,
FileAccess.Read);
BinaryFormatter bfmOccupancies = new BinaryFormatter();
lstOccupancies = (Collection<Occupancy>)bfmOccupancies.Deserialize(stmOccupancies);
stmOccupancies.Close();
}
if (editor.ShowDialog() == DialogResult.OK)
{
Occupancy occupy = new Occupancy();
occupy.OccupancyNumber = editor.txtOccupancyNumber.Text;
occupy.DateOccupied = editor.dtpDateOccupied.Value;
occupy.ProcessedBy = editor.txtEmployeeNumber.Text;
occupy.ProcessedFor = editor.txtAccountNumber.Text;
occupy.RoomOccupied = editor.cbxRoomsNumbers.Text;
occupy.RateApplied = double.Parse(editor.txtRateApplied.Text);
occupy.PhoneUse = double.Parse(editor.txtPhoneUse.Text);
lstOccupancies.Add(occupy);
string strFilename = dirInfo.FullName + "\\occupancies.ocp";
FileStream stmRooms = new FileStream(strFilename,
FileMode.Create,
FileAccess.Write);
BinaryFormatter bfmRooms = new BinaryFormatter();
bfmRooms.Serialize(stmRooms, lstOccupancies);
stmRooms.Close();
ShowOccupancies();
}
}
- Return to the form and double-click the Close button
- Implement it as follows:
private void btnClose_Click(object sender, EventArgs e)
{
Close();
}
Creating a Collection<> Class
|
|
As stated already, the real role of the
Collection<> class is to let you derive a class from it and
implement some custom behaviors. To let you do this, the class is equipped
with a property and some methods that are not inherited from
ICollection<>. Because these are protected members, you must
override them in your own class.
Practical Learning: Using a Collection Class
|
|
- To create a new class, on the main menu, click Project -> Add
Class...
- Set the Name to RoomManagement
- Click Add
- Change the file as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
namespace CeilInn2
{
[Serializable]
public class RoomManagement<T> : Collection<T>
{
public RoomManagement() : base()
{
}
}
}
The Collection<> class has two
constructors. The default is used to create a list an empty list. The other
constructor uses the following syntax:
public Collection(IList<T> list);
This constructor allows you to create a list based on
another existing list that is from a class that implements the IList<>
interface. Here is an example of using this constructor:
// References Needed: System.dll,
// System.Drawing,
// System.Windows.Form
using System;
using System.Windows.Forms;
using System.Collections.ObjectModel;
public class Algebra : Form
{
Button btnNumbers;
Button btnIntegers;
ListBox lbxNumbers;
Series<int> numbers;
public Algebra()
{
InitializeComponent();
}
private void InitializeComponent()
{
btnNumbers = new Button();
btnNumbers.Text = "Numbers";
btnNumbers.Location = new System.Drawing.Point(12, 12);
btnNumbers.Click += new EventHandler(btnNumbersClicked);
btnIntegers = new Button();
btnIntegers.Text = "New Numbers";
btnIntegers.Width = 90;
btnIntegers.Location = new System.Drawing.Point(90, 12);
btnIntegers.Click += new EventHandler(btnIntegersClicked);
lbxNumbers = new ListBox();
lbxNumbers.Location = new System.Drawing.Point(40, 44);
Text = "Algebra";
Size = new System.Drawing.Size(200, 180);
StartPosition = FormStartPosition.CenterScreen;
Controls.Add(btnNumbers);
Controls.Add(lbxNumbers);
Controls.Add(btnIntegers);
}
private void btnNumbersClicked(object sender, EventArgs e)
{
numbers = new Series<int>();
numbers.Add(2);
numbers.Add(937);
numbers.Add(49);
numbers.Add(8);
numbers.Add(64);
for(int i = 0; i < numbers.Count; i++)
lbxNumbers.Items.Add(numbers[i]);
}
private void btnIntegersClicked(object sender, EventArgs e)
{
Collection<int> integers = new Collection<int>(numbers);
lbxNumbers.Items.Clear();
for (int i = 0; i < integers.Count; i++)
lbxNumbers.Items.Add(integers[i]);
}
}
public class Series<T> : Collection<T>
{
}
On the other hand, if you had previously created a
Collection<> object, to let you get it as an
IList<>, the Collection<> class provides a
property named Items that of type IList<>:
protected IList<T> Items { get; }
As you can see, Items is a protected
property. This means that, to use it, you must first create a class that
overrides it.
In both cases, whether using the
Collection(IList<T> list) constructor or the Items
property to get a new list, once you have the new collection, you can use it
as you see fit. For example, you can add new values to it. Here are
examples:
// References Needed: System.dll,
// System.Drawing,
// System.Windows.Form
using System;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Collections.ObjectModel;
public class Algebra : Form
{
Button btnNumbers;
Button btnIntegers;
ListBox lbxNumbers;
Series<int> numbers;
public Algebra()
{
InitializeComponent();
}
private void InitializeComponent()
{
btnNumbers = new Button();
btnNumbers.Text = "Numbers";
btnNumbers.Location = new System.Drawing.Point(12, 12);
btnNumbers.Click += new EventHandler(btnNumbersClicked);
btnIntegers = new Button();
btnIntegers.Text = "New Numbers";
btnIntegers.Width = 90;
btnIntegers.Location = new System.Drawing.Point(90, 12);
btnIntegers.Click += new EventHandler(btnIntegersClicked);
lbxNumbers = new ListBox();
lbxNumbers.Location = new System.Drawing.Point(40, 44);
Text = "Algebra";
Size = new System.Drawing.Size(200, 180);
StartPosition = FormStartPosition.CenterScreen;
Controls.Add(btnNumbers);
Controls.Add(lbxNumbers);
Controls.Add(btnIntegers);
}
private void btnNumbersClicked(object sender, EventArgs e)
{
numbers = new Series<int>();
numbers.Add(2);
numbers.Add(937);
numbers.Add(49);
numbers.Add(8);
numbers.Add(64);
for(int i = 0; i < numbers.Count; i++)
lbxNumbers.Items.Add(numbers[i]);
}
private void btnIntegersClicked(object sender, EventArgs e)
{
Series<int> integers = (Series<int>)numbers.Items;
integers.Add(1865);
integers.Add(370);
lbxNumbers.Items.Clear();
for (int i = 0; i < integers.Count; i++)
lbxNumbers.Items.Add(integers[i]);
}
}
public class Series<T> : Collection<T>
{
public IList<T> Items
{
get
{
return this;
}
}
}
Of course, you can also perform all the other allowed
operations on the new collection.
Practical Learning: Getting Items From a Collection
|
|
- Change the RoomManagement class as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
namespace CeilInn2
{
[Serializable]
public class RoomManagement<T> : Collection<T>
{
public RoomManagement() : base()
{
}
public RoomManagement(IList<T> list) : base(list)
{
}
public virtual new IList<T> Items
{
get
{
return this;
}
}
}
}
To let you customize the way an item should be inserted
in a list, the Collection<> class provides the
InsertItem() method. Its syntax is:
protected virtual void InsertItem(int index, T item);
This method takes two arguments: the item that will be
inserted and the position it must occupy. Once again, the easisest
implementation would consist of calling the parent's definition, which
should be fine in a regular scenario. Here is an example:
// References Needed: System.dll,
// System.Drawing,
// System.Windows.Form
using System;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Collections.ObjectModel;
public class Algebra : Form
{
Button btnNumbers;
Button btnInsert;
ListBox lbxNumbers;
Series<int> numbers;
public Algebra()
{
InitializeComponent();
}
private void InitializeComponent()
{
btnNumbers = new Button();
btnNumbers.Text = "Numbers";
btnNumbers.Location = new System.Drawing.Point(12, 12);
btnNumbers.Click += new EventHandler(btnNumbersClicked);
btnInsert = new Button();
btnInsert.Text = "Insert";
btnInsert.Location = new System.Drawing.Point(90, 12);
btnInsert.Click += new EventHandler(btnInsertClicked);
lbxNumbers = new ListBox();
lbxNumbers.Location = new System.Drawing.Point(40, 44);
Text = "Algebra";
Size = new System.Drawing.Size(200, 180);
StartPosition = FormStartPosition.CenterScreen;
Controls.Add(btnNumbers);
Controls.Add(lbxNumbers);
Controls.Add(btnInsert);
}
private void btnNumbersClicked(object sender, EventArgs e)
{
numbers = new Series<int>();
numbers.Add(2);
numbers.Add(937);
numbers.Add(49);
numbers.Add(8);
numbers.Add(64);
for(int i = 0; i < numbers.Count; i++)
lbxNumbers.Items.Add(numbers[i]);
}
private void btnInsertClicked(object sender, EventArgs e)
{
numbers.InsertItem(3, 10509);
lbxNumbers.Items.Clear();
for (int i = 0; i < numbers.Count; i++)
lbxNumbers.Items.Add(numbers[i]);
}
}
public class Series<T> : Collection<T>
{
public new IList<T> Items
{
get
{
return this;
}
}
public new void SetItem(int index, T item)
{
if (index < 0)
return;
else if (index > Count)
return;
else
this[index] = item;
// This too would work
// base.SetItem(index, item);
}
public new void InsertItem(int index, T item)
{
base.InsertItem(index, item);
}
}
An alternative is to create your own implementation. For
example, if the user passes an invalid index, the compiler would throw an
ArgumentOutOfRangeException exception. One probable
solution is to indicate to the compiler what to do in case of a problem.
Here is an example:
public new void InsertItem(int index, T item)
{
if( (index >= 0) && (index <= Count) )
base.InsertItem(index, item);
}
Of course, another solution is to call the
ICollection<>.Insert() method.
Practical Learning: Creating or Inserting an Item
|
|
- Change the RoomManagement class as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
namespace CeilInn2
{
[Serializable]
public class RoomManagement<T> : Collection<T>
{
public RoomManagement() : base()
{
}
public RoomManagement(IList<T> list) : base(list)
{
}
public virtual new IList<T> Items
{
get
{
return this;
}
}
public new void InsertItem(int index, T item)
{
if (index < 0)
throw new ArgumentOutOfRangeException("The value you provided " +
"for the index is not valid");
else if ((index >= 0) && (index <= Count))
base.InsertItem(index, item);
else // If the index is higher than Count, simply add the item (at the end of the list)
this.Add(item);
}
}
}
- To create a new form, on the main menu, click Project -> Add Windows
Form...
- Set the name to Rooms
- Click Add
- In the Menus & Toolbars section of the Toolbox, click
ContextMenuStrip and click the form
- Click the menu items as follows:
(Name) |
Enabled |
Text |
mnuNewRoom |
False |
&New Room... |
mnuInsertRoom |
False |
&Insert Room... |
mnuEditRoomDetails |
False |
&Edit Room Details... |
mnuDeleteRoom |
False |
&Delete Room |
- Add a list viiew to the form and create the columns as follows:
(Name) |
Text |
TextAlign |
Width |
colRoomNumber |
Room # |
|
|
colRoomType |
Room Type |
|
100 |
colBedType |
Bed Type |
|
80 |
colRate |
Rate |
Right |
|
colAvailable |
Available? |
Center |
65 |
- Click OK
- Design the form as follows:
|
Control |
(Name) |
Text |
Other Properties |
ListView |
|
lvwRooms |
|
ContextMenuStrip: cmsRooms FullRowSelect: True
GridLines: True View: Details |
Button |
|
btnNewRoom |
New Room... |
|
Button |
|
btnClose |
Close |
|
|
- Double-click an unoccupied area of the form and make the following
changes:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Collections.ObjectModel;
using System.Runtime.Serialization.Formatters.Binary;
namespace CeilInn2
{
public partial class Rooms : Form
{
RoomManagement<Room> lstRooms;
public Rooms()
{
InitializeComponent();
}
private void ShowRooms()
{
Directory.CreateDirectory(@"C:\Ceil Inn");
string Filename = @"C:\Ceil Inn\rooms.rms";
if (File.Exists(Filename) == true)
{
FileStream stmRooms = new FileStream(Filename,
FileMode.Open,
FileAccess.Read);
BinaryFormatter bfmRooms = new BinaryFormatter();
lstRooms = (RoomManagement<Room>)bfmRooms.Deserialize(stmRooms);
lvwRooms.Items.Clear();
foreach (Room unit in lstRooms)
{
ListViewItem lviRoom = new ListViewItem(unit.RoomNumber);
lviRoom.SubItems.Add(unit.RoomType);
lviRoom.SubItems.Add(unit.BedType);
lviRoom.SubItems.Add(unit.Rate.ToString());
lviRoom.SubItems.Add(unit.Available.ToString());
lvwRooms.Items.Add(lviRoom);
}
stmRooms.Close();
}
}
private void Rooms_Load(object sender, EventArgs e)
{
lstRooms = new RoomManagement<Room>();
ShowRooms();
}
}
}
- Return to the form and double-click the New Room button
- Implement its event as follows:
private void btnNewRoom_Click(object sender, EventArgs e)
{
RoomEditor editor = new RoomEditor();
DirectoryInfo dirInfo = Directory.CreateDirectory(@"C:\Ceil Inn");
string Filename = @"C:\Ceil Inn\rooms.rms";
if (File.Exists(Filename) == true)
{
FileStream stmRooms = new FileStream(Filename,
FileMode.Open,
FileAccess.Read);
BinaryFormatter bfmRooms = new BinaryFormatter();
lstRooms = (RoomManagement<Room>)bfmRooms.Deserialize(stmRooms);
stmRooms.Close();
}
if (editor.ShowDialog() == DialogResult.OK)
{
Room unit = new Room();
unit.RoomNumber = editor.txtRoomNumber.Text;
unit.RoomType = editor.cbxRoomTypes.Text;
unit.BedType = editor.cbxBedTypes.Text;
unit.Rate = double.Parse(editor.txtRate.Text);
unit.Available = editor.chkAvailable.Checked;
lstRooms.InsertItem(lstRooms.Count + 1, unit);
string strFilename = dirInfo.FullName + "\\rooms.rms";
FileStream stmRooms = new FileStream(strFilename,
FileMode.Create,
FileAccess.Write);
BinaryFormatter bfmRooms = new BinaryFormatter();
bfmRooms.Serialize(stmRooms, lstRooms);
stmRooms.Close();
ShowRooms();
}
}
- Return to the form
- Under the form, click cmsRooms
- Under ContextMenuStrip, double-click New Room...
- Implement the event as follows:
private void mnuNewRoom_Click(object sender, EventArgs e)
{
btnNewRoom_Click(sender, e);
}
- Return to the form and click the list view
- In the Properties window, click Events and, in the Events section,
double-click ItemSelectionChanged
- Implement the event as follows:
private void lvwRooms_ItemSelectionChanged(object sender,
ListViewItemSelectionChangedEventArgs e)
{
if (lvwRooms.SelectedItems.Count == 1)
{
mnuInsertRoom.Enabled = true;
mnuEditRoomDetails.Enabled = true;
mnuDeleteRoom.Enabled = true;
}
else
{
mnuInsertRoom.Enabled = false;
mnuEditRoomDetails.Enabled = false;
mnuDeleteRoom.Enabled = false;
}
}
- Return to the form and, under the form, click cmsRooms
- On the form, double-click Insert Room...
- Implement the event as follows:
private void mnuInsertRoom_Click(object sender, EventArgs e)
{
RoomEditor editor = new RoomEditor();
string Filename = @"C:\Ceil Inn\rooms.rms";
DirectoryInfo dirInfo = Directory.CreateDirectory(@"C:\Ceil Inn");
if (File.Exists(Filename) == true)
{
FileStream stmRooms = new FileStream(Filename,
FileMode.Open,
FileAccess.Read);
BinaryFormatter bfmRooms = new BinaryFormatter();
lstRooms = (RoomManagement<Room>)bfmRooms.Deserialize(stmRooms);
stmRooms.Close();
}
Room rm = new Room();
string strRoomNumber = lvwRooms.SelectedItems[0].Text;
rm.RoomNumber = lvwRooms.SelectedItems[0].Text;
if (lstRooms.IndexOf(rm) >= 0)
{
if (editor.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
Room unit = new Room();
unit.RoomNumber = editor.txtRoomNumber.Text;
unit.RoomType = editor.cbxRoomTypes.Text;
unit.BedType = editor.cbxBedTypes.Text;
unit.Rate = double.Parse(editor.txtRate.Text);
unit.Available = editor.chkAvailable.Checked;
lstRooms.InsertItem(lstRooms.IndexOf(rm), unit);
string strFilename = dirInfo.FullName + "\\rooms.rms";
FileStream stmRooms = new FileStream(strFilename,
FileMode.Create,
FileAccess.Write);
BinaryFormatter bfmRooms = new BinaryFormatter();
bfmRooms.Serialize(stmRooms, lstRooms);
stmRooms.Close();
}
ShowRooms();
}
}
- Return to the form and click the list view
- In the Events section of the Ribbon, double-click KeyDown
- Implement the event as follows:
private void lvwRooms_KeyDown(object sender, KeyEventArgs e)
{
if( lvwRooms.SelectedItems.Count == 0 )
return;
if (e.KeyCode == Keys.Insert)
mnuInsertRoom_Click(sender, e);
}
- Return to the form and double-click the Close button
- Implement it as follows:
private void btnClose_Click(object sender, EventArgs e)
{
Close();
}
- Display the OccupanyEditor form
- Double-click an unoccupied area of the form and change the file as
follows:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Collections.ObjectModel;
using System.Runtime.Serialization.Formatters.Binary;
namespace CeilInn2
{
public partial class OccupancyEditor : Form
{
public OccupancyEditor()
{
InitializeComponent();
}
private void OccupancyEditor_Load(object sender, EventArgs e)
{
string Filename = @"C:\Ceil Inn\rooms.rms";
if (File.Exists(Filename) == true)
{
FileStream stmRooms = new FileStream(Filename,
FileMode.Open,
FileAccess.Read);
BinaryFormatter bfmRooms = new BinaryFormatter();
RoomManagement<Room> lstRooms = (RoomManagement<Room>)bfmRooms.Deserialize(stmRooms);
foreach (Room unit in lstRooms)
cbxRoomsNumbers.Items.Add(unit.RoomNumber);
stmRooms.Close();
}
}
}
}
- Return to the form
- Click the Employee # text box
- In the Events section of the Properties window, double-click Leave
- Implement the event as follows:
private void txtEmployeeNumber_Leave(object sender, EventArgs e)
{
string Filename = @"C:\Ceil Inn\employees.mpl";
if (File.Exists(Filename) == true)
{
FileStream stmEmployees = new FileStream(Filename,
FileMode.Open,
FileAccess.Read);
BinaryFormatter bfmEmployees = new BinaryFormatter();
Collection<Employee> lstEmployees = (Collection<Employee>)bfmEmployees.Deserialize(stmEmployees);
foreach (Employee clerk in lstEmployees)
{
if (clerk.EmployeeNumber == txtEmployeeNumber.Text)
{
txtEmployeeName.Text = clerk.LastName + ", " + clerk.FirstName;
break;
}
}
// Close the file stream
stmEmployees.Close();
}
}
- Return to the form and click the Customer # text box
- In the Events section of the Properties window, double-click Leave
- Implement the event as follows:
private void txtAccountNumber_Leave(object sender, EventArgs e)
{
string Filename = @"C:\Ceil Inn\customers.cst";
if (File.Exists(Filename) == true)
{
FileStream stmCustomers = new FileStream(Filename,
FileMode.Open,
FileAccess.Read);
BinaryFormatter bfmCustomers = new BinaryFormatter();
Collection<Customer> lstCustomers = (Collection<Customer>)bfmCustomers.Deserialize(stmCustomers);
foreach (Customer client in lstCustomers)
{
if (client.AccountNumber == txtAccountNumber.Text)
{
txtCustomerName.Text = client.FullName;
break;
}
}
stmCustomers.Close();
}
}
- Return to the form and double-click the Room Number combo box
- Implement the event as follows:
private void cbxRoomsNumbers_SelectedIndexChanged(object sender, EventArgs e)
{
string Filename = @"C:\Ceil Inn\rooms.rms";
if (File.Exists(Filename) == true)
{
FileStream stmRooms = new FileStream(Filename,
FileMode.Open,
FileAccess.Read);
BinaryFormatter bfmRooms = new BinaryFormatter();
RoomManagement<Room> lstRooms = (RoomManagement<Room>)bfmRooms.Deserialize(stmRooms);
foreach (Room unit in lstRooms)
{
if (unit.RoomNumber == cbxRoomsNumbers.Text)
{
txtRoomDescription.Text = unit.RoomType + ", " +
unit.BedType + ", " +
unit.Rate.ToString() + ", " +
(unit.Available == true ? "Available" : "Occupied");
break;
}
}
stmRooms.Close();
}
}
- In the Solution Explorer, right-click Form1.cs and click Rename
- Type CeilInn.cs and press Enter twice to display
the form
- Design the form as follows:
|
Control |
(Name) |
Text |
Button |
|
btnCustomers |
Customers... |
Button |
|
btnEmployees |
Employees... |
Button |
|
btnRooms |
Rooms... |
Button |
|
btnOcupancies |
Occupancies... |
Button |
|
btnClose |
Close |
|
- Double-click the Customers button
- Implement its event as follows:
private void btnCustomers_Click(object sender, EventArgs e)
{
Customers clients = new Customers();
clients.ShowDialog();
}
- Return to the Ceil Inn form and double-click the Employees button
- Implement its event as follows:
private void btnEmployees_Click(object sender, EventArgs e)
{
Employees staff = new Employees();
staff.ShowDialog();
}
- Return to the form and double-click the Rooms button
- Implement the event as follows:
private void btnRooms_Click(object sender, EventArgs e)
{
Rooms rms = new Rooms();
rms.ShowDialog();
}
- Return to the form and double-click the Occupancies button
- Implement the event as follows:
private void btnOccupancies_Click(object sender, EventArgs e)
{
Occupancies rentals = new Occupancies();
rentals.ShowDialog();
}
- Return to the form and double-click the Close button
- Implement its event as follows:
private void btnClose_Click(object sender, EventArgs e)
{
Close();
}
- To execute, press F9
- Click the Customers button
- In the Customers form, click New Customer...
- Create each record as follows and click OK at then end of each:
Account # |
Full Name |
Phone # |
Emergency Name |
Emergency Phone |
294-209 |
Doris Wilson |
703-416-0934 |
Gabriela Dawson |
703-931-1000 |
608-502 |
Caroline Lomey |
301-652-0700 |
Albert Lomey |
301-412-5055 |
208-405 |
Peter Carney |
990-585-1886 |
Spencer Miles |
990-750-8666 |
284-085 |
Lucy Chen |
425-979-7413 |
Edward Lamb |
425-720-9247 |
629-305 |
Joan Davids |
202-789-0500 |
Rebecca Boiron |
202-399-3600 |
180-204 |
Randy Whittaker |
703-631-1200 |
Bryan Rattner |
703-506-9200 |
204-795 |
Juliette Beckins |
410-944-1440 |
Bernard Brodsky |
410-385-2235 |
608-208 |
Alfred Owens |
804-798-3257 |
Jane Owens |
240-631-1445 |
902-840 |
Daniel Peters |
624-802-1686 |
Grace Peters |
877-490-9333 |
660-820 |
Anne Sandt |
953-172-9347 |
William Sandt |
953-279-2475 |
946-090 |
Peter Carney |
990-585-1886 |
Spencer Miles |
990-750-8666 |
100-752 |
Caroline Lomey |
301-652-0700 |
Albert Lomey |
301-412-5055 |
- Close the Customers form
- Click the Employees button
- Click the New Employee button and create each new employee as
follows (click OK after each):
Employee # |
First Name |
Last Name |
Title |
22-958 |
Andrew |
Laskin |
General Manager |
70-429 |
Lynda |
Fore |
Shift Manager |
27-049 |
Harriett |
Dovecot |
Associate |
28-405 |
Peggy |
Thompson |
Associate |
24-095 |
Fred |
Barclay |
Associate |
72-947 |
Sheryl |
Shegger |
Intern |
- Close the Employees form
- Click the Rooms button
- Continuously click New Room... and create the following records:
Room # |
Type |
Bed |
Rate |
Available |
104 |
Bedroom |
Queen |
75.85 |
Unchecked |
105 |
Bedroom |
Queen |
85.75 |
Checked |
107 |
Bedroom |
King |
92.55 |
Unchecked |
108 |
Bedroom |
Queen |
75.85 |
Checked |
202 |
Bedroom |
King |
98.95 |
Unchecked |
203 |
Bedroom |
Queen |
94.50 |
Checked |
204 |
Bedroom |
Double |
79.90 |
Checked |
205 |
Bedroom |
Queen |
75.85 |
Checked |
207 |
Bedroom |
King |
85.75 |
Unchecked |
- Close the Rooms form
- Click Occupancies
- Create the following records:
Date Occupied |
Processed By |
Customer |
Room # |
Rate Applied |
Phone Use |
Occupancy # |
June 4, 2011 |
27-049 |
294-209 |
105 |
85.75 |
0.00 |
294-209-0001 |
June 5, 2011 |
28-405 |
294-209 |
105 |
85.75 |
5.35 |
294-209-0001 |
June 5, 2011 |
70-429 |
608-502 |
110 |
450.00 |
8.75 |
608-502-0001 |
June 6, 2011 |
70-429 |
294-209 |
105 |
85.75 |
0.00 |
294-209-0001 |
June 6, 2011 |
24-095 |
208-405 |
108 |
75.85 |
3.45 |
208-405-0001 |
June 7, 2011 |
28-405 |
208-405 |
108 |
75.85 |
2.65 |
208-405-0001 |
June 8, 2011 |
28-405 |
208-405 |
108 |
75.85 |
3.15 |
208-405-0001 |
June 9, 2011 |
27-049 |
208-405 |
108 |
75.85 |
1.95 |
208-405-0001 |
June 9, 2011 |
28-405 |
284-085 |
205 |
75.85 |
0.00 |
284-085-0001 |
June 10, 2011 |
24-095 |
208-405 |
108 |
75.85 |
5.50 |
208-405-0001 |
June 11, 2011 |
24-095 |
629-305 |
112 |
98.95 |
0.00 |
629-305-0001 |
June 12, 2011 |
70-429 |
629-305 |
112 |
98.85 |
0.00 |
629-305-0001 |
- Close the Occupancies form
- Click the Rooms button
- Right-click the 107 row and click Insert Room...
- Fill the form with the following values:
Room #: 106
Room Type: Bedroom Bed Type: Queen
Rate: 75.85 Check the Available check box
- Click OK
- Right-click the 202 record and click Insert Room...
- Fill the form with the following values:
Room #: 110
Room Type: Conference Room Rate: 450.00
Check the Available check box
- Click OK
- Right-click the 202 record and click Insert Room...
- Fill the form with the following values:
Room #: 114
Room Type: Conference Room Rate: 625.00
- Click OK
- Right-click anywhere in the list view and click New Room...
- Fill the form with the following values:
Room #: 210
Room Type: Bedroom Bed Type: King
Rate: 98.95
- Click OK
- Right-click the 210 record and click Insert Room...
- Fill the form with the following values:
Room #: 208
Room Type: Bedroom Bed Type: King
Rate: 115.95
- Click OK
- Close the Rooms form
- Click the Occupancies button
- Click New Occupancy and create the following new records:
Date Occupied |
Processed By |
Customer |
Room # |
Rate Applied |
Phone Use |
Internet Fee |
July 18, 2011 |
28-405 |
180-204 |
105 |
94.50 |
0.00 |
180-204-0001 |
July 18, 2011 |
72-947 |
660-820 |
204 |
115.95 |
0.00 |
660-820-0001 |
July 18, 2011 |
28-405 |
608-208 |
206 |
94.50 |
0.00 |
608-208-0001 |
July 18, 2011 |
72-947 |
204-795 |
204 |
0.00 |
0.00 |
204-795-0001 |
July 18, 2011 |
28-405 |
902-840 |
203 |
104.50 |
0.00 |
902-840-0001 |
July 19, 2011 |
24-095 |
180-204 |
105 |
94.50 |
0.00 |
180-204-0001 |
July 19, 2011 |
24-095 |
660-820 |
204 |
115.95 |
0.00 |
660-820-0001 |
July 19, 2011 |
24-095 |
608-208 |
206 |
94.50 |
0.00 |
608-208-0001 |
July 19, 2011 |
24-095 |
204-795 |
204 |
0.00 |
0.00 |
204-795-0001 |
July 19, 2011 |
72-947 |
902-840 |
203 |
104.50 |
0.00 |
902-840-0001 |
- Close the forms and return to your programming environment
The Collection<> class implements the
ICollection interface. This allows you to access an item
using its index. Besides the ability to specify the value an item based on
its index, the Collection<> class provides the
SetItem() method that makes it possible to change an item. Its
syntax is:
protected virtual void SetItem(int index, T item);
The item argument holds the value that will be
assigned to the item at the index position. When overriding this
method, the simplest implementation would consist of calling the same method
of the parent class. Here is an example:
// References Needed: System.dll,
// System.Drawing,
// System.Windows.Form
using System;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Collections.ObjectModel;
public class Algebra : Form
{
Button btnNumbers;
Button btnChange;
ListBox lbxNumbers;
Series<int> numbers;
public Algebra()
{
InitializeComponent();
}
private void InitializeComponent()
{
btnNumbers = new Button();
btnNumbers.Text = "Numbers";
btnNumbers.Location = new System.Drawing.Point(12, 12);
btnNumbers.Click += new EventHandler(btnNumbersClicked);
btnChange = new Button();
btnChange.Text = "New Numbers";
btnChange.Width = 90;
btnChange.Location = new System.Drawing.Point(90, 12);
btnChange.Click += new EventHandler(btnChangeClicked);
lbxNumbers = new ListBox();
lbxNumbers.Location = new System.Drawing.Point(40, 44);
Text = "Algebra";
Size = new System.Drawing.Size(200, 180);
StartPosition = FormStartPosition.CenterScreen;
Controls.Add(btnNumbers);
Controls.Add(lbxNumbers);
Controls.Add(btnChange);
}
private void btnNumbersClicked(object sender, EventArgs e)
{
numbers = new Series<int>();
numbers.Add(2);
numbers.Add(937);
numbers.Add(49);
numbers.Add(8);
numbers.Add(64);
for(int i = 0; i < numbers.Count; i++)
lbxNumbers.Items.Add(numbers[i]);
}
private void btnChangeClicked(object sender, EventArgs e)
{
numbers.SetItem(2, 13579);
lbxNumbers.Items.Clear();
for (int i = 0; i < numbers.Count; i++)
lbxNumbers.Items.Add(numbers[i]);
}
}
public class Series<T> : Collection<T>
{
public new IList<T> Items
{
get
{
return this;
}
}
public new void SetItem(int index, T item)
{
base.SetItem(index, item);
}
}
Otherwise, when defining this method, you must decide
what to do in case of this or that. For example, what should the compiler do
if the index is negative? What if the passed index is higher
than the total number of items in the collection. In this case, by default,
the compiler would throw an IndexOutRangeException
exception. One alternative is to ignore the new value if the index is out of
range. Here is an example of implementing:
// References Needed: System.dll,
// System.Drawing,
// System.Windows.Form
using System;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Collections.ObjectModel;
public class Algebra : Form
{
Button btnNumbers;
Button btnChange;
ListBox lbxNumbers;
Series<int> numbers;
. . .
private void btnChangeClicked(object sender, EventArgs e)
{
numbers.SetItem(12, 13579);
lbxNumbers.Items.Clear();
for (int i = 0; i < numbers.Count; i++)
lbxNumbers.Items.Add(numbers[i]);
}
}
public class Series<T> : Collection<T>
{
public new IList<T> Items
{
get
{
return this;
}
}
public new void SetItem(int index, T item)
{
if (index < 0)
return;
else if (index > Count)
return;
else
this[index] = item;
// This too would work
// base.SetItem(index, item);
}
}
Another alternative is to add the item as the last in
the list.
Practical Learning: Changing an Item
|
|
- On the main menu, click Window -> RoomManagement.cs
- Change the class as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
namespace CeilInn2
{
[Serializable]
public class RoomManagement<T> : Collection<T>
{
public RoomManagement() : base()
{
}
public RoomManagement(IList<T> list) : base(list)
{
}
public virtual new IList<T> Items
{
get
{
return this;
}
}
public new void InsertItem(int index, T item)
{
if (index < 0)
throw new ArgumentOutOfRangeException("The value you provided " +
"for the index is not valid");
else if ((index >= 0) && (index <= Count))
base.InsertItem(index, item);
else // If the index is higher than Count, simply add the item (at the end of the list)
this.Add(item);
}
public new void SetItem(int index, T item)
{
if (index < 0)
return;
else if (index > Count)
return;
else
base.SetItem(index, item);
}
}
}
- Display the Rooms form
- Click the list view
- In the Events section of the Properties window, double-click
DoubleClick
- Implement the event as follows:
private void lvwRooms_DoubleClick(object sender, EventArgs e)
{
if (lvwRooms.SelectedItems.Count == 1)
{
RoomEditor editor = new RoomEditor();
string Filename = @"C:\Ceil Inn\rooms.rms";
DirectoryInfo dirInfo = Directory.CreateDirectory(@"C:\Ceil Inn");
if (File.Exists(Filename) == true)
{
FileStream stmRooms = new FileStream(Filename,
FileMode.Open,
FileAccess.Read);
BinaryFormatter bfmRooms = new BinaryFormatter();
lstRooms = (RoomManagement<Room>)bfmRooms.Deserialize(stmRooms);
stmRooms.Close();
}
Room rm = new Room();
rm.RoomNumber = lvwRooms.SelectedItems[0].Text;
if( lstRooms.IndexOf(rm) >= 0 )
{
editor.txtRoomNumber.Text = lvwRooms.SelectedItems[0].Text;
editor.cbxRoomTypes.Text = lvwRooms.SelectedItems[0].SubItems[1].Text;
editor.cbxBedTypes.Text = lvwRooms.SelectedItems[0].SubItems[2].Text;
editor.txtRate.Text = lvwRooms.SelectedItems[0].SubItems[3].Text;
editor.chkAvailable.Checked = bool.Parse(lvwRooms.SelectedItems[0].SubItems[4].Text);
if (editor.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
Room unit = new Room();
unit.RoomNumber = editor.txtRoomNumber.Text;
unit.RoomType = editor.cbxRoomTypes.Text;
unit.BedType = editor.cbxBedTypes.Text;
unit.Rate = double.Parse(editor.txtRate.Text);
unit.Available = editor.chkAvailable.Checked;
lstRooms.SetItem(lstRooms.IndexOf(rm), unit);
string strFilename = dirInfo.FullName + "\\rooms.rms";
FileStream stmRooms = new FileStream(strFilename,
FileMode.Create,
FileAccess.Write);
BinaryFormatter bfmRooms = new BinaryFormatter();
bfmRooms.Serialize(stmRooms, lstRooms);
stmRooms.Close();
}
ShowRooms();
}
}
}
- Return to the form and, under the form, click cmsRooms
- On the form, click Edit Room Details...
- In the Events section of the Properties, click Click and, in its
combo box, select lvwRooms_DoubleClick
- To execute, press F9
- Click Rooms
- Double-click the 105 record
- In the dialog box, change the Bed Type to King
- Change the rate to 95.95
- In the list view, right-click the 114 record and click Edit Room
Details
- In the dialog box, change the rate to 575.00
- Click the Available check box
- Click OK
- Close the forms and return to your programming environment
To let you delete an item from its list, the
Collection<> class provides the RemoveItem()
method. Its syntax is:
protected virtual void RemoveItem(int index);
This method takes as argument the index of the item to
be removed. Once again, a simply implementation would consist of calling the
base method. Here is an example;
public new void RemoveItem(int index)
{
base.RemoveItem(index);
}
An alternative that produces the same effect is to call
the ICollection<>.RemoveAt() method. Here is an example:
public new void RemoveItem(int index)
{
base.RemoveAt(index);
}
Otherwise, when implementing this method, you will
decide what to do if the index is negative or is higher than the total
number of items in the list. Also, you can specify what other actions the
compiler should take when an item is being deleted.
Practical Learning: Deleting an Item
|
|
- On the main menu, click Window -> RoomManagement.cs
- Change the class as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
namespace CeilInn2
{
[Serializable]
public class RoomManagement<T> : Collection<T>
{
public RoomManagement() : base()
{
}
public RoomManagement(IList<T> list) : base(list)
{
}
public virtual new IList<T> Items
{
get
{
return this;
}
}
public new void InsertItem(int index, T item)
{
if (index < 0)
throw new ArgumentOutOfRangeException("The value you provided " +
"for the index is not valid");
else if ((index >= 0) && (index <= Count))
base.InsertItem(index, item);
else // If the index is higher than Count, simply add the item (at the end of the list)
this.Add(item);
}
public new void SetItem(int index, T item)
{
if (index < 0)
return;
else if (index > Count)
return;
else
base.SetItem(index, item);
}
public new void RemoveItem(int index)
{
if (index < 0)
return;
else if (index > Count)
return;
else
base.RemoveItem(index);
}
}
}
- Display the Rooms form and, under the form, click cmsRooms
- On the form, double-click Delete Room
- Implement the event as follows:
private void mnuDeleteRoom_Click(object sender, EventArgs e)
{
if (lvwRooms.SelectedItems.Count == 0)
return;
else if (lvwRooms.SelectedItems.Count == 1)
{
Room rm = new Room();
RoomEditor editor = new RoomEditor();
string Filename = @"C:\Ceil Inn\rooms.rms";
rm.RoomNumber = lvwRooms.SelectedItems[0].Text;
DirectoryInfo dirInfo = Directory.CreateDirectory(@"C:\Ceil Inn");
if (File.Exists(Filename) == true)
{
FileStream stmRooms = new FileStream(Filename,
FileMode.Open,
FileAccess.Read);
BinaryFormatter bfmRooms = new BinaryFormatter();
lstRooms = (RoomManagement<Room>)bfmRooms.Deserialize(stmRooms);
stmRooms.Close();
}
if (lstRooms.IndexOf(rm) >= 0)
{
if( MessageBox.Show("Are you sure you want to delete " +
lvwRooms.SelectedItems[0].SubItems[1].Text +
" " + rm.RoomNumber + "?",
"Ceil Inn", MessageBoxButtons.YesNo,
MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes )
{
lstRooms.RemoveItem(lstRooms.IndexOf(rm));
string strFilename = dirInfo.FullName + "\\rooms.rms";
FileStream stmRooms = new FileStream(strFilename,
FileMode.Create,
FileAccess.Write);
BinaryFormatter bfmRooms = new BinaryFormatter();
bfmRooms.Serialize(stmRooms, lstRooms);
stmRooms.Close();
}
ShowRooms();
}
}
}
- Return to the form
- Right-click the form and click View Code
- Locate the lvwRooms_KeyDown event and change it as follows:
private void lvwRooms_KeyDown(object sender, KeyEventArgs e)
{
if (lvwRooms.SelectedItems.Count == 0)
return;
else if (e.KeyCode == Keys.Insert)
mnuInsertRoom_Click(sender, e);
else if (e.KeyCode == Keys.Delete)
mnuDeleteRoom_Click(sender, e);
}
- To execute, press F9
- Click Rooms
- Right-click the 107 record and click Delete Room
- On the message box, click No
- Right-click the 107 record and click Delete
- On the message box, click Yes
- Close the forms and return to your programming environment
Because the Collection<> class
implements the ICollection interface, it inherits the
Clear() method. To let you create a custom technique to
delete all items from a class, the Collection class is equipped with the
protected ClearItems() method. Its syntax is:
protected virtual void ClearItems();
When overriding this method, if you don't have any
particular way you want to delete items, you can simply call the
Clear() method. Otherwise, define the method as you wish.
|
|