![]() |
Lists-Based Applications: The Music Store |
The DataSet of the .NET Framework is a very impressive object. It allows you to create and manage any type of list. This makes it a central point for a list-based application, although it is highly used in formal database applications such as those intended for Microsoft SQL Server or Microsoft Access. To support the creation and management of any type of database, the DataSet class has complete built-in mechanisms for creating tables, their associated columns, and to perform data entry. To demonstrate these functionalities of the DataSet, we are going to create a list-based application that can serve as another introduction to databases. The application simulates a music instrument store that processes orders for customers. When a customer comes to the store to purchase a product, the employee can select items by categories, specify the quantity, calculate the total order, and save it.
|
|
Application Data Entry |
|
To perform data entry, we will apply the concepts reviewed for data records. |
|
|

| (Name) | ColumnName | Modifiers |
| colItemNumber | ItemNumber | Public |
| colItemCategory | Category | Public |
| colTypeOfItem | ItemType | Public |
| colItemName | ItemName | Public |
| colUnitPrice | UnitPrice | Public |
#pragma once #include "DataCenter.h" using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; |
System::Void btnAdd_Click(System::Object * sender, System::EventArgs * e)
{
// Get a reference to the Data Center because
// that's where the DataSet object resides
DataCenter *frmData = new DataCenter;
// Create a new record for the Categories table
DataRow *rowNewCategory = frmData->dsMusicStore->Tables->Item[S"Categories"]->NewRow();
// Specify only the Category column since the CategoryID is auto-incrementing
rowNewCategory->Item[0] = this->txtNewCategory->Text;
// Add the new record to the Categories table
frmData->dsMusicStore->Tables->Item[S"Categories"]->Rows->Add(rowNewCategory);
// Display the current records of the Categories table so
// the user would know what categories are already in the table
this->dataGrid1->DataSource = frmData->dsMusicStore;
this->dataGrid1->DataMember = S"Categories";
// Reset the text box in case the user wants to add another category
this->txtNewCategory->Text = S"";
this->txtNewCategory->Focus();
}
|
#pragma once #include "DataCenter.h" using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; |
System::Void btnAdd_Click(System::Object * sender, System::EventArgs * e)
{
DataCenter *frmData = new DataCenter;
DataRow *rowNewType = frmData->dsMusicStore->Tables->Item[S"ItemTypes"]->NewRow();
rowNewType->Item[frmData->colItemType] = this->txtNewItemType->Text;
frmData->dsMusicStore->Tables->Item[S"ItemTypes"]->Rows->Add(rowNewType);
this->dataGrid1->DataSource = frmData->dsMusicStore;
this->dataGrid1->DataMember = S"ItemTypes";
this->txtNewItemType->Text = S"";
this->txtNewItemType->Focus();
}
|
|
Saving the Items and the Orders |
|
Based on the close relationship between the DataSet class and XML, we will save our records as XML. |
|
|
#pragma once
#include "DataCenter.h"
namespace MusicStore2a
{
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::Xml;
. . . No Change
. . . No Change
System::Void btnAdd_Click(System::Object * sender, System::EventArgs * e)
{
// Get a reference to the Data Center because
// that's where the DataSet object resides
DataCenter *frmData = new DataCenter;
// This is the XML file that will holds the Categories
String *strFilename = S"Categories.xml";
// If the file exists already, open it
if( File::Exists(strFilename) )
frmData->dsMusicStore->ReadXml(strFilename);
// Create a new record for the Categories table
DataRow *rowNewCategory = frmData->dsMusicStore->Tables->Item[S"Categories"]->NewRow();
// Specify only the Category column since the CategoryID is auto-incrementing
rowNewCategory->Item[0] = this->txtNewCategory->Text;
// Add the new record to the Categories table
frmData->dsMusicStore->Tables->Item[S"Categories"]->Rows->Add(rowNewCategory);
// Update the XML file
frmData->dsMusicStore->WriteXml(strFilename);
// Display the current records of the Categories table so
// the user would know what categories are already in the table
this->dataGrid1->DataSource = frmData->dsMusicStore;
this->dataGrid1->DataMember = S"Categories";
// Reset the text box in case the user wants to add another category
this->txtNewCategory->Text = S"";
this->txtNewCategory->Focus();
}
};
}
|
#pragma once
#include "DataCenter.h"
namespace MusicStore2a
{
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::Xml;
. . . No Change
System::Void btnAdd_Click(System::Object * sender, System::EventArgs * e)
{
DataCenter *frmData = new DataCenter;
String *strFilename = S"ItemTypes.xml";
if( File::Exists(strFilename) )
frmData->dsMusicStore->ReadXml(strFilename);
DataRow *rowNewType = frmData->dsMusicStore->Tables->Item[S"ItemTypes"]->NewRow();
rowNewType->Item[frmData->colItemType] = this->txtNewItemType->Text;
frmData->dsMusicStore->Tables->Item[S"ItemTypes"]->Rows->Add(rowNewType);
frmData->dsMusicStore->WriteXml(strFilename);
this->dataGrid1->DataSource = frmData->dsMusicStore;
this->dataGrid1->DataMember = S"ItemTypes";
this->txtNewItemType->Text = S"";
this->txtNewItemType->Focus();
}
};
}
|
System::Void NewStoreItem_Load(System::Object * sender, System::EventArgs * e)
{
DataCenter *frmData = new DataCenter;
XmlTextReader * rdrMusicStore = 0;
try {
String *strFilename = S"Categories.xml";
if( File::Exists(strFilename) )
{
rdrMusicStore = new XmlTextReader(strFilename);
// Scan the XML file
while (rdrMusicStore->Read())
{
// every time you find an element, find out what type it is
// If you find a category, put it in the Categories list box
if( XmlNodeType::Element && rdrMusicStore->Name->Equals(S"Category") )
{
this->cboCategories->Items->Add(rdrMusicStore->ReadElementString(S"Category"));
}
}
}
strFilename = S"ItemTypes.xml";
if( File::Exists(strFilename) )
{
rdrMusicStore = new XmlTextReader(strFilename);
// Scan the XML file
while (rdrMusicStore->Read())
{
// every time you find an element, find out what type it is
// If you find an ItemType, put it in the Item Types list box
if( XmlNodeType::Element && rdrMusicStore->Name->Equals(S"ItemType") )
{
this->cboItemTypes->Items->Add(rdrMusicStore->ReadElementString(S"ItemType"));
}
}
}
}
catch(XmlException *)
{
MessageBox::Show(S"Invalid XML file");
}
__finally
{
if( rdrMusicStore != 0 )
rdrMusicStore->Close();
}
// We will generate a random number for the store item
DateTime tmeNow = DateTime::Now;
Random *rndNumber = new Random(tmeNow.Millisecond);
String *strNumber = rndNumber->Next(100000, 999999).ToString();
// Display the new number in the Part # text box
this->txtItemNumber->Text = strNumber;
// Disable the Create button to indicate that the item is not ready
this->btnCreate->Enabled = false;
}
|
System::Void btnNewCategory_Click(System::Object * sender, System::EventArgs * e)
{
Categories *frmCat = new Categories;
frmCat->ShowDialog();
XmlTextReader *rdrMusicStore = 0;
try {
String *strFilename = S"Categories.xml";
if( File::Exists(strFilename) )
{
this->cboCategories->Items->Clear();
rdrMusicStore = new XmlTextReader(strFilename);
// Scan the XML file
while (rdrMusicStore->Read())
{
// every time you find an element, find out what type it is
// If you find a category, put it in the Categories list box
if( XmlNodeType::Element && rdrMusicStore->Name->Equals(S"Category") )
{
String *strNew = rdrMusicStore->ReadElementString(S"Category");
if( !this->cboCategories->Items->Contains(strNew) )
this->cboCategories->Items->Add(strNew);
}
}
}
}
catch(XmlException *)
{
MessageBox::Show(S"Invalid XML file");
}
__finally
{
if( rdrMusicStore != 0 )
rdrMusicStore->Close();
}
}
|
System::Void btnNewType_Click(System::Object * sender, System::EventArgs * e)
{
ItemTypes *frmTypes = new ItemTypes;
frmTypes->ShowDialog();
XmlTextReader *rdrMusicStore = 0;
try {
String *strFilename = S"ItemTypes.xml";
if( File::Exists(strFilename) )
{
rdrMusicStore = new XmlTextReader(strFilename);
while (rdrMusicStore->Read())
{
if( XmlNodeType::Element && rdrMusicStore->Name->Equals(S"ItemType") )
{
String *strNewType = rdrMusicStore->ReadElementString(S"ItemType");
if( !this->cboItemTypes->Items->Contains(strNewType) )
this->cboItemTypes->Items->Add(strNewType);
}
}
}
}
catch(XmlException *)
{
MessageBox::Show(S"Invalid XML file");
}
__finally
{
if( rdrMusicStore != 0 )
rdrMusicStore->Close();
}
}
|
System::Void txtItemName_TextChanged(System::Object * sender, System::EventArgs * e)
{
if( this->txtItemName->Text->Equals(S"") )
this->btnCreate->Enabled = false;
else
this->btnCreate->Enabled = true;
}
|
System::Void txtUnitPrice_TextChanged(System::Object * sender, System::EventArgs * e)
{
if( this->txtUnitPrice->Text->Equals(S"") )
this->btnCreate->Enabled = false;
else
this->btnCreate->Enabled = true;
}
|
System::Void txtItemNumber_TextChanged(System::Object * sender, System::EventArgs * e)
{
if( this->txtItemNumber->Text->Equals(S"") )
this->btnCreate->Enabled = false;
else
this->btnCreate->Enabled = true;
}
|
System::Void btnCreate_Click(System::Object * sender, System::EventArgs * e)
{
// Get a reference to the Data Center because
// that's where the DataSet object resides
DataCenter *frmData = new DataCenter;
// This is the XML file that will holds the general inventory
// of the current items in the store
String *strAvailableItems = S"Inventory.xml";
// If the file exists already, open it
if( File::Exists(strAvailableItems) )
frmData->dsMusicStore->ReadXml(strAvailableItems);
// Create a new record for the AvailableItems table
DataRow *rowNewItem = frmData->dsMusicStore->Tables->Item[S"AvailableItems"]->NewRow();
rowNewItem->Item[S"ItemNumber"] = this->txtItemNumber->Text;
rowNewItem->Item[S"Category"] = this->cboCategories->Text;
rowNewItem->Item[S"ItemType"] = this->cboItemTypes->Text;
rowNewItem->Item[S"ItemName"] = this->txtItemName->Text;
rowNewItem->Item[S"UnitPrice"] = this->txtUnitPrice->Text;
// Add the new record to the AvailableItems table
frmData->dsMusicStore->Tables->Item[S"AvailableItems"]->Rows->Add(rowNewItem);
// Update the XML file
frmData->dsMusicStore->WriteXml(strAvailableItems);
// Reset the controls in case the user wants to add another record
this->cboCategories->SelectedIndex = -1;
this->cboItemTypes->SelectedIndex = -1;
this->txtItemName->Text = S"";
this->txtUnitPrice->Text = S"0.00";
// We will generate a random number for the store item
DateTime tmeNow = DateTime::Now;
Random *rndNumber = new Random(tmeNow.Millisecond);
String *strNumber = rndNumber->Next(100000, 999999).ToString();
// Display the new number in the Part # text box
this->txtItemNumber->Text = strNumber;
// Disable the OK button to indicate that the item is not ready
this->btnCreate->Enabled = false;
}
|
|
|||||||||
![]() |
|
||||||||||
![]() |
| Category | Item Type | Item Name | Unit Price |
| Electric Guitar | Solid Body | Gibson Les Paul Standard Electric Guitar | 1950.00 |
| Bass | 6-String | Ibanez SR506 6-String Electric Bass | 595.50 |
| Electric Guitar | Hollow Body | Oscar Schmidt OE40 Hollow Body Electric Guitar | 205.95 |
| Acoustic Guitar | Left-Handed | Yamaha Left-Handed FG413SL Acoustic Guitar | 295.95 |
| Cables | Instrument Cable | Monster Cable S-100 Straight Instrument Cable | 12.95 |
| Bass | Combo Amps | Behringer BX1200 Ultrabass Amplifier (120 Watts, 2-Channel) | 150.00 |
| Keyboard | Synthesizers | Korg Triton Le 61-Key Workstation Synth | 895.95 |
| Stands | Guitar Stand | String Swing Metal Guitar Wall Hanger | 9.95 |
| Electric Guitar | Solid Body | Epiphone LP-100 Electric Guitar | 275.95 |
| Keyboard | Digital Piano | Yamaha YDP223 88-Key Graded Hammer Piano With Bench | 1490.00 |
| Cables | Guitar Cable | Spectraflex Guitar Cable | 42.25 |
| Electric Guitar | Solid Body | Gibson Les Paul Classic Electric Guitar | 1625.95 |
| Stands | Guitar Stand | Locking Tubular Guitar Stand | 4.95 |
| Electric Guitar | Solid Body | ESP LTD Viper 400 Electric Guitar | 585.50 |
| Acoustic Guitar | 12-String | Washburn J28S12DL Cumberland 12-String Guitar | 650.75 |
| Electric Guitar | Hollow Body | Ibanez Artcore AF75 Electric Guitar | 315.95 |
| Keyboard | Synthesizers | Korg Triton Extreme 61-Key Synth Workstation | 1895.00 |
| Electric Guitar | Solid Body | Epiphone Les Paul Standard | 525.95 |
| Stands | Guitar Stand | Guitar Folding Stand | 12.95 |
| Electric Guitar | Hollow Body | Gibson ES-335 Reissue | 1850.00 |
| Acoustic Guitar | 12-String | Martin DM12 | 850.00 |
| Stands | Guitar Stand | Metal Guitar Wall Hanger | 9.95 |
| Acoustic Guitar | Left Handed | Yamaha FG413SL | 295.95 |
| Electric Guitar | Solid Body | Gibson Faded SG Special | 625.95 |
| Bass | 4-String | Ibanez SR500 | 525.95 |
| Electric Guitar | Hollow Body | Oscar Schmidt OE40 | 225.95 |
| Electric Guitar | Left Handed | Schecher C-1 | 450.95 |
| Cases | Cases | Les Paul Hardshell Case | 39.95 |
| Cables | Instrument Cable | Hosa Dual Instrument Cable | 7.25 |
#pragma once
#include "DataCenter.h"
#include "NewStoreItem.h"
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::Xml;
namespace MusicStore2a
{
. . . No Change
Void PurchaseOrder_Load(System::Object * sender, System::EventArgs * e)
{
// Get a reference to the object that holds the DataSet
DataCenter *frmData = new DataCenter;
// Identify the file that holds the categories
String *strCategories = S"Categories.xml";
// If that file exists, then open it
if( File::Exists(strCategories) )
frmData->dsMusicStore->ReadXml(strCategories);
// Just in case, empty the Categories list box
this->lbxCategories->Items->Clear();
DataRow *row = 0;
// Scan the whole file to locate each category and retrieve it
for(int i = 0; i < frmData->tblCategories->Rows->Count; i++)
{
row = frmData->tblCategories->Rows->Item[i];
this->lbxCategories->Items->Add(dynamic_cast<String *>(row->Item[S"Category"]));
}
}
}
|
System::Void lbxCategories_SelectedIndexChanged(System::Object * sender, System::EventArgs * e)
{
// Get a reference to the object that holds the DataSet
DataCenter *frmData = new DataCenter;
// Identify the file that holds the items
String *strAvailableItems = S"Inventory.xml";
// Identify the category that the user selected
String *strSelectedCategory = this->lbxCategories->Text;
// If that file exists, then open it
if( File::Exists(strAvailableItems) )
frmData->dsMusicStore->ReadXml(strAvailableItems);
// Empty the Item Types list box
this->lbxItemTypes->Items->Clear();
// Also empty the Available Items list box
this->lbxAvailableItems->Items->Clear();
DataRow *row = 0;
// Scan the whole table to locate each record
for(int i = 0; i < frmData->tblAvailableItems->Rows->Count; i++)
{
// Get a reference to the current record
row = frmData->tblAvailableItems->Rows->Item[i];
// Get the name of the category of the current record
String *strCurrentCategory = dynamic_cast<String *>(row->Item[S"ItemCategory"]);
// If the current category matches the one the user selected...
if( strCurrentCategory->Equals(strSelectedCategory) )
{
// ... then get the corresponding item type
String *strType = dynamic_cast<String *>(row->Item[S"ItemType"]);
// Find out if the Item Types list box already contains the item type
// If it doesn't, then put it in the Item Types list box
if( !this->lbxItemTypes->Items->Contains(strType) )
this->lbxItemTypes->Items->Add(strType);
}
}
}
|
System::Void lbxItemTypes_SelectedIndexChanged(System::Object * sender, System::EventArgs * e)
{
// Get a reference to the object that holds the DataSet
DataCenter *frmData = new DataCenter;
// Identify the file that holds the items
String *strAvailableItems = S"Inventory.xml";
// Identify the category that the user selected
String *strSelectedCategory = this->lbxCategories->Text;
String *strSelectedType = this->lbxItemTypes->Text;
// If file exists, then open it
if( File::Exists(strAvailableItems) )
frmData->dsMusicStore->ReadXml(strAvailableItems);
// Empty the Available Items list box
this->lbxAvailableItems->Items->Clear();
DataRow *row = 0;
// Scan the whole table to locate each record
for(int i = 0; i < frmData->tblAvailableItems->Rows->Count; i++)
{
// Get a reference to the current record
row = frmData->tblAvailableItems->Rows->Item[i];
// Get the name of the category of the current record
String *strCurrentCategory = dynamic_cast<String *>(row->Item[S"ItemCategory"]);
// Get the item type of the current record
String *strCurrentType = dynamic_cast<String *>(row->Item[S"ItemType"]);
// If the current category matches the one the user selected
// and the current item type matches the type the user selected ...
if( strCurrentCategory->Equals(strSelectedCategory) &&
strCurrentType->Equals(strSelectedType) )
{
// ... then get the corresponding item name
this->lbxAvailableItems->Items->Add(dynamic_cast<String *>(row->Item[S"ItemName"]));
}
}
}
|
System::Void lbxAvailableItems_DoubleClick(System::Object * sender, System::EventArgs * e)
{
// Get a reference to the object that holds the DataSet
DataCenter *frmData = new DataCenter;
// Identify the file that holds the items
String *strAvailableItems = S"Inventory.xml";
// Identify the item that the user selected
String *strSelectedCategory = this->lbxCategories->Text;
String *strSelectedType = this->lbxItemTypes->Text;
String *strSelectedName = this->lbxAvailableItems->Text;
// If file exists, then open it
if( File::Exists(strAvailableItems) )
frmData->dsMusicStore->ReadXml(strAvailableItems);
DataRow *row = 0;
// Scan the whole table to locate each record
for(int i = 0; i < frmData->tblAvailableItems->Rows->Count; i++)
{
// Get a reference to the current record
row = frmData->tblAvailableItems->Rows->Item[i];
// Get the name of the category of the current record
String *strCurrentCategory = dynamic_cast<String *>(row->Item[S"ItemCategory"]);
// Get the item type of the current record
String *strCurrentType = dynamic_cast<String *>(row->Item[S"ItemType"]);
// Get the name of the current item
String *strCurrentName = dynamic_cast<String *>(row->Item[S"ItemName"]);
// Get the item number of the current item
String *strCurrentNumber = dynamic_cast<String *>(row->Item[S"ItemNumber"]);
// Get the unit price of the current item
String *strCurrentPrice = dynamic_cast<String *>(row->Item[S"UnitPrice"]);
// If the current parts match the ones the user selected ...
if( strCurrentCategory->Equals(strSelectedCategory) &&
strCurrentType->Equals(strSelectedType) &&
strCurrentName->Equals(strSelectedName) )
{
// ... then consider the corresponding item
if( this->txtItemNumber1->Text->Equals(S"") )
{
this->txtItemNumber1->Text = strCurrentNumber;
this->txtItemName1->Text = strCurrentName;
this->txtUnitPrice1->Text = strCurrentPrice;
this->txtQuantity1->Text = S"1";
this->txtSubTotal1->Text = strCurrentPrice;
}
else if( this->txtItemNumber2->Text->Equals(S"") )
{
this->txtItemNumber2->Text = strCurrentNumber;
this->txtItemName2->Text = strCurrentName;
this->txtUnitPrice2->Text = strCurrentPrice;
this->txtQuantity2->Text = S"1";
this->txtSubTotal2->Text = strCurrentPrice;
}
else if( this->txtItemNumber3->Text->Equals(S"") )
{
this->txtItemNumber3->Text = strCurrentNumber;
this->txtItemName3->Text = strCurrentName;
this->txtUnitPrice3->Text = strCurrentPrice;
this->txtQuantity3->Text = S"1";
this->txtSubTotal3->Text = strCurrentPrice;
}
else if( this->txtItemNumber4->Text->Equals(S"") )
{
this->txtItemNumber4->Text = strCurrentNumber;
this->txtItemName4->Text = strCurrentName;
this->txtUnitPrice4->Text = strCurrentPrice;
this->txtQuantity4->Text = S"1";
this->txtSubTotal4->Text = strCurrentPrice;
}
else if( this->txtItemNumber5->Text->Equals(S"") )
{
this->txtItemNumber5->Text = strCurrentNumber;
this->txtItemName5->Text = strCurrentName;
this->txtUnitPrice5->Text = strCurrentPrice;
this->txtQuantity5->Text = S"1";
this->txtSubTotal5->Text = strCurrentPrice;
}
else // if( this->txtItemNumber6->Text->Equals(S"") )
{
this->txtItemNumber6->Text = strCurrentNumber;
this->txtItemName6->Text = strCurrentName;
this->txtUnitPrice6->Text = strCurrentPrice;
this->txtQuantity6->Text = S"1";
this->txtSubTotal6->Text = strCurrentPrice;
}
}
}
}
|
|
|
||
| Home | Copyright © 2005-2010 FunctionX, Inc. | |
|
|
||