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. If you create your own class in C++ and want to save information from its variable, you would have to save one member variable at a time. This is not the easiest job to perform in C++. Fortunately, 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 New Item...
  3. In the Templates list of the Add New Item dialog box, click Windows Forms (.NET)
  4. Set the Name to NewStoreItem and press Enter
  5. 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
     
  6. Arrange the Tab Order (View -> Tab Order) so the Item # text box is the last in the sequence:
     
    New Store Item - Tab Order
  7. Double-click an unoccupied area of the form and implement its Click event as follows:
     
    #pragma once
    
    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;
    
    namespace DepartmentStore3
    {
    	. . . No Change
    
    	private:
    		/// <summary>
    		/// Required designer variable.
    		/// </summary>
    		System::ComponentModel::Container* components;
    		ArrayList *lstStoreItems;
    
    		/// <summary>
    		/// Required method for Designer support - do not modify
    		/// the contents of this method with the code editor.
    		/// </summary>
    		void InitializeComponent(void)
    		{
    			. . . No Change
    
    		}		
    private: System::Void NewStoreItem_Load(System::Object *  sender, System::EventArgs *  e)
    		{
    			lstStoreItems = new ArrayList;
    		}
    
    };
    }
  8. Return to the New Store Item form and double-click its Close button
  9. Implement the event as follows:
     
    System::Void btnClose_Click(System::Object *  sender, System::EventArgs *  e)
    {
    	 Close();
    }
  10. Display the first form (Form1.h [Design])
  11. Add a button to it with the following properties:
    Text: New Store Item
    Name: btnNewStoreItem
  12. Double-click the New Store Item button and implement its Click event as follows:
     
    #pragma once
    
    #include "NewStoreItem.h"
    
    namespace DepartmentStore3
    {
    	using namespace System;
    	using namespace System::ComponentModel;
    	using namespace System::Collections;
    	using namespace System::Windows::Forms;
    	using namespace System::Data;
    	using namespace System::Drawing;
    
    		
    	. . . No Change
    
    	
    	private: System::Void btnNewStoreItem_Click(System::Object *  sender, System::EventArgs *  e)
    			 {
    				 NewStoreItem *frmNewItem = new NewStoreItem();
    
    				 frmNewItem->Show();
    			 }
    
    	};
    }
  13. To add a new form, on the main menu, click Project -> Add New Item...
  14. In the Templates list of the Add New Item dialog box, click Windows Forms (.NET)
  15. Set the Name to StoreInventory and press Enter
  16. 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
  17. Double-click the Close button and implement its Click event as follows:
     
    System::Void btnClose_Click(System::Object *  sender, System::EventArgs *  e)
    {
    	 Close();
    }
  18. Display the first form (Form1.h [Design])
  19. Add a button to it with the following properties:
    Text: Store Inventory
    Name: btnStoreInventory
  20. Double-click the Store Inventory button
  21. In the top section of the file, under the other #include line, type #include "StoreInventory.h"
  22. Implement its Click event as follows:
     
    System::Void btnStoreInventory_Click(System::Object *  sender, System::EventArgs *  e)
    {
    	 StoreInventory *frmInventory = new StoreInventory();
    
    	 frmInventory->Show();
    }
  23. To add a new form, on the main menu, click Project -> Add New Item...
  24. In the Templates list of the Add New Item dialog box, click Windows Forms (.NET) if necessary.
    Set the Name to CustomerOrder and press Enter
  25. 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  
     
  26. Double-click the Close button and implement its Click event as follows:
     
    System::Void btnClose_Click(System::Object *  sender, System::EventArgs *  e)
    {
    	 Close();
    }
  27. Display the first form (Form1.h [Design])
  28. Add a button to it with the following properties:
    Text: New Customer Order
    Name: btnNewOrder
  29. Double-click the New Customer Order button
  30. In the top section of the form, type #include "CustomerOrder.h"
  31. Implement its Click event as follows:
     
    System::Void btnNewOrder_Click(System::Object *  sender, System::EventArgs *  e)
    {
    	 CustomerOrder*frmOrder = new CustomerOrder();
    
    	 frmOrder ->Show();
    }
  32. To add a new form, on the main menu, click Project -> Add New Item...
  33. In the Templates list of the Add New Item dialog box, click Windows Forms (.NET)
  34. Set the Name to DailySales and press Enter
  35. 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
  36. Double-click the Close button and implement its Click event as follows:
     
    System::Void btnClose_Click(System::Object *  sender, System::EventArgs *  e)
    {
    	 Close();
    }
  37. Display the first form (Form1.h [Design])
  38. Add a button to it with the following properties:
    Text: View Daily Sales
    Name: btnDailySales
  39. Double-click the View Daily Sales button
  40. In the top section of the file, under the other #include line, type #include "DailySales.h"
  41. Implement its Click event as follows:
     
    System::Void btnDailySales_Click(System::Object *  sender, System::EventArgs *  e)
    {
    	 DailySales *frmSales = new DailySales;
    
    	 frmSales->Show();
    }
  42. Return to the main form. Add a new button to it and set its properties as follows:
    Text: Close
    Name: btnClose

     
    Department Store - Switchboard
  43. Double-click the Close button and implement its Click event as follows:
     
    System::Void btnClose_Click(System::Object *  sender, System::EventArgs *  e)
    {
    	 Close();
    }
  44. 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. Here is an example:

#pragma once

using namespace System;

[Serializable]
public __gc class CEmployee
{
public:
	String  *FirstName;
	String  *LastName;
	DateTime DateHired;
	Double   Salary;

	CEmployee()
	{
		this->FirstName = S"";
		this->LastName  = S"";
		this->DateHired = DateTime::Now;
		this->Salary    = 0.00;
	}

	CEmployee(String *fn, String *ln, DateTime dte, Double sal)
	{
		this->FirstName = fn;
		this->LastName  = ln;
		this->DateHired = dte;
		this->Salary    = sal;
	}
};

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 (.NET)
  3. Set the Name to StoreItemR2
  4. Click OK
  5. In the Solution Explorer, double-click StoreItemR2.h
  6. Change the file as follows:
     
    // StoreItemR2.h
    
    #pragma once
    
    using namespace System;
    
    namespace StoreItemR2
    {
    	[Serializable]
    	public __gc class CStoreItem
    	{
    	private:
    		String *nbr;
    		String *nm;
    		String *sz;
    		double  uprice;
    		
    	public:
    		CStoreItem(void)
    		{
    			nbr = S"";
    			nm  = S"";
    			sz  = S"";
    			uprice = 0.00;
    		}
    
    CStoreItem(String *number, String *name, String *size, double price)
    		{
    			nbr    = number;
    			nm     = name;
    			sz     = size;
    			uprice = price;
    		}
    
    		__property String *get_ItemNumber()
    		{
    			return nbr;
    		}
    	
    		__property void set_ItemNumber(String *no)
    		{
    			nbr = no; 
    		}
    
    		__property String *get_ItemName()
    		{
    			return nm;
    		}
    
    		__property void set_ItemName(String *desc)
    		{
    			nm = desc;
    		}
    		__property String *get_Size()
    		{
    			return sz;
    		}
    
    		__property void set_Size(String *s)
    		{
    			sz = s;
    		}
    
    		__property double get_UnitPrice()
    		{
    			return uprice;
    		}
    
    		__property void set_UnitPrice(double price)
    		{
    			uprice = price;
    		}
    	};
    }
  7. To create the library, in the Solution Explorer, right-click the StoreItemR2 node and click Build
  8. To get a reference of this library to the department store project, in Solution Explorer, under DepartmentStore3, right-click References and click Add Reference...
    In the Project property page, 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:
     
    System::Void NewStoreItem_Load(System::Object *  sender, System::EventArgs *  e)
    {
    	lstStoreItems = new ArrayList;
    
    	 DateTime tmeNow = DateTime::Now;
    
    	 // Get ready to create a unique item number
    	 bool FoundUniqueNumber = false;
    	 String *strItemNumber = S"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 = String::Concat(NewNumber1.ToString(), "-", NewNumber2.ToString());
    
    		StoreItemR2::CStoreItem *item = new StoreItemR2::CStoreItem;
    
    	 	// 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 = dynamic_cast<StoreItemR2::CStoreItem *>(this->lstStoreItems->Item[i]);
    
    		   if( item->ItemNumber->Equals(strItemNumber) )
    			 FoundUniqueNumber = true;
    	 	}
    	 }while(FoundUniqueNumber = false);
    
    	 // Display the created item number in the Item # text box
    	 this->txtItemNumber->Text = strItemNumber;
    }
  11. Display the Customer Order form and double-click an unoccupied area of its body
  12. Implement the Load event as follows:
     
    #pragma once
    
    . . . No Change
    
    namespace DepartmentStore3b
    {
    	. . . No Change
    	
    
    	private:
    		/// <summary>
    		/// Required designer variable.
    		/// </summary>
    		System::ComponentModel::Container* components;
    		ArrayList *lstAvailableItems;
    
    		/// <summary>
    		/// Required method for Designer support - do not modify
    		/// the contents of this method with the code editor.
    		/// </summary>
    		void InitializeComponent(void)
    		{
    			. . . No Change
    			
    		}		
    	
    
    		. . . No Change
    
    private: System::Void CustomerOrder_Load(System::Object *  sender, System::EventArgs *  e)
    		 {
    			 lstAvailableItems = new ArrayList;
    		 }
    
    };
  13. In the ClassView, expand DepartmentStore3 and DepartmentStore3
  14. Right-click CustomerOrder -> Add -> Add Function...
  15. Set the Return Type to StoreItemR2::CStoreItem *
  16. Set the Function Name to LocateStoreItem
  17. Set the Parameter Type to String *
  18. Set the Parameter Name to ItemNumber and click Add
     
    Add Member Function Wizard
  19. Click Finish and implement the method as follows:
     
    StoreItemR2::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 = dynamic_cast<StoreItemR2::CStoreItem *>(this->lstAvailableItems->Item[i]);
    
    		// If the Item Number of the current item matches the argument,
    		// then return it
    		if( item->ItemNumber->Equals(ItemNumber) )
    			return item;
    	}
    
    	// If the item was not found, then return nothing;
    	return NULL;
    }
  20. In Class View, inside the DepartmentStore3 node, right-click CustomerOrder -> Add -> Add Function...
  21. Set the Return Type to void
  22. Set the Function Name to CalculateTotalOrder
  23. Set the Access to private
      
    Add Member Function
  24. Click Finish and implement the method as follows:
     
    void CalculateTotalOrder(void)
    {
    	 double subTotal1, subTotal2, subTotal3,
                                 subTotal4, subTotal5, subTotal6,
                                 subTotal7, subTotal8;
    	double orderTotal;
    
    	// Retrieve the value of each sub total
    	subTotal1 = this->txtSubTotal1->Text->ToDouble(0);
    	subTotal2 = this->txtSubTotal2->Text->ToDouble(0);
    	subTotal3 = this->txtSubTotal3->Text->ToDouble(0);
    	subTotal4 = this->txtSubTotal4->Text->ToDouble(0);
    	subTotal5 = this->txtSubTotal5->Text->ToDouble(0);
    	subTotal6 = this->txtSubTotal6->Text->ToDouble(0);
    	subTotal7 = this->txtSubTotal7->Text->ToDouble(0);
    	subTotal8 = this->txtSubTotal8->Text->ToDouble(0);
    
    	// 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(S"F");
    }
  25. Return to the Customer Order form and click the first text box under Item #
  26. In the Properties window, click the Events button if necessary and double-click its Leave field
  27. 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
  28. Implement the events as follows:
     
    System::Void txtItemNumber1_Leave(System::Object *  sender, System::EventArgs *  e)
    {
    	 String *strItemNumber = this->txtItemNumber1->Text;
    	 StoreItemR2::CStoreItem *item = this->LocateStoreItem(strItemNumber);
    
    	 if( item != 0 )
    	 {
    		 this->txtDescription1->Text = item->ItemName;
    		 this->txtSize1->Text        = item->Size;
    		 this->txtUnitPrice1->Text   = item->UnitPrice.ToString(S"F");
    		 this->txtQuantity1->Text    = S"1";
    		 this->txtSubTotal1->Text    = item->UnitPrice.ToString(S"F");
    
    		 CalculateTotalOrder();
    	 }
    	 else
    	 {
    		 this->txtItemNumber1->Text  = S"";
    		 this->txtDescription1->Text = S"";
    		 this->txtSize1->Text        = S"";
    		 this->txtUnitPrice1->Text   = S"0.00";
    		 this->txtQuantity1->Text    = S"0";
    		 this->txtSubTotal1->Text    = S"0.00";
    	 }
    }
    
    System::Void txtItemNumber2_Leave(System::Object *  sender, System::EventArgs *  e)
    {
    	 String *strItemNumber = this->txtItemNumber2->Text;
    	 StoreItemR2::CStoreItem *item = this->LocateStoreItem(strItemNumber);
    
    	 if( item != 0 )
    	 {
    		 this->txtDescription2->Text = item->ItemName;
    		 this->txtSize2->Text        = item->Size;
    		 this->txtUnitPrice2->Text   = item->UnitPrice.ToString(S"F");
    		 this->txtQuantity2->Text    = S"1";
    		 this->txtSubTotal2->Text    = item->UnitPrice.ToString(S"F");
    				
    		 CalculateTotalOrder();
    	 }
    	 else
    	 {
    		 this->txtItemNumber2->Text  = S"";
    		 this->txtDescription2->Text = S"";
    		 this->txtSize2->Text        = S"";
    		 this->txtUnitPrice2->Text   = S"0.00";
    		 this->txtQuantity2->Text    = S"0";
    		 this->txtSubTotal2->Text    = S"0.00";
    	 }
    }
    
    System::Void txtItemNumber3_Leave(System::Object *  sender, System::EventArgs *  e)
    {
    	 String *strItemNumber = this->txtItemNumber3->Text;
    	 StoreItemR2::CStoreItem *item = this->LocateStoreItem(strItemNumber);
    
    	 if( item != 0 )
    	 {
    		 this->txtDescription3->Text = item->ItemName;
    		 this->txtSize3->Text        = item->Size;
    		 this->txtUnitPrice3->Text   = item->UnitPrice.ToString(S"F");
    		 this->txtQuantity3->Text    = S"1";
    		 this->txtSubTotal3->Text    = item->UnitPrice.ToString(S"F");
    
    		 CalculateTotalOrder();
    	 }
    	 else
    	 {
    		 this->txtItemNumber3->Text  = S"";
    		 this->txtDescription3->Text = S"";
    		 this->txtSize3->Text        = S"";
    		 this->txtUnitPrice3->Text   = S"0.00";
    		 this->txtQuantity3->Text    = S"0";
    		 this->txtSubTotal3->Text    = S"0.00";
    	 }
    }
    
    System::Void txtItemNumber4_Leave(System::Object *  sender, System::EventArgs *  e)
    {
    	 String *strItemNumber = this->txtItemNumber4->Text;
    	 StoreItemR2::CStoreItem *item = this->LocateStoreItem(strItemNumber);
    
    	 if( item != 0 )
    	 {
    		 this->txtDescription4->Text = item->ItemName;
    		 this->txtSize4->Text        = item->Size;
    		 this->txtUnitPrice4->Text   = item->UnitPrice.ToString(S"F");
    		 this->txtQuantity4->Text    = S"1";
    		 this->txtSubTotal4->Text    = item->UnitPrice.ToString(S"F");
    
    		 CalculateTotalOrder();
    	 }
    	 else
    	 {
    		 this->txtItemNumber4->Text  = S"";
    		 this->txtDescription4->Text = S"";
    		 this->txtSize4->Text        = S"";
    		 this->txtUnitPrice4->Text   = S"0.00";
    		 this->txtQuantity4->Text    = S"0";
    		 this->txtSubTotal4->Text    = S"0.00";
    	 }
    }
    
    System::Void txtItemNumber5_Leave(System::Object *  sender, System::EventArgs *  e)
    {
    	 String *strItemNumber = this->txtItemNumber5->Text;
    	 StoreItemR2::CStoreItem *item = this->LocateStoreItem(strItemNumber);
    
    	 if( item != 0 )
    	 {
    		 this->txtDescription5->Text = item->ItemName;
    		 this->txtSize5->Text        = item->Size;
    		 this->txtUnitPrice5->Text   = item->UnitPrice.ToString(S"F");
    		 this->txtQuantity5->Text    = S"1";
    		 this->txtSubTotal5->Text    = item->UnitPrice.ToString(S"F");
    
    		 CalculateTotalOrder();
    	 }
    	 else
    	 {
    		 this->txtItemNumber5->Text  = S"";
    		 this->txtDescription5->Text = S"";
    		 this->txtSize5->Text        = S"";
    		 this->txtUnitPrice5->Text   = S"0.00";
    		 this->txtQuantity5->Text    = S"0";
    		 this->txtSubTotal5->Text    = S"0.00";
    	 }
    }
    
    System::Void txtItemNumber6_Leave(System::Object *  sender, System::EventArgs *  e)
    {
    	 String *strItemNumber = this->txtItemNumber6->Text;
    	 StoreItemR2::CStoreItem *item = this->LocateStoreItem(strItemNumber);
    
    	 if( item != 0 )
    	 {
    		 this->txtDescription6->Text = item->ItemName;
    		 this->txtSize6->Text        = item->Size;
    		 this->txtUnitPrice6->Text   = item->UnitPrice.ToString(S"F");
    		 this->txtQuantity6->Text    = S"1";
    		 this->txtSubTotal6->Text    = item->UnitPrice.ToString(S"F");
    
    		 CalculateTotalOrder();
    	 }
    	 else
    	 {
    		 this->txtItemNumber6->Text  = S"";
    		 this->txtDescription6->Text = S"";
    		 this->txtSize6->Text        = S"";
    		 this->txtUnitPrice6->Text   = S"0.00";
    		 this->txtQuantity6->Text    = S"0";
    		 this->txtSubTotal6->Text    = S"0.00";
    	 }
    }
    
    System::Void txtItemNumber7_Leave(System::Object *  sender, System::EventArgs *  e)
    {
    	 String *strItemNumber = this->txtItemNumber7->Text;
    	 StoreItemR2::CStoreItem *item = this->LocateStoreItem(strItemNumber);
    
    	 if( item != 0 )
    	 {
    		 this->txtDescription7->Text = item->ItemName;
    		 this->txtSize7->Text        = item->Size;
    		 this->txtUnitPrice7->Text   = item->UnitPrice.ToString(S"F");
    		 this->txtQuantity7->Text    = S"1";
    		 this->txtSubTotal7->Text    = item->UnitPrice.ToString(S"F");
    
    		 CalculateTotalOrder();
    	 }
    	 else
    	 {
    		 this->txtItemNumber7->Text  = S"";
    		 this->txtDescription7->Text = S"";
    		 this->txtSize7->Text        = S"";
    		 this->txtUnitPrice7->Text   = S"0.00";
    		 this->txtQuantity7->Text    = S"0";
    		 this->txtSubTotal7->Text    = S"0.00";
    	 }
    }
    
    System::Void txtItemNumber8_Leave(System::Object *  sender, System::EventArgs *  e)
    {
    	 String *strItemNumber = this->txtItemNumber8->Text;
    	 StoreItemR2::CStoreItem *item = this->LocateStoreItem(strItemNumber);
    
    	 if( item != 0 )
    	 {
    		 this->txtDescription8->Text = item->ItemName;
    		 this->txtSize8->Text        = item->Size;
    		 this->txtUnitPrice8->Text   = item->UnitPrice.ToString(S"F");
    		 this->txtQuantity8->Text    = S"1";
    		 this->txtSubTotal8->Text    = item->UnitPrice.ToString(S"F");
    
    		 CalculateTotalOrder();
    	 }
    	 else
    	 {
    		 this->txtItemNumber8->Text  = S"";
    		 this->txtDescription8->Text = S"";
    		 this->txtSize8->Text        = S"";
    		 this->txtUnitPrice8->Text   = S"0.00";
    		 this->txtQuantity8->Text    = S"0";
    		 this->txtSubTotal8->Text    = S"0.00";
    	 }
    }
  29. In the ClassView, under the second DepartmentStore3 node, right-click CustomerOrder -> Add -> Add Function...
  30. Set the Return Type to double
  31. Set the Function Name to CalculateSubTotal
  32. Set the Parameter Type to String *
  33. Set the Parameter Name to strPrice and click Add
  34. Set the Parameter Type to String *
  35. Set the Parameter Name to strQuantity and click Add
     
    Add Member Function
  36. Click Finish and implement the method as follows:
     
    double CalculateSubTotal(String * strPrice, String * strQuantity)
    {
    	int qty;
    	double unitPrice, subTotal;
    	
    	try {
    		// Get the quantity of the current item
    		qty = strQuantity->ToInt16(0);
    	}
    	catch(FormatException *)
    	{
    MessageBox::Show(S"The value you provided for the quantity of the item is invalid"
    				         S"\nPlease try again");
    	}
    			
    	try {
    		// Get the unit price of the current item
    		unitPrice = strPrice->ToDouble(0);
    	}
    	catch(FormatException *)
    	{
    		MessageBox::Show(S"The unit price you provided for item is invalid"
    				         S"\nPlease try again");
    	}
    	// Calculate the current sub total
    	subTotal = qty * unitPrice;
    
    	return subTotal;
    }
  37. Display the Customer Order form again and click the first text box under Qty
  38. In the Properties window and in the Events section, double-click the Leave field
  39. Return to the form, click each of the other Qty text boxes, and in the Properties window, click the Leave field of each Qty
  40. Implement their events as follows:
     
    System::Void txtQuantity1_Leave(System::Object *  sender, System::EventArgs *  e)
    {
    	 String *strUnitPrice = this->txtUnitPrice1->Text;
    	 String *strQty = this->txtQuantity1->Text;
    	 double subTotal = this->CalculateSubTotal(strUnitPrice, strQty);
    	
    	// Display the new sub total in the corresponding text box
    	this->txtSubTotal1->Text = subTotal.ToString(S"F");
    	// Update the order
    	CalculateTotalOrder();
    }
    
    System::Void txtQuantity2_Leave(System::Object *  sender, System::EventArgs *  e)
    {
    	 String *strUnitPrice = this->txtUnitPrice2->Text;
    	 String *strQty = this->txtQuantity2->Text;
    	 double subTotal = this->CalculateSubTotal(strUnitPrice, strQty);
    	
    	this->txtSubTotal2->Text = subTotal.ToString(S"F");
    	CalculateTotalOrder();
    }
    
    System::Void txtQuantity3_Leave(System::Object *  sender, System::EventArgs *  e)
    {
    	 String *strUnitPrice = this->txtUnitPrice3->Text;
    	 String *strQty = this->txtQuantity3->Text;
    	 double subTotal = this->CalculateSubTotal(strUnitPrice, strQty);
    	
    	this->txtSubTotal3->Text = subTotal.ToString(S"F");
    	CalculateTotalOrder();
    }
    
    System::Void txtQuantity4_Leave(System::Object *  sender, System::EventArgs *  e)
    {
    	 String *strUnitPrice = this->txtUnitPrice4->Text;
    	 String *strQty = this->txtQuantity4->Text;
    	 double subTotal = this->CalculateSubTotal(strUnitPrice, strQty);
    	
    	this->txtSubTotal4->Text = subTotal.ToString(S"F");
    	CalculateTotalOrder();
    }
    
    System::Void txtQuantity5_Leave(System::Object *  sender, System::EventArgs *  e)
    {
    	 String *strUnitPrice = this->txtUnitPrice5->Text;
    	 String *strQty = this->txtQuantity5->Text;
    	 double subTotal = this->CalculateSubTotal(strUnitPrice, strQty);
    	
    	this->txtSubTotal5->Text = subTotal.ToString(S"F");
    	CalculateTotalOrder();
    }
    
    System::Void txtQuantity6_Leave(System::Object *  sender, System::EventArgs *  e)
    {
    	 String *strUnitPrice = this->txtUnitPrice6->Text;
    	 String *strQty = this->txtQuantity6->Text;
    	 double subTotal = this->CalculateSubTotal(strUnitPrice, strQty);
    
    	this->txtSubTotal6->Text = subTotal.ToString(S"F");
    	CalculateTotalOrder();
    }
    
    System::Void txtQuantity7_Leave(System::Object *  sender, System::EventArgs *  e)
    {
    	 String *strUnitPrice = this->txtUnitPrice7->Text;
    	 String *strQty = this->txtQuantity7->Text;
    	 double subTotal = this->CalculateSubTotal(strUnitPrice, strQty);
    	
    	this->txtSubTotal7->Text = subTotal.ToString(S"F");
    	CalculateTotalOrder();
    }
    
    System::Void txtQuantity8_Leave(System::Object *  sender, System::EventArgs *  e)
    {
    	 String *strUnitPrice = this->txtUnitPrice8->Text;
    	 String *strQty = this->txtQuantity8->Text;
    	 double subTotal = this->CalculateSubTotal(strUnitPrice, strQty);
    	
    	this->txtSubTotal8->Text = subTotal.ToString(S"F");
    	CalculateTotalOrder();
    }
  41. 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:
     
    System::Void NewStoreItem_Deactivate(System::Object *  sender, System::EventArgs *  e)
    {
    	 String *strFilename = S"StoreItems.sti";
    	 FileStream *fStream = new FileStream(strFilename, FileMode::Create);
    	 BinaryFormatter *binFormat = new BinaryFormatter;
    
    	 try {
    		 binFormat->Serialize(fStream, this->lstStoreItems);
    	 }
    	 catch(ArgumentNullException *)
    	 {
    		 MessageBox::Show(S"The inventory could not be accessed");
    	 }
    	 catch(SerializationException *)
    	 {
    		 MessageBox::Show(S"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:
     
    #pragma once
    
    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;
    using namespace System::IO;
    using namespace System::Runtime::Serialization;
    using namespace System::Runtime::Serialization::Formatters::Binary;
    
    namespace DepartmentStore3
    {
    	. . . No Change
    
    	private:
    		/// <summary>
    		/// Required designer variable.
    		/// </summary>
    		System::ComponentModel::Container* components;
    		ArrayList *lstStoreItems;
    
    		/// <summary>
    		/// Required method for Designer support - do not modify
    		/// the contents of this method with the code editor.
    		/// </summary>
    		void InitializeComponent(void)
    		{
    			. . . No Change
    
    		}		
    System::Void NewStoreItem_Activated(System::Object *  sender, System::EventArgs *  e)
    {
    	 // This file holds the items sold in the store
    	 String *strFilename = S"StoreItems.sti";
    	 FileStream *fStream;
    
    	 if( File::Exists(strFilename) )
    	 {
    		 try {
    			 // Create a stream of store items
    			 fStream = new FileStream(strFilename, FileMode::Open);
                         
    			 BinaryFormatter *binFormat = new BinaryFormatter;
    			 lstStoreItems = dynamic_cast<ArrayList *>(binFormat->Deserialize(fStream));
    		 }
    		 catch(ArgumentNullException *)
    		 {
    			 MessageBox::Show(S"The inventory could not be accessed");
    		 }
    		 catch(SerializationException *)
    		 {
    			 MessageBox::Show(S"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:
     
    System::Void btnAddItem_Click(System::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->Equals(S"") )
    		 return;
    	 if( this->txtItemName->Text->Equals(S"") )
    		 return;
    	 if( this->txtUnitPrice->Text->Equals(S"") )
    		 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  = this->txtUnitPrice->Text->ToDouble(0);
    	 // Add the record
    	 this->lstStoreItems->Add(item);
    		
    	 // Reset the form for a new record
    	 this->txtItemNumber->Text = S"";
    	 this->txtItemName->Text = S"";
    	 this->txtSize->Text = S"";
    	 this->txtUnitPrice->Text = S"";
    	 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 namespace lines, type:
     
    using namespace System::IO;
    using namespace System::Runtime::Serialization;
    using namespace System::Runtime::Serialization::Formatters::Binary;
  8. Implement its Click event as follows:
     
    System::Void btnLoad_Click(System::Object *  sender, System::EventArgs *  e)
    {
    	 ArrayList *lstItems= new ArrayList();
    	 String *strFilename = S"StoreItems.sti";
    				 
    	 if( File::Exists(strFilename) )
    	 {
    		 FileStream *fStream = new FileStream(strFilename, FileMode::Open);
    
    		 try {
    			 BinaryFormatter *binFormat = new BinaryFormatter;
    	lstItems = dynamic_cast<ArrayList *>(binFormat->Deserialize(fStream));
    
    			 this->dataGrid1->DataSource = 0;
    			 this->dataGrid1->DataSource = lstItems;
    		 }	 
    		 catch(ArgumentNullException *)
    		 {
    			 MessageBox::Show(S"The inventory could not be accessed");
    		 }
    		 catch(SerializationException *)
    		{
    	 MessageBox::Show(S"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:
     
    #pragma once
    
    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;
    using namespace System::IO;
    using namespace System::Runtime::Serialization;
    using namespace System::Runtime::Serialization::Formatters::Binary;
    
    namespace DepartmentStore3a
    {
    	private:
    		/// <summary>
    		/// Required designer variable.
    		/// </summary>
    		System::ComponentModel::Container* components;
    		ArrayList *lstAvailableItems;
    			
    			
    	. . . No Change
    
    }
    
    private: System::Void CustomerOrder_Activated(System::Object *  sender, System::EventArgs *  e)
    {
    	lstAvailableItems = new ArrayList;
    			 
    	 // This file holds the items sold in the store
    	 String *strFilename = S"StoreItems.sti";
    	 FileStream *fStream;
    
    	 if( File::Exists(strFilename) )
    	 {
    		 try {
    			 // Create a stream of store items
    			 fStream = new FileStream(strFilename, FileMode::Open);
                         
    			 BinaryFormatter *binFormat = new BinaryFormatter;
    		lstAvailableItems = dynamic_cast<ArrayList *>(binFormat->Deserialize(fStream));
    		 }
    		 catch(ArgumentNullException *)
    		 {
    			 MessageBox::Show(S"The inventory could not be accessed");
    		 }
    		 catch(SerializationException *)
    		 {
    			 MessageBox::Show(S"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 (.NET)
  17. Set the Name to SalesInventory and click OK
  18. In the Solution Explorer, double-click SalesInventory.h
  19. Change the file as follows:
     
    // SalesInventory.h
    
    #pragma once
    
    using namespace System;
    
    namespace SalesInventory
    {
    	[Serializable]
    	public __gc class CSaleInventory
    	{
    		
    	private:
    		String *strNbr;
    		String *strName;
    		String *strSize;
    		double  uPrice;
    		int     iQty;
    		double  stotal;
    		
    	public:
    		CSaleInventory(void)
    		{
    			strNbr  = S"";
    			strName = S"";
    			strSize = S"";
    			uPrice  = 0.00;
    			iQty    = 0;
    			stotal  = 0.00;
    		}
    
    		CSaleInventory(String *number, String *name, String *size,
    			            double price, int qty, double total)
    		{
    			strNbr  = number;
    			strName = name;
    			strSize = size;
    			uPrice  = price;
    			iQty    = qty;
    			stotal  = total;
    		}
    
    		__property String *get_ItemNumber()
    		{
    			return strNbr;
    		}
    	
    		__property void set_ItemNumber(String *no)
    		{
    			strNbr = no; 
    		}
    
    		__property String *get_ItemName()
    		{
    			return strName;
    		}
    
    		__property void set_ItemName(String *name)
    		{
    			strName = name;
    		}
    		__property String *get_Size()
    		{
    			return strSize;
    		}
    
    		__property void set_Size(String *size)
    		{
    			strSize = size;
    		}
    
    		__property double get_UnitPrice()
    		{
    			return uPrice;
    		}
    
    		__property void set_UnitPrice(double price)
    		{
    			uPrice = price;
    		}
    
    		__property int get_Quantity()
    		{
    			return iQty;
    		}
    
    		__property void set_Quantity(int qty)
    		{
    			iQty = qty;
    		}
    
    		__property double get_SubTotal()
    		{
    			return stotal;
    		}
    
    		__property void set_SubTotal(double total)
    		{
    			stotal = total;
    		}
    	};
    }
  20. To create the library, in the Solution Explorer, right-click the SalesInventory node and click Build
  21. To get a reference of this library to the department store project, in Solution Explorer, under DepartmentStore3, right-click References and click Add Reference...
    In the Project 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:
     
    System::Void btnSaveOrder_Click(System::Object *  sender, System::EventArgs *  e)
    {
    	 DateTime dteCurrent = this->dtpSaleDate->Value;
    	 int month = dteCurrent.Month;
    	 int day   = dteCurrent.Day;
    	 int year  = dteCurrent.Year;
    			 
    String *strFilename = String::Concat(month.ToString(), S"-", day.ToString(), S"-", year.ToString(), S".dly");
    	 ArrayList *lstCurrentSoldItems = new ArrayList;
    	 SalesInventory::CSaleInventory *curOrder;
    	 FileStream *fStream;
    	 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 = dynamic_cast<ArrayList *>(binFormat->Deserialize(fStream));
    		 }
    		 catch(ArgumentNullException *)
    		 {
    			 MessageBox::Show(S"The inventory could not be accessed");
    		 }
    		 catch(SerializationException *)
    		 {
    			 MessageBox::Show(S"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->Equals(S"") )
    	 {
    		 curOrder = new SalesInventory::CSaleInventory;
    		 curOrder->ItemNumber = this->txtItemNumber1->Text;
    		 curOrder->ItemName   = this->txtDescription1->Text;
    		 curOrder->Size       = this->txtSize1->Text;
    		 curOrder->UnitPrice  = this->txtUnitPrice1->Text->ToDouble(0);
    		 curOrder->Quantity   = this->txtQuantity1->Text->ToInt16(0);
    		 curOrder->SubTotal   = this->txtSubTotal1->Text->ToDouble(0);
    		 lstCurrentSoldItems->Add(curOrder);
    	 }
    
    	 if( !this->txtItemNumber2->Text->Equals(S"") )
    	 {
    		 curOrder = new SalesInventory::CSaleInventory;
    		 curOrder->ItemNumber = this->txtItemNumber2->Text;
    		 curOrder->ItemName   = this->txtDescription2->Text;
    		 curOrder->Size       = this->txtSize2->Text;
    		 curOrder->UnitPrice  = this->txtUnitPrice2->Text->ToDouble(0);
    		 curOrder->Quantity   = this->txtQuantity2->Text->ToInt16(0);
    		 curOrder->SubTotal   = this->txtSubTotal2->Text->ToDouble(0);
    		 lstCurrentSoldItems->Add(curOrder);
    	 }
    
    	 if( !this->txtItemNumber3->Text->Equals(S"") )
    	 {
    		 curOrder = new SalesInventory::CSaleInventory;
    		 curOrder->ItemNumber = this->txtItemNumber3->Text;
    		 curOrder->ItemName   = this->txtDescription3->Text;
    		 curOrder->Size       = this->txtSize3->Text;
    		 curOrder->UnitPrice  = this->txtUnitPrice3->Text->ToDouble(0);
    		 curOrder->Quantity   = this->txtQuantity3->Text->ToInt16(0);
    		 curOrder->SubTotal   = this->txtSubTotal3->Text->ToDouble(0);
    		 lstCurrentSoldItems->Add(curOrder);
    	 }
    
    	 if( !this->txtItemNumber4->Text->Equals(S"") )
    	 {
    		 curOrder = new SalesInventory::CSaleInventory;
    		 curOrder->ItemNumber = this->txtItemNumber4->Text;
    		 curOrder->ItemName   = this->txtDescription4->Text;
    		 curOrder->Size       = this->txtSize4->Text;
    		 curOrder->UnitPrice  = this->txtUnitPrice4->Text->ToDouble(0);
    		 curOrder->Quantity   = this->txtQuantity4->Text->ToInt16(0);
    		 curOrder->SubTotal   = this->txtSubTotal4->Text->ToDouble(0);
    		 lstCurrentSoldItems->Add(curOrder);
    	 }
    
    	 if( !this->txtItemNumber5->Text->Equals(S"") )
    	 {
    		 curOrder = new SalesInventory::CSaleInventory;
    		 curOrder->ItemNumber = this->txtItemNumber5->Text;
    		 curOrder->ItemName   = this->txtDescription5->Text;
    		 curOrder->Size       = this->txtSize5->Text;
    		 curOrder->UnitPrice  = this->txtUnitPrice5->Text->ToDouble(0);
    		 curOrder->Quantity   = this->txtQuantity3->Text->ToInt16(0);
    		 curOrder->SubTotal   = this->txtSubTotal5->Text->ToDouble(0);
    		 lstCurrentSoldItems->Add(curOrder);
    	 }
    
    	 if( !this->txtItemNumber6->Text->Equals(S"") )
    	 {
    		 curOrder = new SalesInventory::CSaleInventory;
    		 curOrder->ItemNumber = this->txtItemNumber6->Text;
    		 curOrder->ItemName   = this->txtDescription6->Text;
    		 curOrder->Size       = this->txtSize6->Text;
    		 curOrder->UnitPrice  = this->txtUnitPrice6->Text->ToDouble(0);
    		 curOrder->Quantity   = this->txtQuantity6->Text->ToInt16(0);
    		 curOrder->SubTotal   = this->txtSubTotal6->Text->ToDouble(0);
    		 lstCurrentSoldItems->Add(curOrder);
    	 }
    
    	 if( !this->txtItemNumber7->Text->Equals(S"") )
    	 {
    		 curOrder = new SalesInventory::CSaleInventory;
    		 curOrder->ItemNumber = this->txtItemNumber7->Text;
    		 curOrder->ItemName   = this->txtDescription7->Text;
    		 curOrder->Size       = this->txtSize7->Text;
    		 curOrder->UnitPrice  = this->txtUnitPrice7->Text->ToDouble(0);
    		 curOrder->Quantity   = this->txtQuantity7->Text->ToInt16(0);
    		 curOrder->SubTotal   = this->txtSubTotal7->Text->ToDouble(0);
    		 lstCurrentSoldItems->Add(curOrder);
    	 }
    
    	 if( !this->txtItemNumber8->Text->Equals(S"") )
    	 {
    		 curOrder = new SalesInventory::CSaleInventory;
    		 curOrder->ItemNumber = this->txtItemNumber8->Text;
    		 curOrder->ItemName   = this->txtDescription8->Text;
    		 curOrder->Size       = this->txtSize8->Text;
    		 curOrder->UnitPrice  = this->txtUnitPrice8->Text->ToDouble(0);
    		 curOrder->Quantity   = this->txtQuantity8->Text->ToInt16(0);
    		 curOrder->SubTotal   = this->txtSubTotal8->Text->ToDouble(0);
    		 lstCurrentSoldItems->Add(curOrder);
    	 }
    
    	 fStream = new FileStream(strFilename, FileMode::Create, FileAccess::Write, FileShare::None);
    
    	 try {
    		 binFormat->Serialize(fStream, lstCurrentSoldItems);
    	 }
    	 catch(ArgumentNullException *)
    	 {
    		 MessageBox::Show(S"The customer order could not be accessed");
    	 }
    	 catch(SerializationException *)
    	 {
    		 MessageBox::Show(S"The customer order could not be saved");
    	 }
    	 __finally {
    		 fStream->Close();
    	 }
    
    	 // Reset the order
    	 this->txtItemNumber1->Text = S"";
    	 this->txtItemNumber2->Text = S"";
    	 this->txtItemNumber3->Text = S"";
    	 this->txtItemNumber4->Text = S"";
    	 this->txtItemNumber5->Text = S"";
    	 this->txtItemNumber6->Text = S"";
    	 this->txtItemNumber7->Text = S"";
    	 this->txtItemNumber8->Text = S"";
    
    	 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 = S"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:
     
    #pragma once
    
    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;
    using namespace System::IO;
    using namespace System::Runtime::Serialization;
    using namespace System::Runtime::Serialization::Formatters::Binary;
    
    namespace DepartmentStore3a
    {
    	. . . No Change 
    		
    
    private: System::Void btnClose_Click(System::Object *  sender, System::EventArgs *  e)
    {
    	 Close();
    }
    
    private: System::Void dtpSaleDate_ValueChanged(System::Object *  sender, System::EventArgs *  e)
    {
    	 DateTime dteCurrent = this->dtpSaleDate->Value;
    	 int month = dteCurrent.Month;
    	 int day   = dteCurrent.Day;
    	 int year  = dteCurrent.Year;
    			 
    String *strFilename = String::Concat(month.ToString(), S"-", day.ToString(), S"-", year.ToString(), S".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 {
    			 BinaryFormatter *binFormat = new BinaryFormatter;
    			 lstDaySoldItems = dynamic_cast<ArrayList *>(binFormat->Deserialize(fStream));
    
    			 this->dataGrid1->DataSource = 0;
    			 this->dataGrid1->DataSource = lstDaySoldItems;
    		 }	 
    		 catch(ArgumentNullException *)
    		 {
    			 MessageBox::Show(S"The inventory could not be accessed");
    		 }
    		 catch(SerializationException *)
    		{
    			 MessageBox::Show(S"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-2005 FunctionX, Inc.