Home

Department Store: Object Serialization

 

Introduction to Serialization

In traditional file processing supported by most compiled languages such as C#, you learn to create values from primitive types (int, double, char, etc) and save them to a medium. Many libraries such as MFC, VCL, and the .NET Framework provide built-in classes you can use to save a variable of your class as if the variable had been created from a primitive data type.

Object serialization consists of saving the state of any object as a whole. Serialization makes it possible to easily create a file-based database since you are able to save and restore the object the same way you would use file processing of primitive types in C++.

 

Practical Learning Practical Learning: Introducing File-Based Databases

  1. Start a new Windows Forms Application named DepartmentStore3
  2. To add a new form, on the main menu, click Project -> Add Windows Form...
  3. In the Templates list of the Add New Item dialog box, make sure Windows Form is selected.
    Set the Name to NewStoreItem and press Enter
  4. Design the form as follows:
     
    Control Name Text Other Properties
    Label   Item #:  
    TextBox txtItemNumber    
    Label   Item Name:  
    TextBox txtItemName    
    Label   Size:  
    TextBox txtSize    
    Label   Unit Price:  
    TextBox txtUnitPrice   AlignText: Right
    Button btnAddItem Add Item  
    Button btnClose Close  
    Form   AcceptButton: btnAddItem
    MaximizeBox: False
    StartPosition: CenterScreen
     
  5. Arrange the Tab Order (View . Tab Order) so the Item # text box is the last in the sequence:
     
    New Store Item - Tab Order
  6. Double-click an unoccupied area of the form and implement its Click event as follows:
     
    using System;
    using System.Drawing;
    using System.Collections;
    using System.ComponentModel;
    using System.Windows.Forms;
    
    namespace DepartmentStore3
    {
    	/// <summary>
    	/// Summary description for NewStoreItem.
    	/// </summary>
    	public class NewStoreItem : System.Windows.Forms.Form
    	{
    		. . . No Change 
    		
    		private System.ComponentModel.Container components = null;
    		ArrayList lstStoreItems;
    
    		. . . No Change 
    			
    		private void InitializeComponent()
    		{
    			. . . No Change 
    			
    		}
    		#endregion
    
    		private void NewStoreItem_Load(object sender, System.EventArgs e)
    		{
    			lstStoreItems = new ArrayList();
    		}
    	}
    }
  7. Return to the New Store Item form and double-click its Close button
  8. Implement the event as follows:
     
    private void btnClose_Click(object sender, System.EventArgs e)
    {
    	Close();
    }
  9. Display the first form (Form1.cs [Design])
  10. Add a button to it with the following properties:
    Text: New Store Item
    Name: btnNewStoreItem
  11. Double-click the New Store Item button and implement its Click event as follows:
     
    private void btnNewStoreItem_Click(object sender, System.EventArgs e)
    {
    	NewStoreItem frmNewItem = new NewStoreItem();
    
    	frmNewItem.Show();
    }
  12. Add a new Windows Form
  13. Set its Name to StoreInventory and press Enter
  14. Design the form as follows:
     
    Department Store - Inventory
    Control Name Text Other Properties
    DataGrid     Auto Format: Colorful 3
    Button bntLoad Load  
    Button btnClose Close  
    Form     AcceptButton: bntLoad
    MaximizeBox: False
    StartPosition: CenterScreen
  15. Double-click the Close button and implement its Click event as follows:
     
    private void btnClose_Click(object sender, System.EventArgs e)
    {
    	 Close();
    }
  16. Display the first form (Form1.cs [Design])
  17. Add a button to it with the following properties:
    Text: Store Inventory
    Name: btnStoreInventory
  18. Double-click the Store Inventory button
  19. Implement its Click event as follows:
     
    private void btnStoreInventory_Click(object sender, System.EventArgs e)
    {
    	StoreInventory frmInventory = new StoreInventory();
    
    	frmInventory.Show();
    }
  20. To add a new form, on the main menu, click Project -> Add Windows Form...
  21. In the Templates list of the Add New Item dialog box, make sure Windows Forms is selected.
    Set the Name to CustomerOrder and press Enter
  22. Design the form as follows:
     
    Department Store - Customer Order
     
    Control Name Text Other Properties
    Label   Item #  
    Label   Description  
    Label   Size  
    Label   Unit Price  
    Label   Qty  
    Label   Sub-Total  
    TextBox txtItemNumber1    
    TextBox txtDescription1    
    TextBox txtSize1    
    TextBox txtUnitPrice1 0.00 TextAlign: Right
    TextBox txtQuantity1 0 TextAlign: Right
    TextBox txtSubTotal1 0.00 TextAlign: Right
    TextBox txtItemNumber2    
    TextBox txtDescription2    
    TextBox txtSize2    
    TextBox txtUnitPrice2 0.00 TextAlign: Right
    TextBox txtQuantity2 0 TextAlign: Right
    TextBox txtSubTotal2 0.00 TextAlign: Right
    TextBox txtItemNumber3    
    TextBox txtDescription3    
    TextBox txtSize3    
    TextBox txtUnitPrice3 0.00 TextAlign: Right
    TextBox txtQuantity3 0 TextAlign: Right
    TextBox txtSubTotal3 0.00 TextAlign: Right
    TextBox txtItemNumber4    
    TextBox txtDescription4    
    TextBox txtSize4    
    TextBox txtUnitPrice4 0.00 TextAlign: Right
    TextBox txtQuantity4 0 TextAlign: Right
    TextBox txtSubTotal4 0.00 TextAlign: Right
    TextBox txtItemNumber5    
    TextBox txtDescription5    
    TextBox txtSize5    
    TextBox txtUnitPrice5 0.00 TextAlign: Right
    TextBox txtQuantity5 0 TextAlign: Right
    TextBox txtSubTotal5 0.00 TextAlign: Right
    TextBox txtItemNumber6    
    TextBox txtDescription6    
    TextBox txtSize6    
    TextBox txtUnitPrice6 0.00 TextAlign: Right
    TextBox txtQuantity6 0 TextAlign: Right
    TextBox txtSubTotal6 0.00 TextAlign: Right
    TextBox txtItemNumber7    
    TextBox txtDescription7    
    TextBox txtSize7    
    TextBox txtUnitPrice7 0.00 TextAlign: Right
    TextBox txtQuantity7 0 TextAlign: Right
    TextBox txtSubTotal7 0.00 TextAlign: Right
    TextBox txtItemNumber8    
    TextBox txtDescription8    
    TextBox txtSize8    
    TextBox txtUnitPrice8 0.00 TextAlign: Right
    TextBox txtQuantity8 0 TextAlign: Right
    TextBox txtSubTotal8 0.00 TextAlign: Right
    Label   This order will be saved in  
    DateTimePicker dtpSaleDate   Format: Custom
    CustomFormat: ddd dd MMM yyyy
    Label   Total Order:  
    TextBox txtTotalOrder 0.00 TextAlign: Right
    Button btnSave Save and Start a New Order  
    Button btnClose Close  
     
  23. Double-click the Close button and implement its Click event as follows:
     
    private void btnClose_Click(object sender, System.EventArgs e)
    {
    	 Close();
    }
  24. Display the first form (Form1.cs [Design])
  25. Add a button to it with the following properties:
    Text: New Customer Order
    Name: btnNewOrder
  26. Double-click the New Customer Order button
  27. Implement its Click event as follows:
     
    private void btnNewOrder_Click(object sender, System.EventArgs e)
    {
    	CustomerOrder frmOrder = new CustomerOrder();
    
    	frmOrder .Show();
    }
  28. Add a new Windows Form and name it DailySales
  29. Design the form as follows:
     
    Control Name Text Other Properties
    Label   View Sales For  
    DateTimePicker dtpSaleDate   Format: Custom
    CustomFormat: ddd dd MMM yyyy
    DataGrid     Auto Format: Colorful 3
    Button btnClose Close  
    Form     MaximizeBox: False
    StartPosition: CenterScreen
  30. Double-click the Close button and implement its Click event as follows:
     
    private void btnClose_Click(object sender, System.EventArgs e)
    {
    	 Close();
    }
  31. Display the first form (Form1.cs [Design])
  32. Add a button to it with the following properties:
    Text: View Daily Sales
    Name: btnDailySales
  33. Double-click the View Daily Sales button
  34. Implement its Click event as follows:
     
    private void btnDailySales_Click(object sender, System.EventArgs e)
    {
    	DailySales frmSales = new DailySales;
    
    	 frmSales.Show();
    }
  35. Return to the main form. Add a new button to it and set its properties as follows:
    Text: Close
    Name: btnClose

     
    Department Store - Switchboard
  36. Double-click the Close button and implement its Click event as follows:
     
    private void btnClose_Click(object sender, System.EventArgs e)
    {
    	Close();
    }
  37. Save all
 

Binary Serialization

The .NET Framework provides all means of serializing any managed class through a concept referred to as binary serialization. To proceed with object serialization, you must first specify the object you would use. As with any other program, you can either use one of the classes built-in the .NET Framework or you can use your own programmer-created class. If you decide to use your own class, you can specify whether the whole class or just some parts of the class can be saved.

Binary serialization consists of saving an object. This object is usually a class that either you create or is provided through the .NET Framework. For a class to be serializable, it must be marked with the Serializable attribute. This means that, when checking the MSDN documentation, any class you see with this attribute is already configured to be serialized. This is the case for almost all list-oriented classes such as Array, ArrayList, etc, including many of the classes we will use when we start studying ADO .NET and relational databases.

If you create your own class and want to be able to save values from its variables, you can (must) mark the class with the Serializable attribute. To do this, type [Serializable] before starting to create the class.

The Serializable attribute informs the compiler that values from the class can be serialized. When creating a serializable class, you have the ability to specify whether all of the member variables of the class can be serialized or just some of them.

Practical Learning Practical Learning: Creating a Serializable Class

  1. To add a new project, on the main menu, click File -> Add Project -> New Project...
  2. In the Project Types list of the Add New Project dialog box, make sure Visual C# Projects is selected
    In the Templates list, click Class Library
  3. Change the Name to StoreItemR2
     
    Add New Project
  4. Click OK
  5. Change the file as follows:
     
    using System;
    
    namespace StoreItemR2
    {
    	/// <summary>
    	/// Summary description for CStoreItem.
    	/// </summary>
    	[Serializable]
    	public class CStoreItem
    	{
    		private string  nbr;
    		private string  nm;
    		private string  sz;
    		private decimal uprice;
    
    		public CStoreItem()
    		{
    			nbr = "";
    			nm  = "";
    			sz  = "";
    			uprice = 0.00M;
    		}
    
    CStoreItem(string number, string name, string size, decimal price)
    		{
    			nbr    = number;
    			nm     = name;
    			sz     = size;
    			uprice = price;
    		}
    
    		public string ItemNumber
    		{
    			get { return nbr; }
    			set { nbr = value; }
    		}
    	
    		public string ItemName
    		{
    			get { return nm; }
    			set { nm = value; }
    		}
    		
    		public string Size
    		{
    			get { return sz;}
    			set { sz = value; }
    		}
    
    		public decimal UnitPrice
    		{
    			get { return uprice; }
    			set { uprice = value; }
    		}
    	}
    }
  6. To create the library, in the Solution Explorer, right-click the StoreItemR2 node and click Build
  7. To get a reference of this library to the department store project, in Solution Explorer, under DepartmentStore3, right-click References and click Add Reference...
  8. In the Add Reference dialog box, click the Projects property page and make sure the StoreItemR2 project is selected:
     
    Add Reference
  9. Click Select and click OK
  10. Change the Load event of the New Store Item form as follows:
     
    private void NewStoreItem_Load(object sender, System.EventArgs e)
    {
    	lstStoreItems = new ArrayList();
    
    	 DateTime tmeNow = DateTime.Now;
    
    	 // Get ready to create a random item number
    	 string strItemNumber = "000000";
    
    	int mls = tmeNow.Millisecond;
     	// Generate two random numbers between 100 and 999
    	Random rndNumber = new Random(mls);
    	int NewNumber1 = rndNumber.Next(100, 999);
     	int NewNumber2 = rndNumber.Next(100, 999);
     	// Create an item number from the random numbers
     	strItemNumber = NewNumber1.ToString() + "-" + NewNumber2.ToString();
    
    	 // Display the created item number in the Item # text box
    	 this.txtItemNumber.Text = strItemNumber;
    }
  11. Display the Customer Order form. Right-click it and click View Code
  12. In the top section of the file, under the other using lines, type using StoreItemR2;
  13. Create a method as follows before the closing of the class:
     
    internal CStoreItem LocateStoreItem(string ItemNumber)
    {
    	StoreItemR2.CStoreItem item = new StoreItemR2.CStoreItem();
    
    	// Get a list of all items in the store
    	for(int i = 0; i < this.lstAvailableItems.Count; i++)
    	{
    		// Get a reference to the current item
    		item = (StoreItemR2.CStoreItem)this.lstAvailableItems[i];
    
    		// If the Item Number of the current item matches the argument,
    		// then return it
    		if( item.ItemNumber == ItemNumber )
    			return item;
    	}
    
    	// If the item was not found, then return nothing;
    	return null;
    }
    }
    }
  14. In the same way, create the following method at the end of the above method:
     
    internal void CalculateTotalOrder()
    {
    	decimal subTotal1, subTotal2, subTotal3,
    		subTotal4, subTotal5, subTotal6,
    		subTotal7, subTotal8;
    		decimal orderTotal;
    
    	// Retrieve the value of each sub total
    	subTotal1 = decimal.Parse(this.txtSubTotal1.Text);
    	subTotal2 = decimal.Parse(this.txtSubTotal2.Text);
    	subTotal3 = decimal.Parse(this.txtSubTotal3.Text);
    	subTotal4 = decimal.Parse(this.txtSubTotal4.Text);
    	subTotal5 = decimal.Parse(this.txtSubTotal5.Text);
    	subTotal6 = decimal.Parse(this.txtSubTotal6.Text);
    	subTotal7 = decimal.Parse(this.txtSubTotal7.Text);
    	subTotal8 = decimal.Parse(this.txtSubTotal8.Text);
    
    	// Calculate the total value of the sub totals
    	orderTotal = subTotal1 + subTotal2 + subTotal3 + 
    		subTotal4 + subTotal5 + subTotal6 +
    		subTotal7 + subTotal8;
    			
    	// Display the total order in the appropriate text box
    	this.txtTotalOrder.Text = orderTotal.ToString("F");
    }
  15. Return to the Customer Order form and click the first text box under Item #
  16. In the Properties window, click the Events button if necessary and double-click its Leave field
  17. Return to the Customer Order form. Click each of the other text boxes under Item #, then, in the Properties window, double-click the Leave field
  18. Implement the events as follows:
     
    private void txtItemNumber1_Leave(object sender, System.EventArgs e)
    {
    	string strItemNumber = this.txtItemNumber1.Text;
    StoreItemR2.CStoreItem item = this.LocateStoreItem(strItemNumber);
    
    	if( item != null )
    	{
    		this.txtDescription1.Text = item.ItemName;
    		this.txtSize1.Text        = item.Size;
    	this.txtUnitPrice1.Text   = item.UnitPrice.ToString("F");
    		this.txtQuantity1.Text    = "1";
    	this.txtSubTotal1.Text    = item.UnitPrice.ToString("F");
    
    		CalculateTotalOrder();
    	}
    	else
    	{
    		this.txtItemNumber1.Text  = "";
    		this.txtDescription1.Text = "";
    		this.txtSize1.Text        = "";
    		this.txtUnitPrice1.Text   = "0.00";
    		this.txtQuantity1.Text    = "0";
    		this.txtSubTotal1.Text    = "0.00";
    	}
    }
    
    private void txtItemNumber2_Leave(object sender, System.EventArgs e)
    {	
    	string strItemNumber = this.txtItemNumber2.Text;
    StoreItemR2.CStoreItem item = this.LocateStoreItem(strItemNumber);
    
    	if( item != null )
    	{
    		this.txtDescription2.Text = item.ItemName;
    		this.txtSize2.Text        = item.Size;
    	this.txtUnitPrice2.Text   = item.UnitPrice.ToString("F");
    		this.txtQuantity2.Text    = "1";
    	this.txtSubTotal2.Text    = item.UnitPrice.ToString("F");
    				
    		CalculateTotalOrder();
    	}
    	else
    	{
    		this.txtItemNumber2.Text  = "";
    		this.txtDescription2.Text = "";
    		this.txtSize2.Text        = "";
    		this.txtUnitPrice2.Text   = "0.00";
    		this.txtQuantity2.Text    = "0";
    		this.txtSubTotal2.Text    = "0.00";
    	}
    }
    
    private void txtItemNumber3_Leave(object sender, System.EventArgs e)
    {
    	string strItemNumber = this.txtItemNumber3.Text;
    StoreItemR2.CStoreItem item = this.LocateStoreItem(strItemNumber);
    
    	if( item != null )
    	{
    		this.txtDescription3.Text = item.ItemName;
    		this.txtSize3.Text        = item.Size;
    	this.txtUnitPrice3.Text   = item.UnitPrice.ToString("F");
    		this.txtQuantity3.Text    = "1";
    	this.txtSubTotal3.Text    = item.UnitPrice.ToString("F");
    
    		CalculateTotalOrder();
    	}
    	else
    	{
    		this.txtItemNumber3.Text  = "";
    		this.txtDescription3.Text = "";
    		this.txtSize3.Text        = "";
    		this.txtUnitPrice3.Text   = "0.00";
    		this.txtQuantity3.Text    = "0";
    		this.txtSubTotal3.Text    = "0.00";
    	}
    }
    
    private void txtItemNumber4_Leave(object sender, System.EventArgs e)
    {
    	string strItemNumber = this.txtItemNumber4.Text;
    StoreItemR2.CStoreItem item = this.LocateStoreItem(strItemNumber);
    
    	if( item != null )
    	{
    		this.txtDescription4.Text = item.ItemName;
    		this.txtSize4.Text        = item.Size;
    	this.txtUnitPrice4.Text   = item.UnitPrice.ToString("F");
    		this.txtQuantity4.Text    = "1";
    	this.txtSubTotal4.Text    = item.UnitPrice.ToString("F");
    
    		CalculateTotalOrder();
    	}
    	else
    	{
    		this.txtItemNumber4.Text  = "";
    		this.txtDescription4.Text = "";
    		this.txtSize4.Text        = "";
    		this.txtUnitPrice4.Text   = "0.00";
    		this.txtQuantity4.Text    = "0";
    		this.txtSubTotal4.Text    = "0.00";
    	}
    }
    
    private void txtItemNumber5_Leave(object sender, System.EventArgs e)
    {
    	string strItemNumber = this.txtItemNumber5.Text;
    StoreItemR2.CStoreItem item = this.LocateStoreItem(strItemNumber);
    
    	if( item != null )
    	{
    		this.txtDescription5.Text = item.ItemName;
    		this.txtSize5.Text        = item.Size;
    	this.txtUnitPrice5.Text   = item.UnitPrice.ToString("F");
    		this.txtQuantity5.Text    = "1";
    	this.txtSubTotal5.Text    = item.UnitPrice.ToString("F");
    
    		CalculateTotalOrder();
    	}
    	else
    	{
    		this.txtItemNumber5.Text  = "";
    		this.txtDescription5.Text = "";
    		this.txtSize5.Text        = "";
    		this.txtUnitPrice5.Text   = "0.00";
    		this.txtQuantity5.Text    = "0";
    		this.txtSubTotal5.Text    = "0.00";
    	}
    }
    
    private void txtItemNumber6_Leave(object sender, System.EventArgs e)
    {
    	string strItemNumber = this.txtItemNumber6.Text;
    StoreItemR2.CStoreItem item = this.LocateStoreItem(strItemNumber);
    
    	if( item != null )
    	{
    		this.txtDescription6.Text = item.ItemName;
    		this.txtSize6.Text        = item.Size;
    	this.txtUnitPrice6.Text   = item.UnitPrice.ToString("F");
    		this.txtQuantity6.Text    = "1";
    	this.txtSubTotal6.Text    = item.UnitPrice.ToString("F");
    
    		CalculateTotalOrder();
    	}
    	else
    	{
    		this.txtItemNumber6.Text  = "";
    		this.txtDescription6.Text = "";
    		this.txtSize6.Text        = "";
    		this.txtUnitPrice6.Text   = "0.00";
    		this.txtQuantity6.Text    = "0";
    		this.txtSubTotal6.Text    = "0.00";
    	}
    }
    
    private void txtItemNumber7_Leave(object sender, System.EventArgs e)
    {
    	string strItemNumber = this.txtItemNumber7.Text;
    StoreItemR2.CStoreItem item = this.LocateStoreItem(strItemNumber);
    
    	if( item != null )
    	{
    		this.txtDescription7.Text = item.ItemName;
    		this.txtSize7.Text        = item.Size;
    	this.txtUnitPrice7.Text   = item.UnitPrice.ToString("F");
    		this.txtQuantity7.Text    = "1";
    	this.txtSubTotal7.Text    = item.UnitPrice.ToString("F");
    
    		CalculateTotalOrder();
    	}
    	else
    	{
    		this.txtItemNumber7.Text  = "";
    		this.txtDescription7.Text = "";
    		this.txtSize7.Text        = "";
    		this.txtUnitPrice7.Text   = "0.00";
    		this.txtQuantity7.Text    = "0";
    		this.txtSubTotal7.Text    = "0.00";
    	}
    }
    
    private void txtItemNumber8_Leave(object sender, System.EventArgs e)
    {
    	string strItemNumber = this.txtItemNumber8.Text;
    StoreItemR2.CStoreItem item = this.LocateStoreItem(strItemNumber);
    
    	if( item != null )
    	{
    		this.txtDescription8.Text = item.ItemName;
    		this.txtSize8.Text        = item.Size;
    	this.txtUnitPrice8.Text   = item.UnitPrice.ToString("F");
    		this.txtQuantity8.Text    = "1";
    	this.txtSubTotal8.Text    = item.UnitPrice.ToString("F");
    
    		CalculateTotalOrder();
    	}
    	else
    	{
    		this.txtItemNumber8.Text  = "";
    		this.txtDescription8.Text = "";
    		this.txtSize8.Text        = "";
    		this.txtUnitPrice8.Text   = "0.00";
    		this.txtQuantity8.Text    = "0";
    		this.txtSubTotal8.Text    = "0.00";
    	}
    }
  19. At the end of the above methods, create the following method:
     
    internal decimal CalculateSubTotal(string  strPrice, string  strQuantity)
    {
    	int qty = 0;
    	decimal unitPrice = 0.00M, subTotal;
    	
    	try 
    	{
    		// Get the quantity of the current item
    		qty = int.Parse(strQuantity);
    	}
    	catch(FormatException)
    	{
    	MessageBox.Show("The value you provided for the quantity of the item is invalid" +
    					"\nPlease try again");
    	}
    			
    	try 
    	{
    		// Get the unit price of the current item
    		unitPrice = decimal.Parse(strPrice);
    	}
    	catch(FormatException )
    	{
    	MessageBox.Show("The unit price you provided for item is invalid" +
    					"\nPlease try again");
    	}
    	// Calculate the current sub total
    	subTotal = qty * unitPrice;
    
    	return subTotal;
    }
  20. Display the Customer Order form again and click the first text box under Qty
  21. In the Properties window and in the Events section, double-click the Leave field
  22. Return to the form, click each of the other Qty text boxes, and in the Properties window, click the Leave field of each Qty
  23. Implement their events as follows:
     
    private void txtQuantity1_Leave(object sender, System.EventArgs e)
    		{
    			string strUnitPrice = this.txtUnitPrice1.Text;
    			string strQty = this.txtQuantity1.Text;
    			decimal subTotal = this.CalculateSubTotal(strUnitPrice, strQty);
    	
    			// Display the new sub total in the corresponding text box
    			this.txtSubTotal1.Text = subTotal.ToString("F");
    			// Update the order
    			CalculateTotalOrder();
    		}
    
    		private void txtQuantity2_Leave(object sender, System.EventArgs e)
    		{
    			string strUnitPrice = this.txtUnitPrice2.Text;
    			string strQty = this.txtQuantity2.Text;
    			decimal subTotal = this.CalculateSubTotal(strUnitPrice, strQty);
    	
    			this.txtSubTotal2.Text = subTotal.ToString("F");
    			CalculateTotalOrder();
    		}
    
    		private void txtQuantity3_Leave(object sender, System.EventArgs e)
    		{
    			string strUnitPrice = this.txtUnitPrice3.Text;
    			string strQty = this.txtQuantity3.Text;
    			decimal subTotal = this.CalculateSubTotal(strUnitPrice, strQty);
    	
    			this.txtSubTotal3.Text = subTotal.ToString("F");
    			CalculateTotalOrder();
    		}
    
    		private void txtQuantity4_Leave(object sender, System.EventArgs e)
    		{
    			string strUnitPrice = this.txtUnitPrice4.Text;
    			string strQty = this.txtQuantity4.Text;
    			decimal subTotal = this.CalculateSubTotal(strUnitPrice, strQty);
    	
    			this.txtSubTotal4.Text = subTotal.ToString("F");
    			CalculateTotalOrder();
    		}
    
    		private void txtQuantity5_Leave(object sender, System.EventArgs e)
    		{
    			string strUnitPrice = this.txtUnitPrice5.Text;
    			string strQty = this.txtQuantity5.Text;
    			decimal subTotal = this.CalculateSubTotal(strUnitPrice, strQty);
    	
    			this.txtSubTotal5.Text = subTotal.ToString("F");
    			CalculateTotalOrder();
    		}
    
    		private void txtQuantity6_Leave(object sender, System.EventArgs e)
    		{
    			string strUnitPrice = this.txtUnitPrice6.Text;
    			string strQty = this.txtQuantity6.Text;
    			decimal subTotal = this.CalculateSubTotal(strUnitPrice, strQty);
    
    			this.txtSubTotal6.Text = subTotal.ToString("F");
    			CalculateTotalOrder();
    		}
    
    		private void txtQuantity7_Leave(object sender, System.EventArgs e)
    		{
    			string strUnitPrice = this.txtUnitPrice7.Text;
    			string strQty = this.txtQuantity7.Text;
    			decimal subTotal = this.CalculateSubTotal(strUnitPrice, strQty);
    	
    			this.txtSubTotal7.Text = subTotal.ToString("F");
    			CalculateTotalOrder();
    		}
    
    		private void txtQuantity8_Leave(object sender, System.EventArgs e)
    		{
    			string strUnitPrice = this.txtUnitPrice8.Text;
    			string strQty = this.txtQuantity8.Text;
    			decimal subTotal = this.CalculateSubTotal(strUnitPrice, strQty);
    	
    			this.txtSubTotal8.Text = subTotal.ToString("F");
    			CalculateTotalOrder();
    		}
  24. Save all

The Process of Serializing

To support serialization of an object, the .NET Framework provides the BinaryFormatter class from the System.Runtime.Serialization.Formatters.Binary namespace. This class is derived from Object but implements the IRemotingFormatter and the IFormatter interfaces. One of the methods of this class is called Serialize. This method is overloaded with two versions. The syntax of the first version is:

public virtual void Serialize(Stream serializationStream, object graph);

The first argument of this method is a stream object that will carry the details of the streaming process. It must be a class derived from Stream. The second argument is a variable that carries the value(s) to be saved. It can be an instance of a class you created or a variable declared from a .NET Framework serializable class.

Practical Learning Practical Learning: Serializing an Object

  1. Display the New Store Item form and click an empty area of its body
  2. In the events section of the Properties window, double-click the Deactivate field
  3. Implement the event as follows:
     
    private void NewStoreItem_Deactivate(object sender, System.EventArgs e)
    {
    	string strFilename = "StoreItems.sti";
    	 FileStream fStream = new FileStream(strFilename, FileMode.Create);
    	 BinaryFormatter binFormat = new BinaryFormatter();
    
    	 try {
    		 binFormat.Serialize(fStream, this.lstStoreItems);
    	 }
    	 catch(ArgumentNullException )
    	 {
    		 MessageBox.Show("The inventory could not be accessed");
    	 }
    	 catch(SerializationException )
    	 {
    		 MessageBox.Show("The inventory could not be saved");
    	 }
    	 finally {
    		 fStream.Close();
    	 }
    }
  4. Save all

Object Deserialization

The opposite of serialization is deserialization. Deserialization is the process of retrieving an object that was serialized. When this is done, an exact copy of the object that was saved is created and restored as the origin.

To support deserialization, the BinaryFormatter class provides the Deserialize() method, which is overloaded in two versions. The syntax of the first version:

public virtual object Deserialize(Stream serializationStream);

This method as argument the object that holds the file and the details on how the file will be opened.

Practical Learning Practical Learning: Deserializing an Object

  1. Display the New Item Store form and click an unoccupied area of its body to make sure the form is selected.
    In the Properties window, click the Events button if necessary.
    In the events list, double-click the Activated field
  2. Implement the event as follows:
     
    using System;
    using System.Drawing;
    using System.Collections;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.IO;
    using System.Runtime.Serialization;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace DepartmentStore3
    {
    	/// <summary>
    	/// Summary description for NewStoreItem.
    	/// </summary>
    	public class NewStoreItem : System.Windows.Forms.Form
    	{
    		. . . No Change
    		
    		private System.ComponentModel.Container components = null;
    		ArrayList lstStoreItems;
    
    		. . . No Change
    		
    		private void InitializeComponent()
    		{
    			. . . No Change
    
    		}
    		#endregion
    
    . . . No Change
    
    private void NewStoreItem_Activated(object sender, System.EventArgs e)
    {
    	// This file holds the items sold in the store
    	 string strFilename = "StoreItems.sti";
    	 FileStream fStream = null;
    
    	 if( File.Exists(strFilename) )
    	 {
    		 try {
    			 // Create a stream of store items
    			 fStream = new FileStream(strFilename, FileMode.Open);
                         
    			 BinaryFormatter binFormat = new BinaryFormatter();
    			 lstStoreItems = (ArrayList)binFormat.Deserialize(fStream);
    		 }
    		 catch(ArgumentNullException )
    		 {
    			 MessageBox.Show("The inventory could not be accessed");
    		 }
    		 catch(SerializationException )
    		 {
    			 MessageBox.Show("The application failed to retrieve the inventory");
    		 }
    		 finally
    		 {
    			 fStream.Close();
    		 }
    	 }
    	 else
    		 return;
    }
  3. Return to the New Store Item form.
    Double-click its Add Item button and implement its Click event as follows:
     
    private void btnAddItem_Click(object sender, System.EventArgs e)
    {
    	StoreItemR2.CStoreItem item = new StoreItemR2.CStoreItem();
    	 
    	// Make sure the record is complete before attempting to add it
    	if( this.txtItemNumber.Text == "" )
    		return;
    	if( this.txtItemName.Text == "" )
    		return;
    	if( this.txtUnitPrice.Text == "" )
    		return;
    
    	// Now the record seems to be ready: build it
    	item.ItemNumber = this.txtItemNumber.Text;
    	item.ItemName   = this.txtItemName.Text;
    	item.Size       = this.txtSize.Text;
    	item.UnitPrice  = decimal.Parse(this.txtUnitPrice.Text);
    	// Add the record
    	this.lstStoreItems.Add(item);
    	DateTime tmeNow = DateTime.Now;
    
    	// Get ready to create a unique item number
    	bool FoundUniqueNumber = false;
    	string strItemNumber = "000000";
    
    	do 
    	{
    		int mls = tmeNow.Millisecond;
    		// Generate two random numbers between 100 and 999
    		Random rndNumber = new Random(mls);
    		int NewNumber1 = rndNumber.Next(100, 999);
    		int NewNumber2 = rndNumber.Next(100, 999);
    		// Create an item number from the random numbers
    		strItemNumber = NewNumber1.ToString() + "-" + NewNumber2.ToString();
    
    		// Find out if the item number created already exists in the database
    		// If it does, then create another
    		for(int i = 0; i < this.lstStoreItems.Count; i++)
    		{
    			item = (StoreItemR2.CStoreItem)this.lstStoreItems[i];
    
    			if( item.ItemNumber == strItemNumber )
    				FoundUniqueNumber = true;
    		}
    	}while(FoundUniqueNumber == false);
    
    	// Reset the form for a new record
    	this.txtItemNumber.Text = strItemNumber;
    	this.txtItemName.Text = "";
    	this.txtSize.Text = "";
    	this.txtUnitPrice.Text = "";
    	this.txtItemName.Focus();
    }
  4. Execute the application and create a few items (let the computer generate the item numbers):
     
    Item Name Size Unit Price
    Women Cashmere Lined Glove 8 115.95
    Men Trendy Jacket Medium 45.85
    Women Stretch Flare Jeans Petite 27.75
    Women Belted Sweater L 15.95
    Girls Classy Handbag One Size 95.95
    Women Casual Dress Shoes 9.5M 45.95
    Boys Hooded Sweatshirt M (7/8) 15.95
    Girls Velour Dress 10 12.55
    Women Lace Desire Panty M 7.15
    Infant Girls Ballerina Dress 12M 22.85
    Men Classic Pinstripe Suit 38 145.95
  5. Close the forms and return to your programming environment
  6. Display the Store Inventory form and double-click its Load button
  7. In the top section of the file, under the other using lines, type:
     
    using System.IO;
    using System.Runtime.Serialization;
    using System.Runtime.Serialization.Formatters.Binary;
  8. Implement its Click event as follows:
     
    private void btnLoad_Click(object sender, System.EventArgs e)
    {
    	ArrayList lstItems= new ArrayList();
    	 string strFilename = "StoreItems.sti";
    				 
    	 if( File.Exists(strFilename) )
    	 {
    		 FileStream fStream = new FileStream(strFilename, FileMode.Open);
    
    		 try {
    			 BinaryFormatter binFormat = new BinaryFormatter();
    			 lstItems = (ArrayList)binFormat.Deserialize(fStream);
    
    			 this.dataGrid1.DataSource = 0;
    			 this.dataGrid1.DataSource = lstItems;
    		 }	 
    		 catch(ArgumentNullException )
    		 {
    			 MessageBox.Show("The inventory could not be accessed");
    		 }
    		 catch(SerializationException )
    		{
    			 MessageBox.Show("The application failed to retrieve the inventory");
    		 }
    		 finally
    		 {
    			 fStream.Close();
    		 }
    	 }
    }
  9. Execute the application
  10. Click the Store Inventory button and click the Load button to display the inventory
     
    Department Store - Inventory
  11. Close the forms and return to your programming environment
  12. Display the Customer Order form and click an unoccupied area of its body to make sure the form is selected.
    In the Properties window, click the Events button.
  13. In the events list, double-click the Activated field
  14. Implement the event as follows:
     
    using System;
    using System.Drawing;
    using System.Collections;
    using System.ComponentModel;
    using System.Windows.Forms;
    using StoreItemR2;
    using System.IO;
    using System.Runtime.Serialization;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace DepartmentStore3
    {
    	/// <summary>
    	/// Summary description for CustomerOrder.
    	/// </summary>
    	public class CustomerOrder : System.Windows.Forms.Form
    	{
    		
    
    		. . . No Change
    			
    		
    		/// <summary>
    		/// Required designer variable.
    		/// </summary>
    		private System.ComponentModel.Container components = null;
    		ArrayList lstAvailableItems;
    					
    
    
    		. . . No Change
    			
    		
    
    private void CustomerOrder_Activated(object sender, System.EventArgs e)
    {
    	lstAvailableItems = new ArrayList();
    			 
    	 // This file holds the items sold in the store
    	 string strFilename = "StoreItems.sti";
    	 FileStream fStream = null;
    
    	 if( File.Exists(strFilename) )
    	 {
    		 try {
    			 // Create a stream of store items
    			 fStream = new FileStream(strFilename, FileMode.Open);
                         
    			 BinaryFormatter binFormat = new BinaryFormatter();
    			 lstAvailableItems = (ArrayList)binFormat.Deserialize(fStream);
    		 }
    		 catch(ArgumentNullException )
    		 {
    			 MessageBox.Show("The inventory could not be accessed");
    		 }
    		 catch(SerializationException )
    		 {
    			 MessageBox.Show("The application failed to retrieve the inventory");
    		 }
    		 finally
    		 {
    			 fStream.Close();
    		 }
    	 }
    	 else
    		 return;
    }
  15. To add a new project, in the Solution Explorer, right-click Solution Department3 (2 Projects), position the mouse on Add and click New Project...
  16. In the Project Types list of the Add New Project dialog box, make sure Visual C# Projects is selected
    In the Templates list, click Class Library
  17. Change the Name to SalesInventory and click OK
  18. Change the file as follows:
     
    using System;
    
    namespace SalesInventory
    {
    	/// <summary>
    	/// Summary description for Class1.
    	/// </summary>
    	[Serializable]
    	public class CSaleInventory
    	{
    		private string strNbr;
    		private string strName;
    		private string strSize;
    		private decimal  uPrice;
    		private int     iQty;
    		private decimal  stotal;
    
    		public CSaleInventory()
    		{
    			strNbr  = "";
    			strName = "";
    			strSize = "";
    			uPrice  = 0.00M;
    			iQty    = 0;
    			stotal  = 0.00M;
    		}
    
    		CSaleInventory(string number, string name, string size,
    			decimal price, int qty, decimal total)
    		{
    			strNbr  = number;
    			strName = name;
    			strSize = size;
    			uPrice  = price;
    			iQty    = qty;
    			stotal  = total;
    		}
    		
    		public string ItemNumber
    		{
    			get { return strNbr; }
    			set { strNbr = value; }
    		}
    
    		public string ItemName
    		{
    			get { return strName; }
    			set { strName = value; }
    		}
    		
    		public string Size
    		{
    			get { return strSize; }
    			set { strSize = value; }
    		}
    
    		public decimal UnitPrice
    		{
    			get { return uPrice; }
    			set { uPrice = value; }
    		}
    
    		public int Quantity
    		{
    			get { return iQty; }
    			set { iQty = value; }
    		}
    
    		public decimal SubTotal
    		{
    			get { return stotal; }
    			set { stotal = value; }
    		}
    	}
    }
  19. To create the library, in the Solution Explorer, right-click the SalesInventory node and click Build
  20. To get a reference of this library to the department store project, in Solution Explorer, under DepartmentStore3, right-click References and click Add Reference...
  21. In the Projects property page, click SalesInventory and click Select
  22. Click OK
  23. Display the Customer Order form
  24. Double-click the Save And Start New Order button and implement its Click event as follows:
     
    private void btnSaveOrder_Click(object sender, System.EventArgs e)
    {
    	 DateTime dteCurrent = this.dtpSaleDate.Value;
    	 int month = dteCurrent.Month;
    	 int day   = dteCurrent.Day;
    	 int year  = dteCurrent.Year;
    			 
    	 string strFilename = month.ToString() + "-" + day.ToString() +
                              "-" + year.ToString() + ".dly";
    	 ArrayList lstCurrentSoldItems = new ArrayList();
    	 SalesInventory.CSaleInventory curOrder = null;
    	 FileStream fStream = null;
    	 BinaryFormatter binFormat = new BinaryFormatter();
    
    	// If this is not the first order of this file, then first open the file
    	 // and store its orders in a temporary list
    	 if( File.Exists(strFilename) )
    	 {
    		 try {
    			 // Create a stream of store items
    			 fStream = new FileStream(strFilename, FileMode.Open, FileAccess.Read, FileShare.Read);
    
    			 lstCurrentSoldItems = (ArrayList)binFormat.Deserialize(fStream);
    		 }
    		 catch(ArgumentNullException )
    		 {
    			 MessageBox.Show("The inventory could not be accessed");
    		 }
    		 catch(SerializationException )
    		 {
    			 MessageBox.Show("The application failed to retrieve the inventory");
    		 }
    		 finally
    		 {
    			 fStream.Close();
    		 }
    	 }
    
    	 // Whether the file existed already or not, add the current items to the list
    	 if( this.txtItemNumber1.Text != "" )
    	 {
    		 curOrder = new SalesInventory.CSaleInventory();
    		 curOrder.ItemNumber = this.txtItemNumber1.Text;
    		 curOrder.ItemName   = this.txtDescription1.Text;
    		 curOrder.Size       = this.txtSize1.Text;
    		 curOrder.UnitPrice  = decimal.Parse(this.txtUnitPrice1.Text);
    		 curOrder.Quantity   = int.Parse(this.txtQuantity1.Text);
    		 curOrder.SubTotal   = decimal.Parse(this.txtSubTotal1.Text);
    		 lstCurrentSoldItems.Add(curOrder);
    	 }
    
    	 if( this.txtItemNumber2.Text != "" )
    	 {
    		 curOrder = new SalesInventory.CSaleInventory();
    		 curOrder.ItemNumber = this.txtItemNumber2.Text;
    		 curOrder.ItemName   = this.txtDescription2.Text;
    		 curOrder.Size       = this.txtSize2.Text;
    		 curOrder.UnitPrice  = decimal.Parse(this.txtUnitPrice2.Text);
    		 curOrder.Quantity   = int.Parse(this.txtQuantity2.Text);
    		 curOrder.SubTotal   = decimal.Parse(this.txtSubTotal2.Text);
    		 lstCurrentSoldItems.Add(curOrder);
    	 }
    
    	 if( !this.txtItemNumber3.Text.Equals("") )
    	 {
    		 curOrder = new SalesInventory.CSaleInventory();
    		 curOrder.ItemNumber = this.txtItemNumber3.Text;
    		 curOrder.ItemName   = this.txtDescription3.Text;
    		 curOrder.Size       = this.txtSize3.Text;
    		 curOrder.UnitPrice  = decimal.Parse(this.txtUnitPrice3.Text);
    		 curOrder.Quantity   = int.Parse(this.txtQuantity3.Text);
    		 curOrder.SubTotal   = decimal.Parse(this.txtSubTotal3.Text);
    		 lstCurrentSoldItems.Add(curOrder);
    	 }
    
    	 if( !this.txtItemNumber4.Text.Equals("") )
    	 {
    		 curOrder = new SalesInventory.CSaleInventory();
    		 curOrder.ItemNumber = this.txtItemNumber4.Text;
    		 curOrder.ItemName   = this.txtDescription4.Text;
    		 curOrder.Size       = this.txtSize4.Text;
    		 curOrder.UnitPrice  = decimal.Parse(this.txtUnitPrice4.Text);
    		 curOrder.Quantity   = int.Parse(this.txtQuantity4.Text);
    		 curOrder.SubTotal   = decimal.Parse(this.txtSubTotal4.Text);
    		 lstCurrentSoldItems.Add(curOrder);
    	 }
    
    	 if( !this.txtItemNumber5.Text.Equals("") )
    	 {
    		 curOrder = new SalesInventory.CSaleInventory();
    		 curOrder.ItemNumber = this.txtItemNumber5.Text;
    		 curOrder.ItemName   = this.txtDescription5.Text;
    		 curOrder.Size       = this.txtSize5.Text;
    		 curOrder.UnitPrice  = decimal.Parse(this.txtUnitPrice5.Text);
    		 curOrder.Quantity   = int.Parse(this.txtQuantity3.Text);
    		 curOrder.SubTotal   = decimal.Parse(this.txtSubTotal5.Text);
    		 lstCurrentSoldItems.Add(curOrder);
    	 }
    
    	 if( !this.txtItemNumber6.Text.Equals("") )
    	 {
    		 curOrder = new SalesInventory.CSaleInventory();
    		 curOrder.ItemNumber = this.txtItemNumber6.Text;
    		 curOrder.ItemName   = this.txtDescription6.Text;
    		 curOrder.Size       = this.txtSize6.Text;
    		 curOrder.UnitPrice  = decimal.Parse(this.txtUnitPrice6.Text);
    		 curOrder.Quantity   = int.Parse(this.txtQuantity6.Text);
    		 curOrder.SubTotal   = decimal.Parse(this.txtSubTotal6.Text);
    		 lstCurrentSoldItems.Add(curOrder);
    	 }
    
    	 if( !this.txtItemNumber7.Text.Equals("") )
    	 {
    		 curOrder = new SalesInventory.CSaleInventory();
    		 curOrder.ItemNumber = this.txtItemNumber7.Text;
    		 curOrder.ItemName   = this.txtDescription7.Text;
    		 curOrder.Size       = this.txtSize7.Text;
    		 curOrder.UnitPrice  = decimal.Parse(this.txtUnitPrice7.Text);
    		 curOrder.Quantity   = int.Parse(this.txtQuantity7.Text);
    		 curOrder.SubTotal   = decimal.Parse(this.txtSubTotal7.Text);
    		 lstCurrentSoldItems.Add(curOrder);
    	 }
    
    	 if( !this.txtItemNumber8.Text.Equals("") )
    	 {
    		 curOrder = new SalesInventory.CSaleInventory();
    		 curOrder.ItemNumber = this.txtItemNumber8.Text;
    		 curOrder.ItemName   = this.txtDescription8.Text;
    		 curOrder.Size       = this.txtSize8.Text;
    		 curOrder.UnitPrice  = decimal.Parse(this.txtUnitPrice8.Text);
    		 curOrder.Quantity   = int.Parse(this.txtQuantity8.Text);
    		 curOrder.SubTotal   = decimal.Parse(this.txtSubTotal8.Text);
    		 lstCurrentSoldItems.Add(curOrder);
    	 }
    
    	 fStream = new FileStream(strFilename, FileMode.Create, FileAccess.Write, FileShare.None);
    
    	 try {
    		 binFormat.Serialize(fStream, lstCurrentSoldItems);
    	 }
    	 catch(ArgumentNullException )
    	 {
    		 MessageBox.Show("The customer order could not be accessed");
    	 }
    	 catch(SerializationException )
    	 {
    		 MessageBox.Show("The customer order could not be saved");
    	 }
    	 finally
    	 {
    		 fStream.Close();
    	 }
    
    	 // Reset the order
    	 this.txtItemNumber1.Text = "";
    	 this.txtItemNumber2.Text = "";
    	 this.txtItemNumber3.Text = "";
    	 this.txtItemNumber4.Text = "";
    	 this.txtItemNumber5.Text = "";
    	 this.txtItemNumber6.Text = "";
    	 this.txtItemNumber7.Text = "";
    	 this.txtItemNumber8.Text = "";
    
    	 this.txtItemNumber1_Leave(sender, e);
    	 this.txtItemNumber2_Leave(sender, e);
    	 this.txtItemNumber3_Leave(sender, e);
    	 this.txtItemNumber4_Leave(sender, e);
    	 this.txtItemNumber5_Leave(sender, e);
    	 this.txtItemNumber6_Leave(sender, e);
    	 this.txtItemNumber7_Leave(sender, e);
    	 this.txtItemNumber8_Leave(sender, e);
    
    	 this.txtTotalOrder.Text = "0.00";
    	 this.dtpSaleDate.Value = DateTime.Today;
    	 
    	 this.txtItemNumber1.Focus();
    }
  25. Execute the application
  26. Click the Store Inventory button and click the Load button to display the inventory
  27. Keep the inventory form opened and from the main form, click the Customer Order button
  28. Process a few orders and save them at different dates. Write on a piece of paper the dates the orders are saved
  29. Close the forms and return to your programming environment
  30. Display the Daily Sales form
  31. Double-click the Date Time Picker control on it
  32. Implement its event as follows:
     
    using System;
    using System.Drawing;
    using System.Collections;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.IO;
    using System.Runtime.Serialization;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace DepartmentStore3
    {
    	. . . No Change
    
    private void dtpSaleDate_ValueChanged(object sender, System.EventArgs e)
    {
    	 DateTime dteCurrent = this.dtpSaleDate.Value;
    	 int month = dteCurrent.Month;
    	 int day   = dteCurrent.Day;
    	 int year  = dteCurrent.Year;
    			 
    	 string strFilename = month.ToString() + "-" + day.ToString() + "-" + year.ToString() + ".dly";
    
    	 ArrayList lstDaySoldItems = new ArrayList();
    	 BinaryFormatter binFormat = new BinaryFormatter();
    
    	// Find out if the file exists, that is, if some orders were placed on that day
    	 if( File.Exists(strFilename) )
    	 {
    		 FileStream fStream = new FileStream(strFilename, FileMode.Open, FileAccess.Read, FileShare.Read);
    
    		 try {
    			 binFormat = new BinaryFormatter();
    			 lstDaySoldItems = (ArrayList)binFormat.Deserialize(fStream);
    
    			 this.dataGrid1.DataSource = 0;
    			 this.dataGrid1.DataSource = lstDaySoldItems;
    		 }	 
    		 catch(ArgumentNullException )
    		 {
    			 MessageBox.Show("The inventory could not be accessed");
    		 }
    		 catch(SerializationException )
    		{
    			 MessageBox.Show("The application failed to retrieve the inventory");
    		 }
    		 finally
    		 {
    			 fStream.Close();
    		 }
    	 }
    	 else
    		 this.dataGrid1.DataSource = 0;
    }
  33. Execute the application and test all objects
 

Home Copyright © 2004-2010 FunctionX, Inc.