|
Microsoft Visual C# File-Based Applications:
Georgetown Dry Cleaning Services |
|
|
A computer database can be created using almost any
application that can be used to store text. Because databases have become a
valuable means of holding company information, specialized software products
have been developed to make it possible to store large and complex pieces of
information.
|
A file-based database (also called a flat file database)
is an application that stores one or various lists of information in
regular, traditional text-based files.
Creating a File-Based Application
|
|
To create a file-based application, you can use a simple
or complex text editor such as Notepad. The main action from you is to
create the list(s) and save it(them) as text files using either the txt or
any extension of your choice. After creating a list, when necessary, you can
open it to access and optionally change the values. After making the
changes, you can save the file. In the same way, you can print the values
and do any type of file-related operation that you judge necessary.
One of the disadvantages of using a text editor to
create a database is that, if you decide to distribute it, either your users
should know as much as necessary about the file (its location and its
content, just to name a few) you must provide a mechanical means of
accessing the file(s). To make your product more professional and user
friendly, you can create a graphical application that the user would use to
access the values in the database. With this approach, you can create an
attractive graphical user interface (GUI) object that display a
functionality the user is familiar with. Using such an aesthetic interface,
you can provide the means of adding, editing, deleting, or changing the
values of the database.
To create a file-based application, you can use the C#
language or the Microsoft Visual C# programming environment that, in
combination with the .NET Framework, provides all the tools you would need.
Using Windows Controls and Accessories
|
|
To create an aesthetically user-friendly application,
you can use the various Windows controls that are implemented in the .NET
Framework. The controls are varied and are meant to accomplish different
roles:
- The form is the most fundamental control. As a container, in fact
the main container, it is the primary object that holds the other
controls of an application
- Based on its fundamental role in an application, a form can be
equipped with functional accessories placed on its frame and intended to
assist with file or print operations. These accessories are the menu(s),
the toolbar(s), and the status bar
- A dialog box is a special type of form you create to perform the
same actions as a form but it does not use the accessories and it may
show a different type of border
- On top of the form or the dialog box, there are controls, referred
to as containers, that can be used to carry or hold other controls.
These are the property sheet, the group box, or the panel
- Text-based controls are used to receive or display text. These are
the label, the text box, the masked text box, and the link label
- Some text-based controls can display enhanced or formatted text
beyond the functionality of the traditional text box. Besides the
formatting and the characteristics of their paragraph, they may also
display pictures. These controls are the rich text box and the web
browser
- Button-based controls allow the user to perform an action when
clicked. These controls are the command button, the radio button, and
the check box
- List-based controls display a list of items to the user. This type
includes the list box, the combo box, the tree view, the list view, and
the domain up/down
- Date and time-based controls are specialized to handle date and time
values. The controls in this category are the calendar and the date/time
picker
- There are other controls used to show a value (the numeric up-down
control) or a progress (the progress bar), etc
Practical
Learning: Introducing File-Based Applications
|
|
- Start Microsoft Visual Studio
- Create a Windows Application named GeorgetownDryCleaningServices1
- In the Solution Explorer, right-click Form1.cs and click Rename
- Type Central.cs and press Enter
- From the Menus & Toolbars section of the Toolbox, click MenuStrip
and click the form
- While the menu strip is still selected, in the Properties window,
click (Name) and type mnuMain
- Under the Properties window, click Insert Standard Items
- On the form, click Help and press Delete
- Click Tools and press Delete
- Click Edit and press Delete
- Click File, click Save As and press Delete
- Using the Properties window, change the names of the menu items as
follows:
Text |
New Name |
&File |
mnuFile |
&New |
mnuFileNew |
&Open |
mnuFileOpen |
&Save |
mnuFileSave |
&Print |
mnuFilePrint |
Print Pre&view |
mnuFilePrintPreview |
- Design the form as follows:
|
Control |
Name |
Text |
Additional Properties |
GroupBox |
|
|
Order Identification |
|
Label |
|
|
&Receipt #: |
|
TextBox |
|
txtReceiptNumber |
1000 |
TextAlign: Right |
Label |
|
|
Customer Name: |
|
TextBox |
|
txtCustomerName |
|
|
Label |
|
|
Customer Phone: |
|
TextBox |
|
txtCustomerPhone |
|
|
Label |
|
|
Date Left: |
|
DateTimePicker |
|
dtpDateLeft |
|
|
Label |
|
|
Time Left: |
|
DateTimePicker |
|
dtpTimeLeft |
|
Format: Time |
Label |
|
|
Date Expected: |
|
DateTimePicker |
|
dtpDateExpected |
|
|
Label |
|
|
Time Expected: |
|
DateTimePicker |
|
dtpTimeExpected |
|
Format: Time |
Label |
|
|
Order &Status: |
|
ComboBox |
|
cbxOrderStatus |
|
|
Label |
|
|
D&ate Picked Up: |
|
DateTimePicker |
|
dtpDatePickedUp |
|
|
Label |
|
|
Time Pic&kep Up: |
|
DateTimePicker |
|
dtpTimePickedUp |
|
|
GroupBox |
|
|
Order Processing |
|
Label |
|
|
Item Type |
|
Label |
|
|
Unit Price |
|
Label |
|
|
Qty |
|
Label |
|
|
Sub Total |
|
Label |
|
|
Shirts |
|
TextBox |
|
txtShirtsUnitPrice |
1.25 |
TextAlign: Right |
TextBox |
|
txtShirtsQuantity |
0 |
TextAlign: Right |
TextBox |
|
txtShirtsSubTotal |
0.00 |
TextAlign: Right |
Label |
|
|
Pants |
|
TextBox |
|
txtPantsUnitPrice |
1.95 |
TextAlign: Right |
TextBox |
|
txtPantsQuantity |
|
TextAlign: Right |
TextBox |
|
txtPantsSubTotal |
0.00 |
TextAlign: Right |
ComboBox |
|
cbxItem1 |
None |
Items: None Women Suit Dress
Regular Skirt Skirt With Hook Men's Suit 2Pc
Men's Suit 3Pc Sweaters Silk Shirt Tie Coat
Jacket Swede |
TextBox |
|
txtItem1UnitPrice |
0.00 |
TextAlign: Right |
TextBox |
|
txtItem1Quantity |
0 |
TextAlign: Right |
TextBox |
|
txtItem1SubTotal |
0.00 |
TextAlign: Right |
ComboBox |
|
cbxItem2 |
None |
Items: None Women Suit Dress
Regular Skirt Skirt With Hook Men's Suit 2Pc
Men's Suit 3Pc Sweaters Silk Shirt Tie Coat
Jacket Swede |
TextBox |
|
txtItem2UnitPrice |
0.00 |
TextAlign: Right |
TextBox |
|
txtItem2Quantity |
0 |
TextAlign: Right |
TextBox |
|
txtItem2SubTotal |
0.00 |
TextAlign: Right |
ComboBox |
|
cbxItem3 |
None |
Items: None Women Suit Dress
Regular Skirt Skirt With Hook Men's Suit 2Pc
Men's Suit 3Pc Sweaters Silk Shirt Tie Coat
Jacket Swede |
TextBox |
|
txtItem3UnitPrice |
0.00 |
TextAlign: Right |
TextBox |
|
txtItem3Quantity |
0 |
TextAlign: Right |
TextBox |
|
txtItem3SubTotal |
0.00 |
TextAlign: Right |
ComboBox |
|
cbxItem4 |
None |
Items: None Women Suit Dress
Regular Skirt Skirt With Hook Men's Suit 2Pc
Men's Suit 3Pc Sweaters Silk Shirt Tie Coat
Jacket Swede |
TextBox |
|
txtItem4UnitPrice |
0.00 |
TextAlign: Right |
TextBox |
|
txtItem4Quantity |
0 |
TextAlign: Right |
TextBox |
|
txtItem4SubTotal |
0.00 |
TextAlign: Right |
GroupBox |
|
|
Order Summary |
|
Label |
|
|
Cleaning Total: |
|
TextBox |
|
txtCleaningTotal |
0.00 |
TextAlign: Right |
Label |
|
|
Tax Rate: |
|
TextBox |
|
txtTaxRate |
7.75 |
TextAlign: Right |
Label |
|
|
% |
|
Label |
|
|
Tax Amount: |
|
TextBox |
|
txtTaxAmount |
0.00 |
TextAlign: Right |
Label |
|
|
Net Total: |
|
TextBox |
|
txtNetPrice |
0.00 |
TextAlign: Right |
|
- Double-click the Time Left control and implement its ValueChanged
event as follows:
private void dtpTimeLeft_ValueChanged(object sender, EventArgs e)
{
var dateLeft = this.dtpDateLeft.Value;
var timeLeft = this.dtpTimeLeft.Value;
var time9AM = new DateTime(timeLeft.Year, timeLeft.Month,
timeLeft.Day, 9, 0, 0);
// If the customer leaves clothes before 9AM...
if (timeLeft <= time9AM)
{
// ... then they should be ready the same day after 5PM
this.dtpDateExpected.Value = dateLeft;
this.dtpTimeExpected.Value = new DateTime(dateLeft.Year,
dateLeft.Month,
dateLeft.Day, 17, 0, 0);
}
else
{
// If the clothes were left after 9AM,
// then they will be available the following business morning at 8AM
// If the following day is Sunday,
// then they will be ready the following Monday
if (dateLeft.DayOfWeek == DayOfWeek.Saturday)
{
dtpDateExpected.Value = dateLeft.AddDays(2.00D);
dtpTimeExpected.Value = new DateTime(dateLeft.Year,
dateLeft.Month,
dateLeft.Day + 2, 8, 0, 0);
}
else
{
dtpDateExpected.Value = new DateTime(dateLeft.Year,
dateLeft.Month,
dateLeft.Day + 1);
dtpTimeExpected.Value = new DateTime(dateLeft.Year,
dateLeft.Month,
dateLeft.Day + 1, 8, 0, 0);
}
}
}
- Return to the form
The Directory of a
Database
|
|
One of the biggest differences between a database and a
regular application is that, traditionally, although not always, all of the
files of a database are located in the same directory. The directory can be
local and accessed only by one computer. The directory can be located in one
computer and accessed by various users on different computers or a
workgroup. The directory can be located on a server that no user directly
uses but that directory's files can be accessed from one or more computers.
Another particularity of a database is that usually you,
the database developer, create and manage the directory or directories used
by the application.
Another difference of a database as compared to a
regular application is that, while using the database, users do not create
files. This means that there is no actual file processing on the part of the
users. For example, the user does not even open the database in the
traditional sense. You, the database developer, provide a means of accessing
the database. Then, the user adds, edits, or deletes values.
Based on the above discussion of directories, when
creating a file-based application, one the first actions you should perform
consists of setting up the directory where the file(s) of your application
would be located. If you already know (and you should know) where and how
the application would be accessed, you can manually create a folder using
Windows Explorer, My Computer, or any appropriate utility. Otherwise, you
can still programmatically create the directory.
The .NET Framework supports the creation and management
of directories through various classes. The main class used to deal with
directories is called Directory. Besides the Directory class,
the .NET Framework provides support for folders through a class named
DirectoryInfo. To use it, declare a variable of type DirectoryInfo
using its constructor to initialize it.
To actually create a directory using the static
Directory class, you can call its CreateDirectory() method that
is overloaded with two versions. Here is an example:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace Exercise
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnDirectory_Click(object sender, EventArgs e)
{
Directory.CreateDirectory(@"E:\Bethesda Car Rental");
}
}
}
To create a folder using the DirectoryInfo class,
call its Create() method that comes in two versions. Here is an
example:
private void btnDirectory_Click(object sender, EventArgs e)
{
DirectoryInfo dirInfo = new DirectoryInfo(@"E:\Bethesda Car Rental");
dirInfo.Create();
}
When you call either the Directory.CreateDirectory()
method or the DirectoryInfo.Create() method, if the directory does
not exist, it would be created. If the directory exists already, nothing
would happen. This implies that the compiler would not attempt to create a
directory if there is already one in the indicated location and you can
safely call any of these methods without the risk of deleting its existing
files, if any.
Before performing any operation on a directory, you
should first make sure it exists. To get this information, you can call the
Directory.Exists() method that returns a Boolean value. This method
takes as argument the path to the directory. Here is an example:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace WinForms4
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnDirectory_Click(object sender, EventArgs e)
{
if (Directory.Exists(@"E:\Bethesda Car Rental"))
MessageBox.Show("The directory exists already");
else
MessageBox.Show("That directory was not yet created");
}
}
}
During the lifetime of your database, at one time, you
may want to change its location, for any reason you judge necessary.
Although this operation is primarily easily supported, it could become
complex in some scenarios. Still, to move a directory and its contents, you
can call the Directory.Move() method. This method takes two
arguments: the source and the destination. After the method has been called,
the directory held by the first argument would be moved, along with its
sub-folders and files, to the path specified by the second argument. To move
a directory using the DirectoryInfo class, you can call its
MoveTo() method.
As opposed to creating a directory, if you don't need it
anymore, you can remove it. To support this, the Directory class is equipped
with the Delete() method that is overloaded with two versions. One of
the versions is used to delete a directory that is currently empty while the
other version is used to delete the directory and its content.
Practical
Learning: Setting up a Directory
|
|
- On the main menu of the form, click File and double-click New
- Implement the event as follows:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace GeorgetownDryCleaningServices1
{
public partial class Central : Form
{
int iFilename;
bool IsNewCleaningOrder;
string Filename;
public Central()
{
InitializeComponent();
}
private void dtpTimeLeft_ValueChanged(object sender, EventArgs e)
{
. . . No Change
}
private void mnuFileNew_Click(object sender, EventArgs e)
{
// We will store our files in the following folder
var strDirectory = @"C:\Georgetown Cleaning Services\Receipts";
var dirInfo = Directory.CreateDirectory(strDirectory);
// Get the list of files, if any, from our directory
var fleList = dirInfo.GetFiles();
// 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
try
{
iFilename = int.Parse(fwe) + 1;
}
catch (FormatException)
{
}
}
// Update our global name of the file
Filename = strDirectory + "\\" + iFilename.ToString() + ".gcs";
txtReceiptNumber.Text = iFilename.ToString();
txtCustomerName.Text = "";
txtCustomerPhone.Text = "";
dtpDateLeft.Value = DateTime.Today;
dtpTimeLeft.Value = DateTime.Today;
dtpDateExpected.Value = DateTime.Today;
dtpTimeExpected.Value = DateTime.Today;
cbxStatus.Text = "Not Yet Ready";
dtpDatePickedUp.Value = DateTime.Today;
dtpTimePickedUp.Value = DateTime.Today;
txtUnitPriceShirts.Text = "1.25";
txtQuantityShirts.Text = "0";
txtSubTotalShirts.Text = "0.00";
txtUnitPricePants.Text = "1.95";
txtQuantityPants.Text = "0";
txtSubTotalPants.Text = "0.00";
cbxItem1.Text = "None";
txtUnitPriceItem1.Text = "0.00";
txtQuantityItem1.Text = "0";
txtSubTotalItem1.Text = "0.00";
cbxItem2.Text = "None";
txtUnitPriceItem2.Text = "0.00";
txtQuantityItem2.Text = "0";
txtSubTotalItem2.Text = "0.00";
cbxItem3.Text = "None";
txtUnitPriceItem3.Text = "0.00";
txtQuantityItem3.Text = "0";
txtSubTotalItem3.Text = "0.00";
cbxItem4.Text = "None";
txtUnitPriceItem4.Text = "0.00";
txtQuantityItem4.Text = "0";
txtSubTotalItem4.Text = "0.00";
txtCleaningTotal.Text = "0.00";
txtTaxRate.Text = "7.75";
txtTaxAmount.Text = "0.00";
txtCleaningTotal.Text = "0.00";
txtCustomerName.Focus();
}
}
}
- Return to the form
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:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace WinForms
{
public partial class Exercise : Form
{
public Exercise()
{
InitializeComponent();
}
private void btnSave_Click(object sender, EventArgs e)
{
StreamWriter stmWrite = new 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 = "";
txtLastName.Text = "";
dtpDateHired.Value = DateTime.Today;
cbxGenders.Text = "Unknown";
txtHourlySalary.Text = "0.00";
txtSave.Text = "";
txtOpen.Text = "";
}
private void txtLastName_Leave(object sender, EventArgs e)
{
string strInitials = txtFirstName.Text.Substring(0, 1) +
txtLastName.Text.Substring(0, 1);
txtSave.Text = strInitials;
}
}
}
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:
internal void SaveCleaningOrder()
{
// We will store our files in the following folder
string strDirectory = @"C:\Georgetown Cleaning Services\Receipts";
DirectoryInfo dirInfo = Directory.CreateDirectory(strDirectory);
// Get the list of files, if any, from our directory
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 + "\\" + iFilename.ToString() + ".gcs";
txtReceiptNumber.Text = iFilename.ToString();
IsNewCleaningOrder = false;
} // If a cleaning order was already opened, we will simply update it
else
Filename = @"C:\Georgetown Cleaning Services\Receipts\" +
txtReceiptNumber.Text + ".gcs";
StreamWriter stmGCS = new StreamWriter(Filename);
try
{
stmGCS.WriteLine(txtCustomerName.Text);
stmGCS.WriteLine(txtCustomerPhone.Text);
stmGCS.WriteLine(dtpDateLeft.Value.ToString("D"));
stmGCS.WriteLine(dtpTimeLeft.Value.ToString("t"));
stmGCS.WriteLine(dtpDateExpected.Value.ToString("D"));
stmGCS.WriteLine(dtpTimeExpected.Value.ToString("t"));
stmGCS.WriteLine(cbxStatus.Text);
stmGCS.WriteLine(dtpDatePickedUp.Value.ToString("D"));
stmGCS.WriteLine(dtpTimePickedUp.Value.ToString("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();
}
}
private void txtUnitPriceShirts_Leave(object sender, EventArgs e)
{
decimal unitPriceShirts = 0.00M, unitPricePants = 0.00M,
unitPriceItem1 = 0.00M, unitPriceItem2 = 0.00M,
unitPriceItem3 = 0.00M, unitPriceItem4 = 0.00M;
decimal subTotalShirts = 0.00M, subTotalPants = 0.00M,
subTotalItem1 = 0.00M, subTotalItem2 = 0.00M,
subTotalItem3 = 0.00M, subTotalItem4 = 0.00M;
int qtyShirts = 1, qtyPants = 1, qtyItem1 = 1,
qtyItem2 = 1, qtyItem3 = 1, qtyItem4 = 4;
decimal cleaningTotal = 0.00M, taxRate = 0.00M,
taxAmount = 0.00M, netPrice = 0.00M;
// Retrieve the unit price of this item
// Just in case the user types an invalid value,
// we are using a try...catch
try
{
unitPriceShirts = decimal.Parse(this.txtUnitPriceShirts.Text);
}
catch (FormatException)
{
MessageBox.Show("The value you entered for the price of " +
"shirts is not valid" +
"\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("The value you entered for the number of " +
"shirts is not valid" +
"\nPlease try again");
return;
}
try
{
unitPricePants = decimal.Parse(this.txtUnitPricePants.Text);
}
catch (FormatException)
{
MessageBox.Show("The value you entered for the price of " +
"pants is not valid" +
"\nPlease try again");
return;
}
try
{
qtyPants = int.Parse(this.txtQuantityPants.Text);
}
catch (FormatException)
{
MessageBox.Show("The value you entered for the number of " +
"pants is not valid" +
"\nPlease try again");
return;
}
if( (cbxItem1.Text == "None") ||
(cbxItem1.Text == "") )
{
qtyItem1 = 0;
unitPriceItem1 = 0.00M;
}
else
{
try
{
unitPriceItem1 = decimal.Parse(this.txtUnitPriceItem1.Text);
}
catch (FormatException)
{
MessageBox.Show("The value you entered for the price is not valid" +
"\nPlease try again");
return;
}
try
{
qtyItem1 = int.Parse(this.txtQuantityItem1.Text);
}
catch (FormatException)
{
MessageBox.Show("The value you entered is not valid" +
"\nPlease try again");
return;
}
}
if( (cbxItem2.Text == "None") ||
(cbxItem2.Text == "") )
{
qtyItem2 = 0;
unitPriceItem2 = 0.00M;
}
else
{
try
{
unitPriceItem2 = decimal.Parse(this.txtUnitPriceItem2.Text);
}
catch (FormatException)
{
MessageBox.Show("The value you entered for " +
"the price is not valid" +
"\nPlease try again");
return;
}
try
{
qtyItem2 = int.Parse(this.txtQuantityItem2.Text);
}
catch (FormatException)
{
MessageBox.Show("The value you entered is not valid" +
"\nPlease try again");
return;
}
}
if( (cbxItem3.Text == "None") ||
(cbxItem3.Text == "") )
{
qtyItem3 = 0;
unitPriceItem3 = 0.00M;
}
else
{
try
{
unitPriceItem3 = decimal.Parse(this.txtUnitPriceItem3.Text);
}
catch (FormatException)
{
MessageBox.Show("The value you entered for the " +
"price is not valid" +
"\nPlease try again");
return;
}
try
{
qtyItem3 = int.Parse(this.txtQuantityItem3.Text);
}
catch (FormatException)
{
MessageBox.Show("The value you entered is not valid" +
"\nPlease try again");
return;
}
}
if ((cbxItem4.Text == "None") || (cbxItem4.Text == ""))
{
qtyItem4 = 0;
unitPriceItem4 = 0.00M;
}
else
{
try
{
unitPriceItem4 = decimal.Parse(this.txtUnitPriceItem4.Text);
}
catch (FormatException)
{
MessageBox.Show("The value you entered for the price is not valid" +
"\nPlease try again");
return;
}
try
{
qtyItem4 = int.Parse(this.txtQuantityItem4.Text);
}
catch (FormatException)
{
MessageBox.Show("The value you entered is not valid" +
"\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 = decimal.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("F");
txtSubTotalPants.Text = subTotalPants.ToString("F");
txtSubTotalItem1.Text = subTotalItem1.ToString("F");
txtSubTotalItem2.Text = subTotalItem2.ToString("F");
txtSubTotalItem3.Text = subTotalItem3.ToString("F");
txtSubTotalItem4.Text = subTotalItem4.ToString("F");
txtCleaningTotal.Text = cleaningTotal.ToString("F");
txtTaxAmount.Text = taxAmount.ToString("F");
txtNetPrice.Text = netPrice.ToString("F");
SaveCleaningOrder();
}
- Return to the form, click File and double-click Save
- Implement the event as follows:
private void mnuFileSave_Click(object sender, 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
Before exploring the contents of a file, you must first
open it. To open a file using the File class, you can call its
Open method that is overloaded with three versions. If the information
in the file is raw text, you can call the OpenText() method. After
opening a file, you can read its content.
To support the ability to read from a file, you can use
the StreamReader class that is derived from the TextReader
class. To use it, declare a variable of type StreamReader and use one
of its constructors to specify the name of, or the path to, the file. To
read information from the file, you can call its Read() or its
ReadLine() method. Here is an example:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace WinForms
{
public partial class Exercise : Form
{
public Exercise()
{
InitializeComponent();
}
private void btnSave_Click(object sender, EventArgs e)
{
StreamWriter stmWrite = new 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 = "";
txtLastName.Text = "";
dtpDateHired.Value = DateTime.Today;
cbxGenders.Text = "Unknown";
txtHourlySalary.Text = "0.00";
txtSave.Text = "";
txtOpen.Text = "";
}
private void txtLastName_Leave(object sender, EventArgs e)
{
string strInitials = txtFirstName.Text.Substring(0, 1) +
txtLastName.Text.Substring(0, 1);
txtSave.Text = strInitials;
}
private void btnOpen_Click(object sender, EventArgs e)
{
StreamReader stmReader = new StreamReader(txtOpen.Text);
txtFirstName.Text = stmReader.ReadLine();
txtLastName.Text = stmReader.ReadLine();
dtpDateHired.Value = DateTime.Parse(stmReader.ReadLine());
cbxGenders.Text = stmReader.ReadLine();
txtHourlySalary.Text = stmReader.ReadLine();
stmReader.Close();
}
private void btnClose_Click(object sender, EventArgs e)
{
Close();
}
}
}
Instead of StreamReader, you can use the
BinaryReader class to read information from a file.
Practical
Learning: Reading From a File
|
|
- On the form, click File and double-click Open
- Implement the event as follows:
private void mnuFileOpen_Click(object sender, EventArgs e)
{
if (txtReceiptNumber.Text == "")
return;
else
{
try
{
IsNewCleaningOrder = false;
Filename =
@"C:\Georgetown Cleaning Services\Receipts\" +
txtReceiptNumber.Text + ".gcs";
StreamReader rdrGCS = new StreamReader(Filename);
try
{
txtCustomerName.Text = rdrGCS.ReadLine();
txtCustomerPhone.Text = rdrGCS.ReadLine();
dtpDateLeft.Value =
DateTime.Parse(rdrGCS.ReadLine());
dtpTimeLeft.Value =
DateTime.Parse(rdrGCS.ReadLine());
dtpDateExpected.Value =
DateTime.Parse(rdrGCS.ReadLine());
dtpTimeExpected.Value =
DateTime.Parse(rdrGCS.ReadLine());
cbxStatus.Text = rdrGCS.ReadLine();
dtpDatePickedUp.Value =
DateTime.Parse(rdrGCS.ReadLine());
dtpTimePickedUp.Value =
DateTime.Parse(rdrGCS.ReadLine());
txtUnitPriceShirts.Text = rdrGCS.ReadLine();
txtQuantityShirts.Text = rdrGCS.ReadLine();
txtSubTotalShirts.Text = rdrGCS.ReadLine();
txtUnitPricePants.Text = rdrGCS.ReadLine();
txtQuantityPants.Text = rdrGCS.ReadLine();
txtSubTotalPants.Text = rdrGCS.ReadLine();
cbxItem1.Text = rdrGCS.ReadLine();
txtUnitPriceItem1.Text = rdrGCS.ReadLine();
txtQuantityItem1.Text = rdrGCS.ReadLine();
txtSubTotalItem1.Text = rdrGCS.ReadLine();
cbxItem2.Text = rdrGCS.ReadLine();
txtUnitPriceItem2.Text = rdrGCS.ReadLine();
txtQuantityItem2.Text = rdrGCS.ReadLine();
txtSubTotalItem2.Text = rdrGCS.ReadLine();
cbxItem3.Text = rdrGCS.ReadLine();
txtUnitPriceItem3.Text = rdrGCS.ReadLine();
txtQuantityItem3.Text = rdrGCS.ReadLine();
txtSubTotalItem3.Text = rdrGCS.ReadLine();
cbxItem4.Text = rdrGCS.ReadLine();
txtUnitPriceItem4.Text = rdrGCS.ReadLine();
txtQuantityItem4.Text = rdrGCS.ReadLine();
txtSubTotalItem4.Text = rdrGCS.ReadLine();
txtCleaningTotal.Text = rdrGCS.ReadLine();
txtTaxRate.Text = rdrGCS.ReadLine();
txtTaxAmount.Text = rdrGCS.ReadLine();
txtNetPrice.Text = rdrGCS.ReadLine();
}
finally
{
rdrGCS.Close();
}
}
catch (FileNotFoundException)
{
MessageBox.Show("There is no cleaning order " +
"with that receipt number");
}
}
}
- Execute the application
- Type 1001 for the receipt number and, on the main menu of the form,
click File -> Open
- Close the form and return to your programming environment
We have mentioned that, on a typical database, the user
is not aware of opening or saving files. In the same way, the user can be
spared with deciding when to save and when not to save data. Whenever
possible, most operations should be performed behind-the-scenes with little
to no intervention from the user. To make this possible, you are in charge
of creating the file(s), receiving data from the user, and then adding that
data to the file.
Practical
Learning: Opening and Saving Data
|
|
- Display the form
- In the combo box on top of the form, select Central and click the
Events button
- Double-click and implement the event as follows:
private void Central_Load(object sender, EventArgs e)
{
mnuFileNew_Click(sender, e);
}
- Return to the form
- On the form, click the Customer Name text box
- In the Events section of the Properties window, double-click Leave
and implement its event as follows:
private void txtCustomerName_Leave(object sender, EventArgs e)
{
if (txtCustomerName.Modified == true)
SaveCleaningOrder();
}
- Return to the form
- On the form, click the Customer Phone text box
- In the Events section of the Properties window, double-click Leave
and implement its event as follows:
private void txtCustomerPhone_Leave(object sender, EventArgs e)
{
if (txtCustomerPhone.Modified == true)
SaveCleaningOrder();
}
- Execute the application and create a few cleaning orders
- Close the form and return to your programming environment
Data input, also referred to as data entry, consists of
entering the values into the application. The user does it mainly using the
keyboard and the mouse. As we reviewed the Windows controls, there are
various types of objects you can use to assist the user. One of the
suggestions you should follow is that you should make the user's job as easy
as you can. Because users of a database are not expected to do any heavy
word processing. This means that typing speed is not among their strongest
points. Instead, when choosing the Windows controls for your application,
you should select the most appropriate one for a particular piece of
information.
Data output consists of retrieving information from a
database. Besides opening the objects, such as the forms, that hold the
information of a database, users also regular want to print. In fact, in
some businesses, the customers require to have a printed copy of their
transaction. Therefore, if you are in the habit of neglecting to configuring
printing in your Windows applications, for a database, you should (strongly)
loose the habit and provide your users with the ability to print the data of
your application.
If you are creating a file-based application, you can
use the various printing classes of the .NET Framework. Unfortunately, there
is no environment inside the Microsoft Visual Studio 2005 that can assist
you to visually design a report. You must manually draw everything.
Practical
Learning: Printing
|
|
- From the Printing section of the Toolbox, click PrintDocument and
click the form
- While the new control is still selected, in the Properties window,
click the Properties button, click (Name), type docPrint and
press Enter
- Under the form, double-click docPrint and implement its event as
follows:
private void docPrint_PrintPage(object sender,
System.Drawing.Printing.PrintPageEventArgs e)
{
e.Graphics.DrawLine(new Pen(Color.Black, 2), 60, 90, 720, 90);
e.Graphics.DrawLine(new Pen(Color.Black, 1), 60, 93, 720, 93);
string strDisplay = "Georgetown Dry Cleaning Services";
System.Drawing.Font fntString = new Font("Times New Roman", 28,
FontStyle.Bold);
e.Graphics.DrawString(strDisplay, fntString,
Brushes.Black, 80, 100);
strDisplay = "Customer Cleaning Order";
fntString = new System.Drawing.Font("Times New Roman", 18,
FontStyle.Bold);
e.Graphics.DrawString(strDisplay, fntString,
Brushes.Black, 220, 150);
e.Graphics.DrawLine(new Pen(Color.Black, 1), 60, 184, 720, 184);
e.Graphics.DrawLine(new Pen(Color.Black, 2), 60, 188, 720, 188);
fntString = new System.Drawing.Font("Times New Roman", 12,
FontStyle.Bold);
e.Graphics.DrawString("", fntString,
Brushes.Black, 80, 200);
fntString = new System.Drawing.Font("Times New Roman", 12,
FontStyle.Bold);
e.Graphics.DrawString("Customer Identification: ", fntString,
Brushes.Black, 100, 220);
fntString = new System.Drawing.Font("Times New Roman", 12,
FontStyle.Regular);
e.Graphics.DrawString(txtCustomerName.Text + " - " +
txtCustomerPhone.Text, fntString,
Brushes.Black, 300, 220); ;
e.Graphics.DrawLine(new Pen(Color.Black, 1), 100, 240, 700, 240);
fntString = new Font("Times New Roman", 12, FontStyle.Bold);
e.Graphics.DrawString("Date Left: ", fntString,
Brushes.Black, 100, 260);
fntString = new Font("Times New Roman", 12, FontStyle.Regular);
e.Graphics.DrawString(dtpDateLeft.Value.ToString("D"), fntString,
Brushes.Black, 300, 260);
e.Graphics.DrawLine(new Pen(Color.Black, 1), 100, 280, 700, 280);
fntString = new Font("Times New Roman", 12, FontStyle.Bold);
e.Graphics.DrawString("Time Left: ", fntString,
Brushes.Black, 500, 260);
fntString = new Font("Times New Roman", 12, FontStyle.Regular);
e.Graphics.DrawString(dtpTimeLeft.Value.ToString("t"), fntString,
Brushes.Black, 620, 260);
fntString = new System.Drawing.Font("Times New Roman",
12, FontStyle.Bold);
e.Graphics.DrawString("Date Expected: ", fntString,
Brushes.Black, 100, 300);
fntString = new Font("Times New Roman", 12, FontStyle.Regular);
e.Graphics.DrawString(dtpDateExpected.Value.ToString("D"),
fntString, Brushes.Black, 300, 300);
fntString = new Font("Times New Roman", 12, FontStyle.Bold);
e.Graphics.DrawString("Time Expected: ", fntString,
Brushes.Black, 500, 300);
fntString = new Font("Times New Roman", 12, FontStyle.Regular);
e.Graphics.DrawString(dtpTimeExpected.Value.ToString("t"),
fntString, Brushes.Black, 620, 300);
e.Graphics.DrawLine(new Pen(Color.Black, 2), 100, 320, 700, 320);
fntString = new Font("Times New Roman", 12, FontStyle.Bold);
e.Graphics.DrawString("Item Type",
fntString, Brushes.Black, 140, 350);
e.Graphics.DrawString("Unit Price",
fntString, Brushes.Black, 300, 350);
e.Graphics.DrawString("Quantity",
fntString, Brushes.Black, 405, 350);
e.Graphics.DrawString("Sub-Total",
fntString, Brushes.Black, 500, 350);
e.Graphics.DrawLine(new Pen(Color.Black, 2), 140, 370, 640, 370);
StringFormat fmtString = new StringFormat();
fmtString.Alignment = StringAlignment.Far;
e.Graphics.DrawString("Shirts",
fntString, Brushes.Black, 150, 380);
fntString = new Font("Times New Roman", 12, FontStyle.Regular);
e.Graphics.DrawString(txtUnitPriceShirts.Text, fntString,
Brushes.Black, 350, 380, fmtString);
e.Graphics.DrawString(txtQuantityShirts.Text, fntString,
Brushes.Black, 440, 380, fmtString);
e.Graphics.DrawString(txtSubTotalShirts.Text, fntString,
Brushes.Black, 550, 380, fmtString);
e.Graphics.DrawLine(new Pen(Color.Black, 1), 140, 400, 640, 400);
fntString = new Font("Times New Roman", 12, FontStyle.Bold);
e.Graphics.DrawString("Pants",
fntString, Brushes.Black, 150, 410);
fntString = new Font("Times New Roman", 12, FontStyle.Regular);
e.Graphics.DrawString(txtUnitPricePants.Text, fntString,
Brushes.Black, 350, 410, fmtString);
e.Graphics.DrawString(txtQuantityPants.Text, fntString,
Brushes.Black, 440, 410, fmtString);
e.Graphics.DrawString(txtSubTotalPants.Text, fntString,
Brushes.Black, 550, 410, fmtString);
e.Graphics.DrawLine(new Pen(Color.Black, 1), 140, 430, 640, 430);
fntString = new Font("Times New Roman", 12, FontStyle.Bold);
e.Graphics.DrawString(cbxItem1.Text,
fntString, Brushes.Black, 150, 440);
fntString = new Font("Times New Roman", 12, FontStyle.Regular);
e.Graphics.DrawString(txtUnitPriceItem1.Text, fntString,
Brushes.Black, 350, 440, fmtString);
e.Graphics.DrawString(txtQuantityItem1.Text, fntString,
Brushes.Black, 440, 440, fmtString);
e.Graphics.DrawString(txtSubTotalItem1.Text, fntString,
Brushes.Black, 550, 440, fmtString);
e.Graphics.DrawLine(new Pen(Color.Black, 1), 140, 460, 640, 460);
fntString = new Font("Times New Roman", 12, FontStyle.Bold);
e.Graphics.DrawString(cbxItem2.Text,
fntString, Brushes.Black, 150, 470);
fntString = new Font("Times New Roman", 12, FontStyle.Regular);
e.Graphics.DrawString(txtUnitPriceItem2.Text, fntString,
Brushes.Black, 350, 470, fmtString);
e.Graphics.DrawString(txtQuantityItem2.Text, fntString,
Brushes.Black, 440, 470, fmtString);
e.Graphics.DrawString(txtSubTotalItem2.Text, fntString,
Brushes.Black, 550, 470, fmtString);
e.Graphics.DrawLine(new Pen(Color.Black, 1), 140, 490, 640, 490);
fntString = new Font("Times New Roman", 12, FontStyle.Bold);
e.Graphics.DrawString(cbxItem3.Text,
fntString, Brushes.Black, 150, 500);
fntString = new Font("Times New Roman", 12, FontStyle.Regular);
e.Graphics.DrawString(txtUnitPriceItem3.Text, fntString,
Brushes.Black, 350, 500, fmtString);
e.Graphics.DrawString(txtQuantityItem3.Text, fntString,
Brushes.Black, 440, 500, fmtString);
e.Graphics.DrawString(txtSubTotalItem3.Text, fntString,
Brushes.Black, 550, 500, fmtString);
e.Graphics.DrawLine(new Pen(Color.Black, 1), 140, 520, 640, 520);
fntString = new Font("Times New Roman", 12, FontStyle.Bold);
e.Graphics.DrawString(cbxItem4.Text,
fntString, Brushes.Black, 150, 530);
fntString = new Font("Times New Roman", 12, FontStyle.Regular);
e.Graphics.DrawString(txtUnitPriceItem4.Text, fntString,
Brushes.Black, 350, 530, fmtString);
e.Graphics.DrawString(txtQuantityItem4.Text, fntString,
Brushes.Black, 440, 530, fmtString);
e.Graphics.DrawString(txtSubTotalItem4.Text, fntString,
Brushes.Black, 550, 530, fmtString);
e.Graphics.DrawLine(new Pen(Color.Black, 2), 140, 550, 640, 550);
fntString = new System.Drawing.Font("Times New Roman", 12,
FontStyle.Bold);
e.Graphics.DrawString("Order Summary", fntString,
Brushes.Black, 260, 600);
e.Graphics.DrawLine(new Pen(Color.Black, 2), 220, 620, 560, 620);
fntString = new System.Drawing.Font("Times New Roman",
10, FontStyle.Bold);
e.Graphics.DrawString("Cleaning Total:", fntString,
Brushes.Black, 260, 630);
fntString = new System.Drawing.Font("Times New Roman",
10, FontStyle.Regular);
e.Graphics.DrawString(txtCleaningTotal.Text, fntString,
Brushes.Black, 440, 630, fmtString);
e.Graphics.DrawLine(new Pen(Color.Black, 1),
220, 650, 520, 650);
fntString = new System.Drawing.Font("Times New Roman",
10, FontStyle.Bold);
e.Graphics.DrawString("Tax Rate:", fntString,
Brushes.Black, 260, 660);
fntString = new System.Drawing.Font("Times New Roman",
10, FontStyle.Regular);
e.Graphics.DrawString(txtTaxRate.Text, fntString,
Brushes.Black, 440, 660, fmtString);
e.Graphics.DrawLine(new Pen(Color.Black, 1),
220, 680, 520, 680);
fntString = new System.Drawing.Font("Times New Roman",
10, FontStyle.Bold);
e.Graphics.DrawString("Tax Amount:", fntString,
Brushes.Black, 260, 690);
fntString = new System.Drawing.Font("Times New Roman",
10, FontStyle.Regular);
e.Graphics.DrawString(txtTaxAmount.Text, fntString,
Brushes.Black, 440, 690, fmtString);
e.Graphics.DrawLine(new Pen(Color.Black, 1),
220, 710, 520, 710);
fntString = new System.Drawing.Font("Times New Roman",
10, FontStyle.Bold);
e.Graphics.DrawString("Net Price:", fntString,
Brushes.Black, 260, 720);
fntString = new System.Drawing.Font("Times New Roman",
10, FontStyle.Regular);
e.Graphics.DrawString(txtNetPrice.Text, fntString,
Brushes.Black, 440, 720, fmtString);
e.Graphics.DrawLine(new Pen(Color.Black, 2),
200, 740, 560, 740);
}
- Return to the form
- From the Printing section of the Toolbox, click PrintDialog and
click the form
- In the Properties window, change its Name to dlgPrint
- Still in the Properties windows, set its Document property to
docPrint
- On the main menu of the form, click File and double-click Print
- Implement the event as follows:
private void mnuFilePrint_Click(object sender, EventArgs e)
{
if (dlgPrint.ShowDialog() == DialogResult.OK)
docPrint.Print();
}
- Return to the form
- From the Printing section of the Toolbox, click PrintPreviewDialog
and click the form
- In the Properties window, change its Name to dlgPrintPreview
- Still in the Properties windows, set its Document property to
docPrint
- On the main menu of the form, click File and double-click Print
Preview
- Implement the event as follows:
private void mnuFilePrintPreview_Click(object sender, EventArgs e)
{
dlgPrintPreview.ShowDialog();
}
- Return to the form
- On the main menu of the form, click File and double-click Exit
- Implement the event as follows:
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
Close();
}
- Execute the application
- Open an existing cleaning order and print preview it
- Close the form and return to your programming environment
|
|