|
File-Based Applications |
|
The Files of a File-Based Application |
|
|
As its name indicates, a file-base application uses one or
more files to hold its information. If you decide to create the application
using the C# language, you can take advantage of the .NET Framework rich library
and its support for file processing.
|
In the .NET Framework, file processing is primarily
supported through the System::IO namespace that is filled with various classes to deal with files and directories
(folders). The most fundamental class of the System::IO namespace and used
to perform file processing is called File. The abstract and sealed File
class contains all necessary methods used to create a file, check the existence
of a file, write information to a file, read information from a file, or
manipulate the system attributes of a file.
Another one of the fundamental file processing classes is
called Stream. This is mainly an abstract class that lays a foundation
for other stream-oriented classes. One of the classes that derives from Stream
is called FileStream.
To create a new file, you can use the File
class, call one of the versions of its Create() method that
takes an argument as the name of, or the path to, the file and returns a FileStream
object.
Besides File, you can use the StreamWriter
class to create a file. To do this, declare a variable of type StreamWriter
and initialize it using one of its constructors.
One of the most routine operations performed on a class
consists of writing information to it. And one of the most useful classes in
this domain is called StreamWriter. The StreamWriter class is
derived from the TextWriter class. To create a file using the StreamWriter
class, you can declare a StreamWriter variable and initialize it using
one of its constructors. After creating the file, you can write information to
it by calling the Write() or the WriteLine() method. Always make sure you close the stream after using it. Also
make sure you use exception handling in your code.
Here is an example:
#pragma once
namespace FileBasedApplication {
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;
. . . No Change
#pragma region Windows Form Designer generated code
. . . No Change
#pragma endregion
private: System::Void txtLastName_Leave(System::Object^ sender,
System::EventArgs^ e)
{
String ^ strInitials = txtFirstName->Text->Substring(0, 1) +
txtLastName->Text->Substring(0, 1);
txtSave->Text = strInitials;
}
private: System::Void btnSave_Click(System::Object^ sender, System::EventArgs^ e)
{
StreamWriter ^ stmWrite = gcnew StreamWriter(txtSave->Text);
stmWrite->WriteLine(txtFirstName->Text);
stmWrite->WriteLine(txtLastName->Text);
stmWrite->WriteLine(dtpDateHired->Value);
stmWrite->WriteLine(cbxGenders->Text);
stmWrite->WriteLine(txtHourlySalary->Text);
stmWrite->Close();
txtFirstName->Text = L"";
txtLastName->Text = L"";
dtpDateHired->Value = DateTime::Today;
cbxGenders->Text = L"Unknown";
txtHourlySalary->Text = L"0.00";
txtSave->Text = L"";
txtOpen->Text = L"";
}
};
}
Besides StreamWriter, to create a file and write
information to it, you can use the BinaryWriter class. You start by
declaring a BinaryWriter variable and initialize it using one of its
constructors, passing a Stream-based object.
Practical
Learning: Writing to a File |
|
- Click the unit price text box that corresponds to the shirts
- In the Properties window, click the Events button and double-click Leave
- Implement the event as follows:
void SaveCleaningOrder()
{
// We will store our files in the following folder
String ^ strDirectory = L"C:\\Georgetown Cleaning Services\\Receipts";
DirectoryInfo ^ dirInfo = Directory::CreateDirectory(strDirectory);
// Get the list of files, if any, from our directory
array<FileInfo ^> ^ fleList = dirInfo->GetFiles();
// If this is a new cleaning order,
// get ready to create a name for the file
if (IsNewCleaningOrder == 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
Filename = strDirectory + L"\\" + iFilename.ToString()+ L".gcs";
txtReceiptNumber->Text = iFilename.ToString();
IsNewCleaningOrder = false;
} // If a cleaning order was already opened, we will simply update it
else
Filename = L"C:\\Georgetown Cleaning Services\\Receipts\\" +
txtReceiptNumber->Text + L".gcs";
StreamWriter ^ stmGCS = gcnew StreamWriter(Filename);
try
{
stmGCS->WriteLine(txtCustomerName->Text);
stmGCS->WriteLine(txtCustomerPhone->Text);
stmGCS->WriteLine(dtpDateLeft->Value.ToString(L"D"));
stmGCS->WriteLine(dtpTimeLeft->Value.ToString(L"t"));
stmGCS->WriteLine(dtpDateExpected->Value.ToString(L"D"));
stmGCS->WriteLine(dtpTimeExpected->Value.ToString(L"t"));
stmGCS->WriteLine(cbxStatus->Text);
stmGCS->WriteLine(dtpDatePickedUp->Value.ToString(L"D"));
stmGCS->WriteLine(dtpTimePickedUp->Value.ToString(L"t"));
stmGCS->WriteLine(txtUnitPriceShirts->Text);
stmGCS->WriteLine(txtQuantityShirts->Text);
stmGCS->WriteLine(txtSubTotalShirts->Text);
stmGCS->WriteLine(txtUnitPricePants->Text);
stmGCS->WriteLine(txtQuantityPants->Text);
stmGCS->WriteLine(txtSubTotalPants->Text);
stmGCS->WriteLine(cbxItem1->Text);
stmGCS->WriteLine(txtUnitPriceItem1->Text);
stmGCS->WriteLine(txtQuantityItem1->Text);
stmGCS->WriteLine(txtSubTotalItem1->Text);
stmGCS->WriteLine(cbxItem2->Text);
stmGCS->WriteLine(txtUnitPriceItem2->Text);
stmGCS->WriteLine(txtQuantityItem2->Text);
stmGCS->WriteLine(txtSubTotalItem2->Text);
stmGCS->WriteLine(cbxItem3->Text);
stmGCS->WriteLine(txtUnitPriceItem3->Text);
stmGCS->WriteLine(txtQuantityItem3->Text);
stmGCS->WriteLine(txtSubTotalItem3->Text);
stmGCS->WriteLine(cbxItem4->Text);
stmGCS->WriteLine(txtUnitPriceItem4->Text);
stmGCS->WriteLine(txtQuantityItem4->Text);
stmGCS->WriteLine(txtSubTotalItem4->Text);
stmGCS->WriteLine(txtCleaningTotal->Text);
stmGCS->WriteLine(txtTaxRate->Text);
stmGCS->WriteLine(txtTaxAmount->Text);
stmGCS->WriteLine(txtNetPrice->Text);
}
finally
{
stmGCS->Close();
}
}
System::Void txtQuantityShirts_Leave(System::Object^ sender,
System::EventArgs^ e)
{
double unitPriceShirts = 0.00, unitPricePants = 0.00,
unitPriceItem1 = 0.00, unitPriceItem2 = 0.00,
unitPriceItem3 = 0.00, unitPriceItem4 = 0.00;
double subTotalShirts = 0.00, subTotalPants = 0.00,
subTotalItem1 = 0.00, subTotalItem2 = 0.00,
subTotalItem3 = 0.00, subTotalItem4 = 0.00;
int qtyShirts = 1, qtyPants = 1, qtyItem1 = 1,
qtyItem2 = 1, qtyItem3 = 1, qtyItem4 = 4;
double cleaningTotal = 0.00, taxRate = 0.00,
taxAmount = 0.00, netPrice = 0.00;
// Retrieve the unit price of this item
// Just in case the user types an invalid value,
// we are using a try...catch
try
{
unitPriceShirts = double::Parse(this->txtUnitPriceShirts->Text);
}
catch(FormatException ^)
{
MessageBox::Show(L"The value you entered for the price of "
L"shirts is not valid"
L"\nPlease try again");
return;
}
// Retrieve the number of this item
// Just in case the user types an invalid value,
// we are using a try...catch
try
{
qtyShirts = int::Parse(this->txtQuantityShirts->Text);
}
catch(FormatException ^)
{
MessageBox::Show(L"The value you entered for the number of "
L"shirts is not valid"
L"\nPlease try again");
return;
}
try
{
unitPricePants = double::Parse(this->txtUnitPricePants->Text);
}
catch(FormatException ^)
{
MessageBox::Show(L"The value you entered for the price of "
L"pants is not valid"
L"\nPlease try again");
return;
}
try
{
qtyPants = int::Parse(this->txtQuantityPants->Text);
}
catch(FormatException ^)
{
MessageBox::Show(L"The value you entered for the number of "
L"pants is not valid"
L"\nPlease try again");
return;
}
if( (cbxItem1->Text == L"None") ||
(cbxItem1->Text == L"") )
{
qtyItem1 = 0;
unitPriceItem1 = 0.00;
}
else
{
try
{
unitPriceItem1 = double::Parse(this->txtUnitPriceItem1->Text);
}
catch(FormatException ^)
{
MessageBox::Show(L"The value you entered for the price is not valid"
L"\nPlease try again");
return;
}
try
{
qtyItem1 = int::Parse(this->txtQuantityItem1->Text);
}
catch(FormatException ^)
{
MessageBox::Show(L"The value you entered is not valid"
L"\nPlease try again");
return;
}
}
if( (cbxItem2->Text == L"None") ||
(cbxItem2->Text == L"") )
{
qtyItem2 = 0;
unitPriceItem2 = 0.00;
}
else
{
try
{
unitPriceItem2 = double::Parse(this->txtUnitPriceItem2->Text);
}
catch(FormatException ^)
{
MessageBox::Show(L"The value you entered for "
L"the price is not valid"
L"\nPlease try again");
return;
}
try
{
qtyItem2 = int::Parse(this->txtQuantityItem2->Text);
}
catch(FormatException ^)
{
MessageBox::Show(L"The value you entered is not valid"
L"\nPlease try again");
return;
}
}
if( (cbxItem3->Text == L"None") ||
(cbxItem3->Text == L"") )
{
qtyItem3 = 0;
unitPriceItem3 = 0.00;
}
else
{
try
{
unitPriceItem3 = double::Parse(this->txtUnitPriceItem3->Text);
}
catch(FormatException ^)
{
MessageBox::Show(L"The value you entered for the "
L"price is not valid"
L"\nPlease try again");
return;
}
try
{
qtyItem3 = int::Parse(this->txtQuantityItem3->Text);
}
catch(FormatException ^)
{
MessageBox::Show(L"The value you entered is not valid"
L"\nPlease try again");
return;
}
}
if ((cbxItem4->Text == L"None") || (cbxItem4->Text == L""))
{
qtyItem4 = 0;
unitPriceItem4 = 0.00;
}
else
{
try
{
unitPriceItem4 = double::Parse(this->txtUnitPriceItem4->Text);
}
catch(FormatException ^)
{
MessageBox::Show(L"The value you entered for the price is not valid"
L"\nPlease try again");
return;
}
try
{
qtyItem4 = int::Parse(this->txtQuantityItem4->Text);
}
catch(FormatException ^)
{
MessageBox::Show(L"The value you entered is not valid"
L"\nPlease try again");
return;
}
}
// Calculate the sub-total for this item
subTotalShirts = qtyShirts * unitPriceShirts;
subTotalPants = qtyPants * unitPricePants;
subTotalItem1 = qtyItem1 * unitPriceItem1;
subTotalItem2 = qtyItem2 * unitPriceItem2;
subTotalItem3 = qtyItem3 * unitPriceItem3;
subTotalItem4 = qtyItem4 * unitPriceItem4;
// Calculate the total based on sub-totals
cleaningTotal = subTotalShirts + subTotalPants + subTotalItem1 +
subTotalItem2 + subTotalItem3 + subTotalItem4;
taxRate = double::Parse(this->txtTaxRate->Text);
// Calculate the amount owed for the taxes
taxAmount = cleaningTotal * taxRate / 100;
// Add the tax amount to the total order
netPrice = cleaningTotal + taxAmount;
// Display the sub-total in the corresponding text box
txtSubTotalShirts->Text = subTotalShirts.ToString(L"F");
txtSubTotalPants->Text = subTotalPants.ToString(L"F");
txtSubTotalItem1->Text = subTotalItem1.ToString(L"F");
txtSubTotalItem2->Text = subTotalItem2.ToString(L"F");
txtSubTotalItem3->Text = subTotalItem3.ToString(L"F");
txtSubTotalItem4->Text = subTotalItem4.ToString(L"F");
txtCleaningTotal->Text = cleaningTotal.ToString(L"F");
txtTaxAmount->Text = taxAmount.ToString(L"F");
txtNetPrice->Text = netPrice.ToString(L"F");
SaveCleaningOrder();
}
|
- Return to the form, click File and double-click Save
- Implement the event as follows:
System::Void mnuFileSave_Click(System::Object^ sender, System::EventArgs^ e)
{
SaveCleaningOrder();
}
|
- Return to the form
- Click the unit price text box that corresponds to the pants
- Press and hold Shift
- Click the unit price text boxes for item 1, item 2, item 3, and item 4
- Click each text box under the Qty label
- Click the Tax Rate text box
- Release Shift
- In the Events section of the Properties window, click Leave, click the
arrow of its combo box and select txtUnitPriceShirts_Leave
- Execute the application
- Create a cleaning order
- Click New and create a few more cleaning orders
- Close the form and return to your programming environment
|
|