Home

File-Based Applications

 

A File-Based Application

 

Introduction to Databases

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

  1. Start Microsoft Visual Studio
  2. Create a Windows Application named GeorgetownDryCleaningServices1
  3. From the Menus & Toolbars section of the Toolbox, click MenuStrip and click the form
  4. While the menu strip is still selected, in the Properties window, click (Name) and type mnuMain
  5. Under the Properties window, click Insert Standard Items
  6. On the form, click Help and press Delete
  7. Click Tools and press Delete
  8. Click Edit and press Delete
  9. Click File, click Save As and press Delete
  10. 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
  11. Design the form as follows:
     
    Georgetown Dry Cleaner
     
    Control Name Text Additional Properties
    GroupBox GroupBox   Order Identification  
    Label Label   &Receipt #:  
    TextBox TextBox txtReceiptNumber 1000 TextAlign: Right
    Label Label   Customer Name:  
    TextBox TextBox txtCustomerName    
    Label Label   Customer Phone:  
    TextBox TextBox txtCustomerPhone    
    Label Label   Date Left:  
    DateTimePicker DateTimePicker dtpDateLeft    
    Label Label   Time Left:  
    DateTimePicker Date Time Picker dtpTimeLeft   Format: Time
    Label Label   Date Expected:  
    DateTimePicker DateTimePicker dtpDateExpected    
    Label Label   Time Expected:  
    DateTimePicker DateTimePicker dtpTimeExpected   Format: Time
    Label Label   Order &Status:  
    ComboBox ComboBox cbxOrderStatus    
    Label Label   D&ate Picked Up:  
    DateTimePicker DateTimePicker dtpDatePickedUp    
    Label Label   Time Pic&kep Up:  
    DateTimePicker DateTimePicker dtpTimePickedUp    
    GroupBox GroupBox   Order Processing  
    Label Label   Item Type  
    Label Label   Unit Price  
    Label Label   Qty  
    Label Label   Sub Total  
    Label Label   Shirts  
    TextBox TextBox txtShirtsUnitPrice 1.25 TextAlign: Right
    TextBox TextBox txtShirtsQuantity 0 TextAlign: Right
    TextBox TextBox txtShirtsSubTotal 0.00 TextAlign: Right
    Label Label   Pants  
    TextBox TextBox txtPantsUnitPrice 1.95 TextAlign: Right
    TextBox TextBox txtPantsQuantity   TextAlign: Right
    TextBox TextBox txtPantsSubTotal 0.00 TextAlign: Right
    ComboBox 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 TextBox txtItem1UnitPrice 0.00 TextAlign: Right
    TextBox TextBox txtItem1Quantity 0 TextAlign: Right
    TextBox TextBox txtItem1SubTotal 0.00 TextAlign: Right
    ComboBox 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 TextBox txtItem2UnitPrice 0.00 TextAlign: Right
    TextBox TextBox txtItem2Quantity 0 TextAlign: Right
    TextBox TextBox txtItem2SubTotal 0.00 TextAlign: Right
    ComboBox 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 TextBox txtItem3UnitPrice 0.00 TextAlign: Right
    TextBox TextBox txtItem3Quantity 0 TextAlign: Right
    TextBox TextBox txtItem3SubTotal 0.00 TextAlign: Right
    ComboBox 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 TextBox txtItem4UnitPrice 0.00 TextAlign: Right
    TextBox TextBox txtItem4Quantity 0 TextAlign: Right
    TextBox TextBox txtItem4SubTotal 0.00 TextAlign: Right
    GroupBox GroupBox   Order Summary  
    Label Label   Cleaning Total:  
    TextBox TextBox txtCleaningTotal 0.00 TextAlign: Right
    Label Label   Tax Rate:  
    TextBox TextBox txtTaxRate 7.75 TextAlign: Right
    Label Label   %  
    Label Label   Tax Amount:  
    TextBox TextBox txtTaxAmount 0.00 TextAlign: Right
    Label Label   Net Total:  
    TextBox TextBox txtNetPrice 0.00 TextAlign: Right
  12. Double-click the Time Left control and implement its ValueChanged event as follows:
     
    System::Void dtpTimeLeft_ValueChanged(System::Object^  sender, 
    		System::EventArgs^  e)
    {
        DateTime dateLeft = this->dtpDateLeft->Value;
        DateTime timeLeft = this->dtpTimeLeft->Value;
        DateTime time9AM = 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 = 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.00);
                dtpTimeExpected->Value = DateTime(dateLeft.Year,
                                                     dateLeft.Month,
    						 dateLeft.Day + 2, 8, 0, 0);
            }
            else
            {
                dtpDateExpected->Value = DateTime(dateLeft.Year,
                                                     dateLeft.Month,
    						 dateLeft.Day + 1);
                dtpTimeExpected->Value = DateTime(dateLeft.Year,
                                                     dateLeft.Month,
    						 dateLeft.Day + 1, 8, 0, 0);
            }
        }
    }
  13. Return to the form
 
 
 

The Directory of a Database

 

Introduction

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, provides a means of accessing the database. Then, the user adds, edits, or deletes values.

Creating a Directory

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:

Header File: Exercise.h

#pragma once

#using <System.dll>
#using <System.Drawing.dll>
#using <System.Windows.Forms.dll>

using namespace System;
using namespace System::IO;
using namespace System::Drawing;
using namespace System::Windows::Forms;

public ref class CExercise : public Form
{
public:
	CExercise(void);

private:
	void InitializeComponents();
};

Source File: Exercise.cpp

#include <windows.h>
#include "Exercise.h"

CExercise::CExercise(void)
{
	InitializeComponents();
}

void CExercise::InitializeComponents()
{
	Text = L"File-Based Application";
	StartPosition = FormStartPosition::CenterScreen;

	Directory::CreateDirectory("D:\\Bethesda Car Rental");
}

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
					 LPSTR lpCmdLine, int nCmdShow)
{
	Application::Run(gcnew CExercise());
	return 0;
}

To create a folder using the DirectoryInfo class, call its Create() method that comes in two versions. Here is an example:

#include <windows.h>
#include "Exercise.h"

CExercise::CExercise(void)
{
	InitializeComponents();
}

void CExercise::InitializeComponents()
{
    Text = L"File-Based Application";
    StartPosition = FormStartPosition::CenterScreen;

    DirectoryInfo ^ dirInfo = gcnew DirectoryInfo(L"D:\\Bethesda Car Rental");
    dirInfo->Create();
}

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
					 LPSTR lpCmdLine, int nCmdShow)
{
	Application::Run(gcnew CExercise());
	return 0;
}

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 means 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:

#include <windows.h>
#include "Exercise.h"

CExercise::CExercise(void)
{
	InitializeComponents();
}

void CExercise::InitializeComponents()
{
    Text = L"File-Based Application";
    StartPosition = FormStartPosition::CenterScreen;

    if( Directory::Exists("D:\\Bethesda Car Rental") )
        MessageBox::Show(L"The directory exists already");
    else
        MessageBox::Show(L"That directory was not yet created");
}

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
					 LPSTR lpCmdLine, int nCmdShow)
{
	Application::Run(gcnew CExercise());
	return 0;
}

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

  1. On the main menu of the form, click File and double-click New
  2. In the top section of the file, include the System::IO namespace and declare three variables as follows:
     
    #pragma once
    
    namespace GeorgetownDryCleaner1 {
    
    	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 namepace System::IO;
    
    	/// <summary>
    	/// Summary for Form1
    	///
    /// WARNING: If you change the name of this class, you will need to change the
    ///        'Resource File Name' property for the managed resource compiler tool
    ///          associated with all .resx files this class depends on.  Otherwise,
    ///          the designers will not be able to interact properly with localized
    	///          resources associated with this form.
    	/// </summary>
        public ref class Form1 : public System::Windows::Forms::Form
        {
            int iFilename;
            bool IsNewCleaningOrder;
            String ^ Filename;
    
        public:
    	Form1(void)
    	{
    		InitializeComponent();
    		//
    		//TODO: Add the constructor code here
    		//
    	}
  3. Implement the event as follows:
     
    System::Void mnuFileNew_Click(System::Object^  sender, System::EventArgs^  e)
    {
        // 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 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 + L"\\" + iFilename.ToString()+ L".gcs";
        txtReceiptNumber->Text = iFilename.ToString();
    
        txtCustomerName->Text = L"";
        txtCustomerPhone->Text = L"";
        dtpDateLeft->Value = DateTime::Today;
        dtpTimeLeft->Value = DateTime::Today;
        dtpDateExpected->Value = DateTime::Today;
        dtpTimeExpected->Value = DateTime::Today;
    
        cbxStatus->Text = L"Not Yet Ready";
        dtpDatePickedUp->Value = DateTime::Today;
        dtpTimePickedUp->Value = DateTime::Today;
    
        txtUnitPriceShirts->Text = L"1.25";
        txtQuantityShirts->Text = L"0";
        txtSubTotalShirts->Text = L"0.00";
        txtUnitPricePants->Text = L"1.95";
        txtQuantityPants->Text = L"0";
        txtSubTotalPants->Text = L"0.00";
        cbxItem1->Text = L"None";
        txtUnitPriceItem1->Text = L"0.00";
        txtQuantityItem1->Text = L"0";
        txtSubTotalItem1->Text = L"0.00";
        cbxItem2->Text = L"None";
        txtUnitPriceItem2->Text = L"0.00";
        txtQuantityItem2->Text = L"0";
        txtSubTotalItem2->Text = L"0.00";
        cbxItem3->Text = L"None";
        txtUnitPriceItem3->Text = L"0.00";
        txtQuantityItem3->Text = L"0";
        txtSubTotalItem3->Text = L"0.00";
        cbxItem4->Text = L"None";
        txtUnitPriceItem4->Text = L"0.00";
        txtQuantityItem4->Text = L"0";
        txtSubTotalItem4->Text = L"0.00";
    
        txtCleaningTotal->Text = L"0.00";
        txtTaxRate->Text = L"7.75";
        txtTaxAmount->Text = L"0.00";
        txtCleaningTotal->Text = L"0.00";
    
        txtCustomerName->Focus();
    }
  4. Return to the form
 
 
   
 

Home Copyright © 2009-2016, FunctionX, Inc. Next