Home

.NET Framwork Collections: The Collection Class

   

Fundamentals of the Collection Class

 

Introduction

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.

ApplicationPractical Learning: Introducing the Collection Class

  1. Start Microsoft Visual C#
  2. To create a new application, on the main menu, click File -> New Project
  3. In the middle list, click Windows Forms Application
  4. Change the Name to CeilInn2
  5. Click OK
  6. To create a new class, on the main menu, click Project -> Add Class...
  7. Set the Name to Customer
  8. Click Add
  9. 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;
            }
        }
    }
  10. To create a new form, on the main menu, click Project -> Add Windows Form...
  11. Set the name to CustomerEditor
  12. Click Add
  13. Design the form as follows:
     
    Ceil Inn - Customer Editor
    Control (Name) Text Modifiers Other Properties
    Label Label   Account Number:    
    MaskTextBox MaskTextBox txtAccountNumber   Public Mask: 000-000
    Label Label   Full Name:    
    TextBox TextBox txtFullName   Public  
    Label Label   Phone Number:    
    TextBox TextBox txtPhoneNumber   Public  
    Label Label   Emergency Name:    
    TextBox TextBox txtEmergencyName   Public  
    Label Label   Emergency Phone:    
    TextBox TextBox txtEmergencyPhone   Public  
    Button Button btnOK OK   DialogResult: OK
    Button 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
  14. To create a new class, on the main menu, click Project -> Add Class...
  15. Set the Name to Employee
  16. Click Add
  17. 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;
            }
        }
    }
  18. To create a new form, on the main menu, click Project -> Add Windows Form...
  19. Set the name to EmployeeEditor
  20. Click Add
  21. Design the form as follows:
     
    Ceil Inn - Employee Editor
    Control (Name) Text Modifiers Other Properties
    Label Label   Employee Number:    
    MaskTextBox MaskTextBox txtEmployeeNumber   Public Mask: 00-000
    Label Label   First Name:    
    TextBox TextBox txtFirstName   Public  
    Label Label   Last Name:    
    TextBox TextBox txtLastName   Public  
    Label Label   Title:    
    TextBox TextBox txtTitle   Public  
    Button Button btnOK OK   DialogResult: OK
    Button 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
  22. To create a new class, on the main menu, click Project -> Add Class...
  23. Set the Name to Room
  24. Click Add
  25. 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;
            }
        }
    }
    
  26. To create a new form, on the main menu, click Project -> Add Windows Form...
  27. Set the name to RoomEditor
  28. Click Add
  29. Design the form as follows:
     
    Ceil Inn - Room Editor
    Control (Name) Text Modifiers Other Properties
    Label Label   Room Number:    
    TextBox TextBox txtRoomNumber      
    Label Label   Room Type:    
    ComboBox ComboBox cbxRoomTypes   Public Items:
    Bedroom
    Conference Room
    Other
    Label Label   Bed Type:    
    ComboBox ComboBox cbxBedTypes   Public Items:
    King
    Queen
    Double
    Other
    Label Label   Rate:    
    TextBox TextBox txtRate 0.00 Public TextAlign: Right
    CheckBox CheckBox chkAvailable Available Public CheckAlign: MiddleRight
    Button Button btnOK OK   DialogResult: OK
    Button 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
  30. To create a new class, on the main menu, click Project -> Add Class...
  31. Set the Name to Occupancy
  32. Click Add
  33. 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;
            }
        }
    }
  34. To create a new form, on the main menu, click Project -> Add Windows Form...
  35. Set the name to OccupancyEditor
  36. Click Add
  37. Design the form as follows:
     
    Ceil Inn - Occupancy Editor
    Control (Name) Text Modifiers Other Properties
    Label Label   Date Occupied:    
    DateTimePicker DateTimePicker dtpDateOccupied   Public  
    Label Label   Processed by ____    
    Label Label   Employee #:    
    MaskTextBox MaskTextBox txtEmployeNumber   Public Mask: 00-000
    TextBox TextBox txtEmployeNme   Public  
    Label Label   Processed for ___    
    Label Label   Customer #:    
    MaskTextBox MaskTextBox txtCustomerNumber   Public Mask: 000-000
    TextBox TextBox txtCustomerName   Public  
    Label Label   Room Rented ____    
    Label Label   Room Number:    
    ComboBox ComboBox cbxRoomNumbers   Public  
    TextBox TextBox txtRoomDescription   Public  
    Label Label   Rate Applied:    
    TextBox TextBox txtRateApplied 0.00 Public TextAlign: Right
    Label Label   Phone Use:    
    TextBox TextBox txtPhoneUse 0.00 Public TextAlign: Right
    Label Label   _______________    
    MaskTextBox MaskTextBox txtOccupanyNumber     Mask: 000-000-0000
    Button Button btnOK OK   DialogResult: OK
    Button 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;
    }
}

Collection

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();
        }
    }
}
Collection Collection
Collection Collection
   

ApplicationPractical Learning: Using a Collection Class

  1. To create a new form, in the Solution Explorer, right-click CeilInn2 -> Add -> Windows Form...
  2. Set the name to Customers
  3. Click Add
  4. In the Toolbox, click ListView and click the form
  5. Right-click it and click Edit Columns
  6. 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
  7. Click OK
  8. Design the form as follows:
     
    Ceil Inn - Customers Records
    Control (Name) Text Other Properties
    ListView ListView lvwCustomers   FullRowSelect: True
    GridLines: True
    View: Details
    Button Button btnNewCustomer New Customer...  
    Button Button btnClose Close  
  9. 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();
            }
        }
    }
  10. Return to the form
  11. Double-click the New Customer button
  12. 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();
        }
    }
  13. Return to the form and double-click the Close button
  14. Implement it as follows:
    private void btnClose_Click(object sender, EventArgs e)
    {
        Close();
    }
  15. To create a new form, on the main menu, click Project -> Add Windows Form...
  16. Set the name to Employees
  17. Click Add
  18. 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
  19. Click OK
  20. Design the form as follows:
     
    Ceil Inn - Employees Records
    Control (Name) Text Other Properties
    ListView ListView lvwEmployeess   FullRowSelect: True
    GridLines: True
    View: Details
    Button Button btnNewEmployee New Employee...  
    Button Button btnClose Close  
  21. 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();
            }
        }
    }
  22. Return to the form and double-click the New Employee button
  23. 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();
        }
    }
  24. Return to the form and double-click the Close button
  25. Implement it as follows:
    private void btnClose_Click(object sender, EventArgs e)
    {
        Close();
    }
  26. To create a new form, on the main menu, click Project -> Add Windows Form...
  27. Set the name to Occupancies
  28. Click Add
  29. 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
  30. Click OK
  31. Design the form as follows:
     
    Ceil Inn - Rooms Occupancies
    Control (Name) Text Other Properties
    ListView ListView lvwOccupancies   FullRowSelect: True
    GridLines: True
    View: Details
    Button Button btnNewOccupancy New Occupancy...  
    Button Button btnClose Close  
  32. 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();
            }
        }
    }
  33. Return to the form and double-click the New Occupancy button
  34. 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();
        }
    }
  35. Return to the form and double-click the Close button
  36. Implement it as follows:
    private void btnClose_Click(object sender, EventArgs e)
    {
        Close();
    }

Creating a Collection<> Class

 

Introduction

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.

ApplicationPractical Learning: Using a Collection Class

  1. To create a new class, on the main menu, click Project -> Add Class...
  2. Set the Name to RoomManagement
  3. Click Add
  4. 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()
    	{
    	}
        }
    }

Copying a Collection

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;
        }
    }
}

Collection  Collection

Of course, you can also perform all the other allowed operations on the new collection.

ApplicationPractical Learning: Getting Items From a Collection

  1. 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;
                }
            }
        }
    }

Inserting an Item

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);
    }
}

Collection  Collection

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.

ApplicationPractical Learning: Creating or Inserting an Item

  1. 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);
            }
        }
    }
  2. To create a new form, on the main menu, click Project -> Add Windows Form...
  3. Set the name to Rooms
  4. Click Add
  5. In the Menus & Toolbars section of the Toolbox, click ContextMenuStrip and click the form
  6. 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
  7. 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
  8. Click OK
  9. Design the form as follows:
     
    Ceil Inn - Rooms Records
    Control (Name) Text Other Properties
    ListView ListView lvwRooms   ContextMenuStrip: cmsRooms
    FullRowSelect: True
    GridLines: True
    View: Details
    Button Button btnNewRoom New Room...  
    Button Button btnClose Close  
  10. 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();
            }
        }
    }
  11. Return to the form and double-click the New Room button
  12. 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();
        }
    }
  13. Return to the form
  14. Under the form, click cmsRooms
  15. Under ContextMenuStrip, double-click New Room...
  16. Implement the event as follows:
    private void mnuNewRoom_Click(object sender, EventArgs e)
    {
        btnNewRoom_Click(sender, e);
    }
  17. Return to the form and click the list view
  18. In the Properties window, click Events and, in the Events section, double-click ItemSelectionChanged
  19. 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;
        }
    }
  20. Return to the form and, under the form, click cmsRooms
  21. On the form, double-click Insert Room...
  22. 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();
        }
    }
  23. Return to the form and click the list view
  24. In the Events section of the Ribbon, double-click KeyDown
  25. 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);
    }
  26. Return to the form and double-click the Close button
  27. Implement it as follows:
    private void btnClose_Click(object sender, EventArgs e)
    {
        Close();
    }
  28. Display the OccupanyEditor form
  29. 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();
                }
            }
        }
    }
  30. Return to the form
  31. Click the Employee # text box
  32. In the Events section of the Properties window, double-click Leave
  33. 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();
        }
    }
  34. Return to the form and click the Customer # text box
  35. In the Events section of the Properties window, double-click Leave
  36. 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();
        }
    }
  37. Return to the form and double-click the Room Number combo box
  38. 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();
        }
    }
  39. In the Solution Explorer, right-click Form1.cs and click Rename
  40. Type CeilInn.cs and press Enter twice to display the form
  41. Design the form as follows:
     
    Altair Realtors
    Control (Name) Text 
    Button btnCustomers Customers...
    Button btnEmployees Employees...
    Button btnRooms Rooms...
    Button btnOcupancies Occupancies...
    Button btnClose  Close
  42. Double-click the Customers button
  43. Implement its event as follows:
    private void btnCustomers_Click(object sender, EventArgs e)
    {
        Customers clients = new Customers();
        clients.ShowDialog();
    }
  44. Return to the Ceil Inn form and double-click the Employees button
  45. Implement its event as follows:
    private void btnEmployees_Click(object sender, EventArgs e)
    {
        Employees staff = new Employees();
        staff.ShowDialog();
    }
  46. Return to the form and double-click the Rooms button
  47. Implement the event as follows:
    private void btnRooms_Click(object sender, EventArgs e)
    {
        Rooms rms = new Rooms();
        rms.ShowDialog();
    }
  48. Return to the form and double-click the Occupancies button
  49. Implement the event as follows:
    private void btnOccupancies_Click(object sender, EventArgs e)
    {
        Occupancies rentals = new Occupancies();
        rentals.ShowDialog();
    }
  50. Return to the form and double-click the Close button
  51. Implement its event as follows:
    private void btnClose_Click(object sender, EventArgs e)
    {
        Close();
    }
  52. To execute, press F9
  53. Click the Customers button
  54. In the Customers form, click New Customer...
  55. 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
  56. Close the Customers form
  57. Click the Employees button
  58. 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
  59. Close the Employees form
  60. Click the Rooms button
  61. 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
  62. Close the Rooms form
  63. Click Occupancies
  64. 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
  65. Close the Occupancies form
  66. Click the Rooms button
  67. Right-click the 107 row and click Insert Room...
  68. Fill the form with the following values:
    Room #: 106
    Room Type: Bedroom
    Bed Type: Queen
    Rate: 75.85
    Check the Available check box
  69. Click OK
  70. Right-click the 202 record and click Insert Room...
  71. Fill the form with the following values:
    Room #: 110
    Room Type: Conference Room
    Rate: 450.00
    Check the Available check box
  72. Click OK
  73. Right-click the 202 record and click Insert Room...
  74. Fill the form with the following values:
    Room #: 114
    Room Type: Conference Room
    Rate: 625.00
  75. Click OK
  76. Right-click anywhere in the list view and click New Room...
  77. Fill the form with the following values:
    Room #: 210
    Room Type: Bedroom
    Bed Type: King
    Rate: 98.95
  78. Click OK
  79. Right-click the 210 record and click Insert Room...
  80. Fill the form with the following values:
    Room #: 208
    Room Type: Bedroom
    Bed Type: King
    Rate: 115.95
  81. Click OK
  82. Close the Rooms form
  83. Click the Occupancies button
  84. 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
  85. Close the forms and return to your programming environment

Setting an Item

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);
    }
}

Collection  Collection

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.

ApplicationPractical Learning: Changing an Item

  1. On the main menu, click Window -> RoomManagement.cs
  2. 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);
            }
        }
    }
  3. Display the Rooms form
  4. Click the list view
  5. In the Events section of the Properties window, double-click DoubleClick
  6. 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();
            }
        }
    }
  7. Return to the form and, under the form, click cmsRooms
  8. On the form, click Edit Room Details...
  9. In the Events section of the Properties, click Click and, in its combo box, select lvwRooms_DoubleClick
  10. To execute, press F9
  11. Click Rooms
  12. Double-click the 105 record
  13. In the dialog box, change the Bed Type to King
  14. Change the rate to 95.95
  15. In the list view, right-click the 114 record and click Edit Room Details
  16. In the dialog box, change the rate to 575.00
  17. Click the Available check box
  18. Click OK
  19. Close the forms and return to your programming environment

Deleting an Item

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.

ApplicationPractical Learning: Deleting an Item

  1. On the main menu, click Window -> RoomManagement.cs
  2. 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);
            }
        }
    }
  3. Display the Rooms form and, under the form, click cmsRooms
  4. On the form, double-click Delete Room
  5. 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();
            }
        }
    }
  6. Return to the form
  7. Right-click the form and click View Code
  8. 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);
    }
  9. To execute, press F9
  10. Click Rooms
  11. Right-click the 107 record and click Delete Room
  12. On the message box, click No
  13. Right-click the 107 record and click Delete
  14. On the message box, click Yes
  15. Close the forms and return to your programming environment

Clearing the Collection

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.

 

Home Copyright © 2010-2015, FunctionX