|
Over all, a clerk would assist a customer locate an item most appropriately
suiting to the customer's needs. This application includes a process, through
some combo boxes, that allows an employee to locate an item.
|
Practical
Learning: Starting a Custom Collection Class
|
|
- Start Microsoft Visual C# and create a new Windows Application named MusicalInstrumentStore2
- To create a dialog box, on the main menu, click Project -> Add Windows
Form...
- Set the name to CategoryEditor and click Add
- Design the form as follows:
 |
| Control |
Text |
Name |
Other Properties |
| Label |
&Category: |
|
|
| TextBox |
|
txtCategory |
Modifiers: Public |
| Button |
OK |
btnOK |
DialogResult: OK |
| Button |
Cancel |
btnCancel |
DialogResult: Cancel |
|
| Form Property |
Value |
| FormBorderStyle |
FixedDialog |
| Text |
Category Editor |
| StartPosition |
CenterScreen |
| AcceptButton |
btnOK |
| CancelButton |
btnCancel |
| MaximizeBox |
False |
| MinimizeBox |
False |
| ShowInTaskbar |
False |
- To create a dialog box, on the main menu, click Project -> Add Windows
Form...
- Set the name to TypeEditor and click Add
- Design the form as follows:
 |
| Control |
Text |
Name |
Other Properties |
| Label |
&Item Type: |
|
|
| TextBox |
|
txtItemType |
Modifiers: Public |
| Button |
OK |
btnOK |
DialogResult: OK |
| Button |
Cancel |
btnCancel |
DialogResult: Cancel |
|
| Form Property |
Value |
| FormBorderStyle |
FixedDialog |
| Text |
Type Editor |
| StartPosition |
CenterScreen |
| AcceptButton |
btnOK |
| CancelButton |
btnCancel |
| MaximizeBox |
False |
| MinimizeBox |
False |
| ShowInTaskbar |
False |
- To create a dialog box, in the Solution Explorer, right-click
MusicalInstrumentStore2 -> Add -> Windows
Form...
- Set the name to ItemEditor and click Add
- Design the form as follows:
 |
| Control |
Text |
Name |
Other Properties |
| Label |
&Item #: |
|
|
| TextBox |
|
txtItemNumber |
|
| Label |
&Category: |
|
|
| ComboBox |
|
cbxCategories |
|
| Button |
New C&ategory... |
btnNewCategory |
|
| Label |
&Item Type: |
|
|
| ComboBox |
|
cbxItemTypes |
|
| Button |
New &Item Type... |
btnNewItemType |
|
| Label |
Item &Name: |
|
|
| TextBox |
|
txtItemName |
|
| Label |
&Unit Price: |
|
|
| TextBox |
0.00 |
txtUnitPrice |
TextAlign: Right |
| Button |
Picture... |
btnPicture |
|
| TextBox |
|
txtPicturePath |
|
| PictureBox |
|
pbxPicturePath |
SizeMode: Zoom |
| Button |
Create |
btnCreate |
|
| Button |
Close |
btnClose |
DialogResult: Cancel |
| OpenFileDialog |
(Name): dlgOpen
Title: Select Item Picture
DefaultExt: jpg
Filter: JPEG Files (*.jpg,*.jpeg)|*.jpg|GIF Files (*.gif)|*.gif|Bitmap Files
(*.bmp)|*.bmp|PNG Files (*.png)|*.png |
|
| Form Property |
Value |
| FormBorderStyle |
FixedDialog |
| Text |
Musical Instrument Store - Item Editor |
| StartPosition |
CenterScreen |
| MaximizeBox |
False |
| MinimizeBox |
False |
| ShowInTaskbar |
False |
- Double-click the New Category button and implement it as follows:
private void btnNewCategory_Click(object sender, EventArgs e)
{
CategoryEditor editor = new CategoryEditor();
if (editor.ShowDialog() == DialogResult.OK)
{
if (editor.txtCategory.Text.Length > 0)
{
string strNewCategory = editor.txtCategory.Text;
// Make sure the category is not yet in the list
if (cbxCategories.Items.Contains(strNewCategory))
MessageBox.Show(strNewCategory + " is already in the list");
else
{
// Since this is a new category, add it to the combox box
cbxCategories.Items.Add(strNewCategory);
// Just in case the user wanted to use this new category
// select it
cbxCategories.Text = strNewCategory;
}
}
}
}
|
- Return to the Item Editor dialog box and double-click the New Item Type
button
- Implement the event as follows:
private void btnNewItemType_Click(object sender, EventArgs e)
{
TypeEditor editor = new TypeEditor();
if (editor.ShowDialog() == DialogResult.OK)
{
if (editor.txtItemType.Text.Length > 0)
{
string strNewType = editor.txtItemType.Text;
// Make sure the type is not yet in the list
if (cbxTypes.Items.Contains(strNewType))
MessageBox.Show("The list already contains " +
strNewType);
else
{
cbxTypes.Items.Add(strNewType);
cbxTypes.Text = strNewType;
}
}
}
}
|
- Return to the Item Editor dialog box and double-click the Picture button
- Implement the event as follows:
private void btnPicture_Click(object sender, EventArgs e)
{
if (dlgPicture.ShowDialog() == DialogResult.OK)
{
txtPicturePath.Text = dlgPicture.FileName;
pbxStoreItem.Image = Image.FromFile(txtPicturePath.Text);
}
}
|
- In the Solution Explorer, right-click Form1.cs and click Rename
- Type MusicStore.cs and press Enter twice (to display the form)
- Design the form as follows:
 |
| Control |
Text |
Name |
Other Properties |
| Label |
 |
Item Category: |
|
|
| ComboBox |
 |
|
cbxCategories |
|
| Label |
 |
Items Type: |
|
|
| ComboBox |
 |
|
cbxTypes |
|
| Label |
 |
Available Items |
|
|
| Button |
 |
New Store Item... |
btnNewStoreItem |
|
| ListView |
 |
|
lvwStoreItems |
View: Details
FullRowSelect: True
GridLines: True |
| Columns |
| (Name) |
Text |
TextAlign |
Width |
| colItemNumber |
Item # |
|
|
| colItemName |
Item Name/Description |
|
320 |
| colUnitPrice |
Unit Price |
Right |
|
|
| PictureBox |
 |
|
pbxStoreItem |
SizeMode: Zoom |
| GroupBox |
 |
Selected Items |
|
|
| Label |
 |
Item # |
|
|
| Label |
 |
Description |
|
|
| Label |
 |
Unit Price |
|
|
| Label |
 |
Qty |
|
|
| Label |
 |
Sub Total |
|
|
| TextBox |
 |
|
txtItemNumber1 |
|
| TextBox |
 |
|
txtDescription1 |
|
| TextBox |
 |
0.00 |
txtUnitPrice1 |
TextAlign: Right |
| TextBox |
 |
0 |
txtQuantity1 |
TextAlign: Right |
| TextBox |
 |
0.00 |
txtSubTotal1 |
TextAlign: Right |
| Button |
 |
Remove |
btnRemove1 |
|
| TextBox |
 |
|
txtItemNumber2 |
|
| TextBox |
 |
|
txtDescription2 |
|
| TextBox |
 |
0.00 |
txtUnitPrice2 |
TextAlign: Right |
| TextBox |
 |
0 |
txtQuantity2 |
TextAlign: Right |
| TextBox |
 |
0.00 |
txtSubTotal2 |
TextAlign: Right |
| Button |
 |
Remove |
btnRemove2 |
|
| TextBox |
 |
|
txtItemNumber3 |
|
| TextBox |
 |
|
txtDescription3 |
|
| TextBox |
 |
0.00 |
txtUnitPrice3 |
TextAlign: Right |
| TextBox |
 |
0 |
txtQuantity3 |
TextAlign: Right |
| TextBox |
 |
0.00 |
txtSubTotal3 |
TextAlign: Right |
| Button |
 |
Remove |
btnRemove3 |
|
| TextBox |
 |
|
txtItemNumber4 |
|
| TextBox |
 |
|
txtDescription4 |
|
| TextBox |
 |
0.00 |
txtUnitPrice4 |
TextAlign: Right |
| TextBox |
 |
0 |
txtQuantity4 |
TextAlign: Right |
| TextBox |
 |
0.00 |
txtSubTotal4 |
TextAlign: Right |
| Button |
 |
Remove |
btnRemove4 |
|
| TextBox |
 |
|
txtItemNumber5 |
|
| TextBox |
 |
|
txtDescription5 |
|
| TextBox |
 |
0.00 |
txtUnitPrice5 |
TextAlign: Right |
| TextBox |
 |
0 |
txtQuantity5 |
TextAlign: Right |
| TextBox |
 |
0.00 |
txtSubTotal5 |
TextAlign: Right |
| Button |
 |
Remove |
btnRemove5 |
|
| TextBox |
 |
|
txtItemNumber6 |
|
| TextBox |
 |
|
txtDescription6 |
|
| TextBox |
 |
0.00 |
txtUnitPrice6 |
TextAlign: Right |
| TextBox |
 |
0 |
txtQuantity6 |
TextAlign: Right |
| TextBox |
 |
0.00 |
txtSubTotal6 |
TextAlign: Right |
| Button |
 |
Remove |
btnRemove6 |
|
| GroupBox |
 |
Order Summary |
|
|
| Label |
 |
Items Total: |
|
|
| TextBox |
 |
0.00 |
txtItemsTotal |
TextAlign: Right |
| Label |
 |
Tax Rate: |
|
|
| TextBox |
 |
7.75 |
|
TextAlign: Right |
| Label |
 |
% |
|
|
| Label |
 |
Tax Amount: |
|
|
| TextBox |
 |
0.00 |
txtTaxAmount |
TextAlign: Right |
| Label |
 |
Order Total: |
|
|
| TextBox |
 |
0.00 |
txtOrderTotal |
TextAlign: Right |
| Button |
 |
Save |
btnSave |
|
| Label |
 |
Receipt #: |
|
|
| TextBox |
 |
0.00 |
txtReceiptNumber |
|
| Button |
 |
&Open |
btnOpen |
|
| Button |
 |
New Order |
btnNewOrder |
|
| Button |
 |
Close |
btnClose |
|
|
- To create a new class, in the Solution Explorer, right-click
MusicalInstrumentStore2 -> Add -> Class...
- Set the Name to StoreItem and press Enter
- Change the file as follows:
using System;
namespace MusicalInstrumentStore2
{
[Serializable]
public class StoreItem
{
private string nbr;
private string cat;
private string tp;
private string nm;
private double prc;
public string ItemNumber
{
get { return nbr; }
set { nbr = value; }
}
public string Category
{
get { return cat; }
set { cat = value; }
}
public string Type
{
get { return tp; }
set { tp = value; }
}
public string ItemName
{
get { return nm; }
set { nm = value; }
}
public double UnitPrice
{
get { return prc; }
set { prc = value; }
}
public virtual bool Equals(StoreItem same)
{
if( (nbr == same.nbr) &&
(cat == same.cat) &&
(tp == same.tp) &&
(nm == same.nm) &&
(prc == same.prc))
return true;
else
return false;
}
public StoreItem()
{
nbr = "000000";
cat = "Accessories";
tp = "Accessories";
nm = "Unknown";
prc = 0.00;
}
public StoreItem(string itmNumber)
{
nbr = itmNumber;
cat = "Accessories";
tp = "Accessories";
nm = "Unknown";
prc = 0.00;
}
public StoreItem(string itmNumber, string category,
string type, string name, double price)
{
nbr = itmNumber;
cat = category;
tp = type;
nm = name;
prc = price;
}
}
}
|
- To create a new class, in the Class View, right-click
MusicalInstrumentStore2 -> Add -> Class...
- Set the Name to StoreItems and press Enter
- Change the file as follows:
using System;
using System.Collections;
namespace MusicalInstrumentStore2
{
[Serializable]
public class StoreItems : IList
{
int counter;
private object[] items;
public virtual int Count
{
get { return counter; }
}
public virtual bool IsSynchronized
{
get { return false; }
}
public virtual object SyncRoot
{
get { return this; }
}
public virtual void CopyTo(Array arr, int index)
{
}
public virtual IEnumerator GetEnumerator()
{
return null;
}
public virtual bool IsFixedSize
{
get { return false; }
}
public virtual bool IsReadOnly
{
get { return false; }
}
public virtual object this[int index]
{
get { return null; }
set { }
}
// This method is used to add a new item to the collection
public virtual int Add(object value)
{
return 0;
}
// This method can be used to insert an item at
// a certain position inside the collection
public virtual void Insert(int index, Object value)
{
}
// This method is used to find out whether the item
// passed as argument exists in the collection
public virtual bool Contains(object value)
{
return false;
}
// This method is used to check whether the item passed as
// argument exists in the collection. If so, it returns its index
public virtual int IndexOf(object value)
{
return 0;
}
// This method is used to delete the item positioned
// at the index passed as argument
public virtual void RemoveAt(int index)
{
}
// This method first checks the existence of the item passed
// as argument. If the item exists, the method deletes it
public virtual void Remove(object value)
{
}
// This methods deletes all items from the collection
public virtual void Clear()
{
}
public StoreItems()
{
counter = 0;
items = new object[5];
}
}
}
|
- Save the file
- Change the code of the StoreItems.Add() method as follows:
// This method is used to add a new item to the collection
public virtual int Add(object value)
{
// Find out if the array is getting too small for the next item(s)
// If it is, increase its size by 5
if (Count == items.Length)
Array.Resize(ref items, items.Length + 5);
if (counter < items.Length)
{
items[counter] = value;
counter++;
return counter - 1;
}
else
return -1;
}
|
- In the Class View, double-click ItemEditor
- In the top section of the file, add the following:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
|
- In the Solution Explorer, double-click ItemEditor.cs
- On the form, double-click the Create button and implement its event
as follows:
private void btnCreate_Click(object sender, EventArgs e)
{
FileStream stmStoreItem = null;
StoreItem item = new StoreItem();
StoreItems items = new StoreItems();
BinaryFormatter bfmStoreItem = new BinaryFormatter();
// If this directory doesn't exist, create it
Directory.CreateDirectory(@"C:\Musical Instrument Store");
// This is the file that holds the list of items
string FileName = @"C:\Musical Instrument Store\StoreItems.mis";
// Create a random number that will be used to identify the item
Random rnd = new Random();
txtItemNumber.Text = rnd.Next(100000, 999999).ToString();
// Make sure the user had selected a category
if (cbxCategories.Text.Length == 0)
{
MessageBox.Show("You must specify the item's category");
cbxCategories.Focus();
return;
}
// Make sure the user had selected a type
if (cbxTypes.Text.Length == 0)
{
MessageBox.Show("You must specify the item's type");
cbxTypes.Focus();
return;
}
// Make sure the user had entered a name/description
if (txtItemName.Text.Length == 0)
{
MessageBox.Show("You must enter the name (or a " +
"short description) for the item");
txtItemName.Focus();
return;
}
// Make sure the user had typed a price for the item
if (txtUnitPrice.Text.Length == 0)
{
MessageBox.Show("You must enter the price of the item");
txtUnitPrice.Focus();
return;
}
// Before saving the new item, find out if there was
// already a file that holds the list of items
// If that file exists, open it and store its items
// in our StoreItems list
if (File.Exists(FileName))
{
stmStoreItem = new FileStream(FileName,
FileMode.Open,
FileAccess.Read,
FileShare.Read);
try
{
// Retrieve the list of items from file
items = (StoreItems)bfmStoreItem.Deserialize(stmStoreItem);
}
finally
{
stmStoreItem.Close();
}
}
// Create the music item
item.ItemNumber = txtItemNumber.Text;
item.Category = cbxCategories.Text;
item.Type = cbxTypes.Text;
item.ItemName = txtItemName.Text;
item.UnitPrice = double.Parse(txtUnitPrice.Text);
// Call the Add method of our collection class to add the item
items.Add(item);
// Save the list
stmStoreItem = new FileStream(FileName,
FileMode.Create,
FileAccess.Write,
FileShare.Write);
try
{
bfmStoreItem.Serialize(stmStoreItem, items);
if (txtPicturePath.Text.Length != 0)
{
FileInfo flePicture = new FileInfo(txtPicturePath.Text);
flePicture.CopyTo(@"C:\Musical Instrument Store\" +
txtItemNumber.Text + flePicture.Extension);
}
// After saving the item, reset the form
txtItemNumber.Text = rnd.Next(100000, 999999).ToString();
cbxCategories.Text = "";
cbxTypes.Text = "";
txtItemName.Text = "";
txtUnitPrice.Text = "0.00";
txtPicturePath.Text = "";
pbxStoreItem.Image = null;
}
finally
{
stmStoreItem.Close();
}
}
|
- In the Class View, click StoreItems
- In the lower part of the Class View, double-click this[int]
- Change the code of the property as
follows:
public virtual object this[int index]
{
get { return items[index]; }
set { items[index] = value; }
}
|
- In the Solution Explorer, double-click ItemEditor.cs
- Double-click an unoccupied area of the form and implement its Load
event as follows:
private void ItemEditor_Load(object sender, EventArgs e)
{
// Since all values seem ready, prepare to process the item
StoreItem item = new StoreItem();
StoreItems items = new StoreItems();
BinaryFormatter bfmStoreItem = new BinaryFormatter();
// This is the file that holds the list of items
string FileName = @"C:\Musical Instrument Store\StoreItems.mis";
if (File.Exists(FileName))
{
FileStream stmStoreItem = new FileStream(FileName,
FileMode.Open,
FileAccess.Read,
FileShare.Read);
try
{
// Retrieve the list of items from file
items = (StoreItems)bfmStoreItem.Deserialize(stmStoreItem);
// Display the categories in the combo box
for (int i = 0; i < items.Count; i++)
{
item = (StoreItem)items[i];
if (!cbxCategories.Items.Contains(item.Category))
cbxCategories.Items.Add(item.Category);
}
// Display the items types in the combo box
for (int i = 0; i < items.Count; i++)
{
item = (StoreItem)items[i];
if (!cbxTypes.Items.Contains(item.Type))
cbxTypes.Items.Add(item.Type);
}
}
finally
{
stmStoreItem.Close();
}
}
else
{
// Create a random number that will be used
// to identify the item
Random rnd = new Random();
txtItemNumber.Text = rnd.Next(100000, 999999).ToString();
// Make sure the user had selected a category
cbxCategories.Text = "";
cbxTypes.Text = "";
}
}
|
- In the Solution Explorer, double-click MusicStore.cs
- Right-click the form and click View Code
- Make the following changes:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace MusicalInstrumentStore21
{
public partial class MusicStore : Form
{
StoreItems items;
int iFileName;
bool IsNewCustomerOrder;
public MusicStore()
{
InitializeComponent();
}
void LoadMusicStore()
{
// Since all values seem ready, prepare to process the item
items = new StoreItems();
BinaryFormatter bfmStoreItem = new BinaryFormatter();
// This is the file that holds the list of items
string FileName = @"C:\Musical Instrument Store\StoreItems.mis";
if (File.Exists(FileName))
{
FileStream stmStoreItem = new FileStream(FileName,
FileMode.Open,
FileAccess.Read,
FileShare.Read);
try
{
// Retrieve the list of items from file
items = (StoreItems)bfmStoreItem.Deserialize(stmStoreItem);
// Display the categories in the combo box
for (int i = 0; i < items.Count; i++)
{
StoreItem item = (StoreItem)items[i];
if (!cbxCategories.Items.Contains(item.Category))
cbxCategories.Items.Add(item.Category);
}
}
finally
{
stmStoreItem.Close();
}
}
}
}
}
|
- Return to the Music Store form
- On the form, double-click New
Store Item
- Implement the event as follows:
private void btnNewStoreItem_Click(object sender, EventArgs e)
{
ItemEditor editor = new ItemEditor();
// Create a random number to get it ready for
// the user creating a new store item
Random rnd = new Random();
editor.txtItemNumber.Text = rnd.Next(100000, 999999).ToString();
if (editor.ShowDialog() == DialogResult.Cancel)
LoadMusicStore();
}
|
- Return to the Music Store form
- Double-click the Categories combo box and implement its event as follows:
private void cbxCategories_SelectedIndexChanged(object sender, EventArgs e)
{
cbxTypes.Items.Clear();
cbxTypes.Text = "";
lvwStoreItems.Items.Clear();
pbxStoreItem.Image = null;
if (items.Count == 0)
return;
string strCategory = (string)cbxCategories.SelectedItem;
cbxTypes.Items.Clear();
for (int i = 0; i < items.Count; i++)
{
StoreItem item = (StoreItem)items[i];
if (item.Category == strCategory)
{
if (!cbxTypes.Items.Contains(item.Type))
cbxTypes.Items.Add(item.Type);
}
}
}
|
- Return to the Music Store form
- Double-click the Item Type combo box and implement its event as follows:
private void cbxTypes_SelectedIndexChanged(object sender, EventArgs e)
{
lvwStoreItems.Items.Clear();
cbxTypes.Text = "";
pbxStoreItem.Image = null;
if (items.Count == 0)
return;
string strCategory = (string)cbxCategories.SelectedItem;
string strType = (string)cbxTypes.SelectedItem;
lvwStoreItems.Items.Clear();
for (int i = 0; i < items.Count; i++)
{
StoreItem item = (StoreItem)items[i];
if ((item.Category == strCategory) &&
(item.Type == strType))
{
ListViewItem lviStoreItem =
lvwStoreItems.Items.Add(item.ItemNumber);
lviStoreItem.SubItems.Add(item.ItemName);
lviStoreItem.SubItems.Add(item.UnitPrice.ToString("F"));
}
}
}
|
- Return to the Music Store form
- On the form, double-click the Available Items list view and implement its
SelectedIndexChanged event as
follows:
private void lvwStoreItems_SelectedIndexChanged(object sender, EventArgs e)
{
StoreItem item = new StoreItem();
if ((lvwStoreItems.SelectedItems.Count == 0) ||
(lvwStoreItems.SelectedItems.Count > 1))
return;
string strItemNumber =
lvwStoreItems.SelectedItems[0].SubItems[0].Text;
for (int i = 0; i < items.Count; i++)
{
StoreItem itm = (StoreItem)items[i];
if (itm.ItemNumber == strItemNumber)
item = itm;
}
// Make a list of the picture files
string strDirectory = @"C:\Musical Instrument Store";
DirectoryInfo dirStoreItems = new DirectoryInfo(strDirectory);
FileInfo[] PictureFiles = dirStoreItems.GetFiles("*.jpg");
// Look for a file that holds the same name as the item number
foreach (FileInfo fle in PictureFiles)
{
// Get the name of the file without its extension
string fwe = Path.GetFileNameWithoutExtension(fle.FullName);
if (fwe == strItemNumber)
pbxStoreItem.Image = Image.FromFile(strDirectory +
"\\" + item.ItemNumber + ".jpg");
}
}
|
- Return to the Music Store form
- Click the Available Items list view
- In the Properties window, click the Events button and double-click
DoubleClick
- Implement the event as follows:
internal void CalculateOrder()
{
// Calculate the current total order and update the order
double subTotal1 = 0.00, subTotal2 = 0.00, subTotal3 = 0.00,
subTotal4 = 0.00, subTotal5 = 0.00, subTotal6 = 0.00;
double itemsTotal = 0.00, taxRate = 0.00,
taxAmount = 0.00, orderTotal = 0.00;
// Retrieve the value of each sub total
try
{
subTotal1 = double.Parse(this.txtSubTotal1.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
subTotal2 = double.Parse(this.txtSubTotal2.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
subTotal3 = double.Parse(this.txtSubTotal3.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
subTotal4 = double.Parse(this.txtSubTotal4.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
subTotal5 = double.Parse(this.txtSubTotal5.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
subTotal6 = double.Parse(this.txtSubTotal6.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
// Calculate the total value of the sub totals
itemsTotal = subTotal1 + subTotal2 + subTotal3 +
subTotal4 + subTotal5 + subTotal6;
// Display the total order in the appropriate text box
txtItemsTotal.Text = itemsTotal.ToString();
try
{
taxRate = double.Parse(txtTaxRate.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Tax Rate");
txtTaxRate.Text = "7.75";
txtTaxRate.Focus();
}
taxAmount = itemsTotal * taxRate / 100;
orderTotal = itemsTotal + taxAmount;
txtTaxAmount.Text = taxAmount.ToString("F");
txtOrderTotal.Text = orderTotal.ToString("F");
}
private void lvwStoreItems_DoubleClick(object sender, EventArgs e)
{
ListViewItem lviStoreItem = lvwStoreItems.SelectedItems[0];
if( (lvwStoreItems.SelectedItems.Count == 0) ||
(lvwStoreItems.SelectedItems.Count > 1) )
return;
if(txtItemNumber1.Text == "")
{
txtItemNumber1.Text = lviStoreItem.Text;
txtDescription1.Text = lviStoreItem.SubItems[1].Text;
txtUnitPrice1.Text = lviStoreItem.SubItems[2].Text;
txtQuantity1.Text = "1";
txtSubTotal1.Text = lviStoreItem.SubItems[2].Text;
btnRemove1.Enabled = true;
txtQuantity1.Focus();
}// If the previous item # text box is not empty, then use the next one
else if (txtItemNumber2.Text == "")
{
txtItemNumber2.Text = lviStoreItem.Text;
txtDescription2.Text = lviStoreItem.SubItems[1].Text;
txtUnitPrice2.Text = lviStoreItem.SubItems[2].Text;
txtQuantity2.Text = "1";
txtSubTotal2.Text = txtUnitPrice2.Text;
btnRemove2.Enabled = true;
txtQuantity2.Focus();
}
else if (txtItemNumber3.Text == "")
{
txtItemNumber3.Text = lviStoreItem.Text;
txtDescription3.Text = lviStoreItem.SubItems[1].Text;
txtUnitPrice3.Text = lviStoreItem.SubItems[2].Text;
txtQuantity3.Text = "1";
txtSubTotal3.Text = txtUnitPrice3.Text;
btnRemove3.Enabled = true;
txtQuantity3.Focus();
}
else if (txtItemNumber4.Text == "")
{
txtItemNumber4.Text = lviStoreItem.Text;
txtDescription4.Text = lviStoreItem.SubItems[1].Text;
txtUnitPrice4.Text = lviStoreItem.SubItems[2].Text;
txtQuantity4.Text = "1";
txtSubTotal4.Text = txtUnitPrice4.Text;
btnRemove4.Enabled = true;
txtQuantity4.Focus();
}
else if (txtItemNumber5.Text == "")
{
txtItemNumber5.Text = lviStoreItem.Text;
txtDescription5.Text = lviStoreItem.SubItems[1].Text;
txtUnitPrice5.Text = lviStoreItem.SubItems[2].Text;
txtQuantity5.Text = "1";
txtSubTotal5.Text = txtUnitPrice5.Text;
btnRemove5.Enabled = true;
txtQuantity5.Focus();
}
else if (txtItemNumber6.Text == "")
{
txtItemNumber6.Text = lviStoreItem.Text;
txtDescription6.Text = lviStoreItem.SubItems[1].Text;
txtUnitPrice6.Text = lviStoreItem.SubItems[2].Text;
txtQuantity6.Text = "1";
txtSubTotal6.Text = txtUnitPrice6.Text;
btnRemove6.Enabled = true;
txtQuantity6.Focus();
} // If all item # text boxes are filled, don't do anything
else
return;
CalculateOrder();
}
|
- Return to the Music Store form
- On the form, click the top Unit Price text box
- Press and hold Shift
- Click the top Qty text box and release Shift
- In the Events section of the Properties window, double-click Leave and
implement the event as follows:
private void txtUnitPrice1_Leave(object sender, EventArgs e)
{
int qty = 0;
decimal unitPrice = 0.00M, subTotal = 0.00M;
// Get the quantity of the current item
try
{
qty = int.Parse(this.txtQuantity1.Text);
}
catch (FormatException)
{
// MessageBox.Show("Invalid quantity value for item 1");
}
// Get the unit price of the current item
try
{
unitPrice = decimal.Parse(this.txtUnitPrice1.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid unit price for item 1");
}
// Calculate the current sub total
subTotal = qty * unitPrice;
// Display the new sub total in the corresponding text box
txtSubTotal1.Text = subTotal.ToString();
btnRemove1.Enabled = true;
// Update the order
CalculateOrder();
}
|
- Return to the Music Store form
- On the form, double-click the top Remove button and implement the event as
follows:
private void btnRemove1_Click(object sender, EventArgs e)
{
txtItemNumber1.Text = "";
txtDescription1.Text = "";
txtUnitPrice1.Text = "0.00";
txtQuantity1.Text = "0";
txtSubTotal1.Text = "0.00";
btnRemove1.Enabled = false;
CalculateOrder();
}
|
- Return to the Music Store form
- On the form, click the second Unit Price text box
- Press and hold Shift
- Click the second Qty text box and release Shift
- In the Events section of the Properties window, double-click Leave and
implement the event as follows:
private void txtUnitPrice2_Leave(object sender, EventArgs e)
{
int qty = 0;
decimal unitPrice = 0.00M, subTotal = 0.00M;
try
{
qty = int.Parse(this.txtQuantity2.Text);
}
catch (FormatException)
{
// MessageBox.Show("Invalid quantity value for item 2");
}
try
{
unitPrice = decimal.Parse(this.txtUnitPrice2.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid unit price for item 2");
}
subTotal = qty * unitPrice;
this.txtSubTotal2.Text = subTotal.ToString();
btnRemove2.Enabled = true;
CalculateOrder();
}
|
- Return to the Music Store form
- On the form, double-click the second Remove button and implement the event
as follows:
private void btnRemove2_Click(object sender, EventArgs e)
{
txtItemNumber2.Text = "";
txtDescription2.Text = "";
txtUnitPrice2.Text = "0.00";
txtQuantity2.Text = "0";
txtSubTotal2.Text = "0.00";
btnRemove2.Enabled = false;
CalculateOrder();
}
|
- Return to the Music Store form
- On the form, click the third Unit Price text box
- Press and hold Shift
- Click the third Qty text box and release Shift
- In the Events section of the Properties window, double-click Leave and
implement the event as follows:
private void txtUnitPrice3_Leave(object sender, EventArgs e)
{
int qty = 0;
decimal unitPrice = 0.00M, subTotal = 0.00M;
try
{
qty = int.Parse(this.txtQuantity3.Text);
}
catch (FormatException)
{
// MessageBox.Show("Invalid quantity value for item 3");
}
try
{
unitPrice = decimal.Parse(this.txtUnitPrice3.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid unit price for item 3");
}
subTotal = qty * unitPrice;
this.txtSubTotal3.Text = subTotal.ToString();
btnRemove3.Enabled = true;
CalculateOrder();
}
|
- Return to the Music Store form
- On the form, double-click the third Remove button and implement the event
as follows:
private void btnRemove3_Click(object sender, EventArgs e)
{
txtItemNumber3.Text = "";
txtDescription3.Text = "";
txtUnitPrice3.Text = "0.00";
txtQuantity3.Text = "0";
txtSubTotal3.Text = "0.00";
btnRemove3.Enabled = false;
CalculateOrder();
}
|
- Return to the Music Store form
- On the form, click the fourth Unit Price text box
- Press and hold Shift
- Click the fourth Qty text box and release Shift
- In the Events section of the Properties window, double-click Leave and
implement the event as follows:
private void txtUnitPrice4_Leave(object sender, EventArgs e)
{
int qty = 0;
decimal unitPrice = 0.00M, subTotal = 0.00M;
try
{
qty = int.Parse(this.txtQuantity4.Text);
}
catch (FormatException)
{
// MessageBox.Show("Invalid quantity value for item 4");
}
try
{
unitPrice = decimal.Parse(this.txtUnitPrice4.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid unit price for item 4");
}
subTotal = qty * unitPrice;
this.txtSubTotal4.Text = subTotal.ToString();
btnRemove4.Enabled = true;
CalculateOrder();
}
|
- Return to the Music Store form
- On the form, double-click the fourth Remove button and implement the event
as follows:
private void btnRemove4_Click(object sender, EventArgs e)
{
txtItemNumber4.Text = "";
txtDescription4.Text = "";
txtUnitPrice4.Text = "0.00";
txtQuantity4.Text = "0";
txtSubTotal4.Text = "0.00";
btnRemove4.Enabled = false;
CalculateOrder();
}
|
- Return to the Music Store form
- On the form, click the fifth Unit Price text box
- Press and hold Shift
- Click the fifth Qty text box and release Shift
- In the Events section of the Properties window, double-click Leave and
implement the event as follows:
private void txtUnitPrice5_Leave(object sender, EventArgs e)
{
int qty = 0;
decimal unitPrice = 0.00M, subTotal = 0.00M;
try
{
qty = int.Parse(this.txtQuantity5.Text);
}
catch (FormatException)
{
// MessageBox.Show("Invalid quantity value for item 5");
}
try
{
unitPrice = decimal.Parse(this.txtUnitPrice5.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid unit price for item 5");
}
subTotal = qty * unitPrice;
this.txtSubTotal5.Text = subTotal.ToString();
btnRemove5.Enabled = true;
CalculateOrder();
}
|
- Return to the Music Store form
- On the form, double-click the fifth Remove button and implement the event
as follows:
private void btnRemove5_Click(object sender, EventArgs e)
{
txtItemNumber5.Text = "";
txtDescription5.Text = "";
txtUnitPrice5.Text = "0.00";
txtQuantity5.Text = "0";
txtSubTotal5.Text = "0.00";
btnRemove5.Enabled = false;
CalculateOrder();
}
|
- Return to the Music Store form
- On the form, click the sixth Unit Price text box
- Press and hold Shift
- Click the sixth Qty text box and release Shift
- In the Events section of the Properties window, double-click Leave and
implement the event as follows:
private void txtUnitPrice6_Leave(object sender, EventArgs e)
{
int qty = 0;
decimal unitPrice = 0.00M, subTotal = 0.00M;
try
{
qty = int.Parse(this.txtQuantity6.Text);
}
catch (FormatException)
{
// MessageBox.Show("Invalid quantity value for item 6");
}
try
{
unitPrice = decimal.Parse(this.txtUnitPrice6.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid unit price for item 6");
}
subTotal = qty * unitPrice;
this.txtSubTotal6.Text = subTotal.ToString();
btnRemove6.Enabled = true;
CalculateOrder();
}
|
- Return to the Music Store form
- On the form, double-click the sixth Remove button and implement the event
as follows:
private void btnRemove6_Click(object sender, EventArgs e)
{
txtItemNumber6.Text = "";
txtDescription6.Text = "";
txtUnitPrice6.Text = "0.00";
txtQuantity6.Text = "0";
txtSubTotal6.Text = "0.00";
btnRemove6.Enabled = false;
CalculateOrder();
}
|
- Return to the Music Store form
- On the form, click the Tax Rate text box
- In the Events section of the Properties window, double-click Leave and
implement the event as follows:
private void txtTaxRate_Leave(object sender, EventArgs e)
{
CalculateOrder();
}
|
- Return to the Music Store form
- Double-click the New Order button and implement its event as follows:
private void btnNewCustomerOrder_Click(object sender, EventArgs e)
{
// We will store our files in the following folder
string strDirectory = @"C:\Musical Instrument Store\Receipts";
DirectoryInfo dirInfo = Directory.CreateDirectory(strDirectory);
// Get the list of files, if any, from our directory
FileInfo[] fleList = dirInfo.GetFiles();
string strFilename = "";
// If there is no file in the directory,
// then we will use 1000 as the first file name
if (fleList.Length == 0)
{
iFileName = 1000;
}
else // If there was at least one file in the directory
{
// Get a reference to the last file
FileInfo fleLast = fleList[fleList.Length - 1];
// Get the name of the last file without its extension
string fwe = Path.GetFileNameWithoutExtension(fleLast.FullName);
// Increment the name of the file by 1
iFileName = int.Parse(fwe) + 1;
}
// Update our global name of the file
strFilename = strDirectory + "\\" + iFileName.ToString() + ".cos";
txtReceiptNumber.Text = iFileName.ToString();
cbxCategories.Text = "";
cbxTypes.Text = "";
lvwStoreItems.Items.Clear();
txtItemNumber1.Text = "";
txtDescription1.Text = "";
txtUnitPrice1.Text = "0.00";
txtQuantity1.Text = "0";
txtSubTotal1.Text = "0.00";
txtItemNumber2.Text = "";
txtDescription2.Text = "";
txtUnitPrice2.Text = "0.00";
txtQuantity2.Text = "0.00";
txtSubTotal2.Text = "0.00";
txtItemNumber3.Text = "";
txtDescription3.Text = "";
txtUnitPrice3.Text = "0.00";
txtQuantity3.Text = "0.00";
txtSubTotal3.Text = "0.00";
txtItemNumber4.Text = "";
txtDescription4.Text = "";
txtUnitPrice4.Text = "0.00";
txtQuantity4.Text = "0.00";
txtSubTotal4.Text = "0.00";
txtItemNumber5.Text = "";
txtDescription5.Text = "";
txtUnitPrice5.Text = "0.00";
txtQuantity5.Text = "0.00";
txtSubTotal5.Text = "0.00";
txtItemNumber6.Text = "";
txtDescription6.Text = "";
txtUnitPrice6.Text = "0.00";
txtQuantity6.Text = "0.00";
txtSubTotal6.Text = "0.00";
txtItemsTotal.Text = "0.00";
txtTaxRate.Text = "7.75";
txtTaxAmount.Text = "0.00";
txtTotalOrder.Text = "0.00";
}
|
- Return to the Music Store form
- Double-click the Save button and implement the event as follows:
private void btnSave_Click(object sender, EventArgs e)
{
// We will store our files in the following folder
string strDirectory = @"C:\Musical Instrument Store\Receipts";
DirectoryInfo dirInfo = Directory.CreateDirectory(strDirectory);
// Get the list of files, if any, from our directory
FileInfo[] fleList = dirInfo.GetFiles();
string strFilename = "";
// If this is a new customer order,
// get ready to create a name for the file
if (IsNewCustomerOrder == true)
{
// If there is no file in the directory,
// then we will use 1000 as the first file name
if (fleList.Length == 0)
{
iFileName = 1000;
}
else // If there was at least one file in the directory
{
// Get a reference to the last file
FileInfo fleLast = fleList[fleList.Length - 1];
// Get the name of the last file without its extension
string fwe = Path.GetFileNameWithoutExtension(fleLast.FullName);
// Increment the name of the file by 1
iFileName = int.Parse(fwe) + 1;
}
// Update our global name of the file
strFilename = strDirectory + "\\" + iFileName.ToString() + ".cos";
txtReceiptNumber.Text = iFileName.ToString();
IsNewCustomerOrder = false;
} // If a cleaning order was already opened, we will simply update it
else
strFilename = @"C:\Musical Instrument Store\Receipts\" +
txtReceiptNumber.Text + ".cos";
StreamWriter wrtCustomerOrder = new StreamWriter(strFilename);
try
{
wrtCustomerOrder.WriteLine(txtItemNumber1.Text);
wrtCustomerOrder.WriteLine(txtDescription1.Text);
wrtCustomerOrder.WriteLine(txtUnitPrice1.Text);
wrtCustomerOrder.WriteLine(txtQuantity1.Text);
wrtCustomerOrder.WriteLine(txtItemNumber2.Text);
wrtCustomerOrder.WriteLine(txtDescription2.Text);
wrtCustomerOrder.WriteLine(txtUnitPrice2.Text);
wrtCustomerOrder.WriteLine(txtQuantity2.Text);
wrtCustomerOrder.WriteLine(txtItemNumber3.Text);
wrtCustomerOrder.WriteLine(txtDescription3.Text);
wrtCustomerOrder.WriteLine(txtUnitPrice3.Text);
wrtCustomerOrder.WriteLine(txtQuantity3.Text);
wrtCustomerOrder.WriteLine(txtItemNumber4.Text);
wrtCustomerOrder.WriteLine(txtDescription4.Text);
wrtCustomerOrder.WriteLine(txtUnitPrice4.Text);
wrtCustomerOrder.WriteLine(txtQuantity4.Text);
wrtCustomerOrder.WriteLine(txtItemNumber5.Text);
wrtCustomerOrder.WriteLine(txtDescription5.Text);
wrtCustomerOrder.WriteLine(txtUnitPrice5.Text);
wrtCustomerOrder.WriteLine(txtQuantity5.Text);
wrtCustomerOrder.WriteLine(txtItemNumber6.Text);
wrtCustomerOrder.WriteLine(txtDescription6.Text);
wrtCustomerOrder.WriteLine(txtUnitPrice6.Text);
wrtCustomerOrder.WriteLine(txtQuantity6.Text);
wrtCustomerOrder.WriteLine(txtItemsTotal.Text);
wrtCustomerOrder.WriteLine(txtTaxRate.Text);
}
finally
{
wrtCustomerOrder.Close();
}
}
|
- Return to the Music Store Form
- Double-click the Open button and implement its event as follows:
private void btnOpen_Click(object sender, EventArgs e)
{
string strDirectory = @"C:\Musical Instrument Store\Receipts";
string strFilename = @"C:\Musical Instrument Store\Receipts\1000.cos";
if (txtReceiptNumber.Text == "")
return;
else
{
try
{
//IsNewCleaningOrder = false;
strFilename = strDirectory + "\\" +
txtReceiptNumber.Text + ".cos";
StreamReader rdrCustomerOrder = new StreamReader(strFilename);
try
{
txtItemNumber1.Text = rdrCustomerOrder.ReadLine();
txtDescription1.Text = rdrCustomerOrder.ReadLine();
txtUnitPrice1.Text = rdrCustomerOrder.ReadLine();
txtQuantity1.Text = rdrCustomerOrder.ReadLine();
txtUnitPrice1_Leave(sender, e);
txtItemNumber2.Text = rdrCustomerOrder.ReadLine();
txtDescription2.Text = rdrCustomerOrder.ReadLine();
txtUnitPrice2.Text = rdrCustomerOrder.ReadLine();
txtQuantity2.Text = rdrCustomerOrder.ReadLine();
txtUnitPrice2_Leave(sender, e);
txtItemNumber3.Text = rdrCustomerOrder.ReadLine();
txtDescription3.Text = rdrCustomerOrder.ReadLine();
txtUnitPrice3.Text = rdrCustomerOrder.ReadLine();
txtQuantity3.Text = rdrCustomerOrder.ReadLine();
txtUnitPrice3_Leave(sender, e);
txtItemNumber4.Text = rdrCustomerOrder.ReadLine();
txtDescription4.Text = rdrCustomerOrder.ReadLine();
txtUnitPrice4.Text = rdrCustomerOrder.ReadLine();
txtQuantity4.Text = rdrCustomerOrder.ReadLine();
txtUnitPrice4_Leave(sender, e);
txtItemNumber5.Text = rdrCustomerOrder.ReadLine();
txtDescription5.Text = rdrCustomerOrder.ReadLine();
txtUnitPrice5.Text = rdrCustomerOrder.ReadLine();
txtQuantity5.Text = rdrCustomerOrder.ReadLine();
txtUnitPrice5_Leave(sender, e);
txtItemNumber6.Text = rdrCustomerOrder.ReadLine();
txtDescription6.Text = rdrCustomerOrder.ReadLine();
txtUnitPrice6.Text = rdrCustomerOrder.ReadLine();
txtQuantity6.Text = rdrCustomerOrder.ReadLine();
txtUnitPrice6_Leave(sender, e);
txtItemsTotal.Text = rdrCustomerOrder.ReadLine();
txtTaxRate.Text = rdrCustomerOrder.ReadLine();
CalculateOrder();
IsNewCustomerOrder = false;
}
finally
{
rdrCustomerOrder.Close();
}
}
catch (FileNotFoundException)
{
MessageBox.Show("There is no customer order with that receipt number");
}
}
}
|
- Return to the Music Store form
- Double-click an unoccupied area of the form and implement the event as
follows:
private void MusicStore_Load(object sender, EventArgs e)
{
btnNewCustomerOrder_Click(sender, e);
LoadMusicStore();
IsNewCustomerOrder = true;
}
|
- Return to the Music Store form
- Double-click the Close and implement its Click event as follows:
private void btnClose_Click(object sender, EventArgs e)
{
Close();
}
|
- Execute the application to test it
- Access the Item Editor dialog box and create a few items as follows
(let the computer create the item numbers):
| Category |
Type |
Item Name |
Unit Price |
Picture |
| Guitars |
Electric |
Gibson Les Paul Vintage Mahogany Electric Guitar |
745.95 |
Picture |
| Bass |
Electric 4-String |
Epiphone Thunderbird IV Bass |
325.85 |
Picture |
| Keyboards |
Synthesizers |
Alesis QS8.2 88 Key Synthesizer |
825.50 |
Picture |
| Guitars |
Acoustic |
Gretsch Guitars G100 Synchromatic Archtop Acoustic Guitar |
595.95 |
Picture |
| Drums |
Drum Set |
Pulse Pro 5-Piece Drum Set with Cymbals |
395.95 |
Picture |
| Keyboards |
Pianos |
Roland RD-700SX Digital Piano |
2195.00 |
|
| Accessories |
Cables |
Mogami Gold AES/EBU Interconnect Cable with Neutrik XLR |
45.85 |
|
| Guitars |
Acoustic-Electric |
Ibanez V Series V70CE Dreadnought Cutaway Acoustic-Electric Guitar |
225.50 |
|
| Guitars |
Electric |
Schecter C-1 Hellraiser Electric Guitar |
650.00 |
Picture |
| Keyboards |
Synthesizers |
Roland V Synth GT Elastic Audio Synthesizer Keyboard |
2895.50 |
Picture |
| Bass |
Electric 5-String |
Fender Jazz Bass 24 V 5-String Bass Guitar |
825.50 |
Picture |
| Guitars |
Electric |
Fender Standard Stratocaster Left-Handed Electric Guitar |
425.85 |
Picture |
| Recording |
Microphone |
MXL V63M Studio Condenser Microphone |
72.95 |
Picture |
| Guitars |
Acoustic |
Yamaha FD01S Acoustic Folk Guitar |
185.95 |
|
| Book/CD/DVD |
Instructional |
Hal Leonard Amazing Phrasing - Alto Sax (Book/CD) |
18.00 |
|
| Guitars |
Classical & Nylon |
Alvarez Artist Series AC60S Classical Acoustic Guitar |
275.95 |
Picture |
| Guitars |
Acoustic |
Washburn D100DL Acoustic Guitar |
150.50 |
Picture |
| Drums |
Electronic Percussion |
Boss DR-670 Dr. Rhythm Drum Machine |
275.85 |
Picture |
| Recording |
Microphone |
Shure SM58 Mic |
95.95 |
Picture |
| Accessories |
Cables |
Live Wire HPE325 Headphone and Extension Cable |
10.95 |
Picture |
| Bass |
Acoustic Fretted |
Ibanez AEB10E Acoustic-Electric Bass Guitar with Onboard Tuner |
350.00 |
Picture |
| Drums |
World Percussion |
Latin Percussion Conga 3-Pack with Bongos |
595.95 |
Picture |
| Keyboards |
Synthesizers |
Roland JUNO-D 61-Key Synthesizer |
595.95 |
Picture |
| Drums |
World Percussion |
Latin Percussion Aspire Conga Set with Bongos and Stand |
425.50 |
Picture |
| Recording |
Microphone |
AKG Perception 200 Condenser Microphone |
160.00 |
Picture |
|
 |
 |
 |
|
- Create a few customers' orders and click Save then New Order each
time. Here are examples:
- Close the form and return to your programming environment
|
|