Home

Windows Controls: The Text Box

   

Introduction to Text Boxes

 

Description

A text box is a Windows control used to get or display text to the user. At its most regular use, a text box serves as a placeholder to fill out and provide information. Such a use is common on employment applications, login dialog boxes, forms, etc. Like most other controls, the role of a text box is not obvious at first glance; that is why it should be accompanied by a label that defines its purpose.

From the user's standpoint, a text box is named after the label closest to it. Such a label is usually positioned to the left or the top side of the text box. From the programmer’s point of view, a text box is a placeholder used for various things. For example, you can show or hide it as you see fit. You can also use it only to display text without allowing the user to change it.

Creating a Text Box

To create a text box, from the Common Controls section of the Toolbox, you can click TextBox Text Box and click the form. The text box is based on the TextBox class. This means that you can use this class to dynamically create a text box and add it to your application. The text box control is based on the TextBox class whose immediate parent is TextBoxBase. Like every .NET Framework class, it has a constructor that can be used to dynamically create the control. The TextBoxBase class provides other methods derived from the control’s parent or from ancestor classes.

Using the Text of a Text Box

 

Introduction

As a control primarily meant to display text, like a label, the text box shares many of the characteristics of a label: text alignment, font, color, etc.

The most important aspect of a text box is its text, whether it is displaying or requesting it. This is the Text property. When you add a text box control to a form or other container, by default, it is left empty. If you want the control to display some text when the form launches, type a string in the Text property field in the Properties window.

After creating a text box, it may be empty, the user can start typing in it to fill it with text. You can programmatically assign it a string to occupy it. Another way you can put or add text to the control is to paste the content of the clipboard, using text from another control. The syntax of the Paste() method is:

public void Paste();

At any time, to know the length of the text in the control, you can retrieve the value of the TextLength property, which is of type int.

Selecting Text

The selection of text from a text box control can be performed either by you or by a user. To select part of the text, you can specify the starting point using the SelectionStart property, which is of type int. After the starting position, you can specify the number of characters to include in the selection. This is done using the SelectionLength property, which is of type int. The SelectionStart and the SelectionLength properties allow you to programmatically select text. The user, on the other hand, also knows how to select part of the text of the control. These operations can also be performed using the Select() method of the TextBox class. Its syntax is:

public void Select(int start, int length);

Alternatively, the user may want to select the whole content of the control. To programmatically select the whole text of a text box control, call the SelectAll() method. Its syntax is:

public void SelectAll();

When  some text has been selected in the control, to get that text, you can retrieve the value of the SelectedText property, which is a handle to String.

Operations on Text

After the text, in part or in whole, has been selected, you or the user can manipulate it. For example, you can copy the selection to the clipboard. This is done using the Copy() method. Its syntax is:

public void Copy();

To delete part of the text, the user can cut it. You can programmatically do this using the Cut() method. Its syntax is:

public void Cut();

To delete the whole contents of the text box, you can call the Clear() method. Its syntax is:

public void Clear();

Any operation performed on the text box can be undone using the Undo() method whose syntax is:

public void Undo();

To prevent an undo operation, call the ClearUndo() method. Its syntax is:

public void ClearUndo();

ApplicationApplication: Introducing Text Boxes

  1. Create a Window Forms Application named ElementaryAddition2
  2. Design the form as follows:
     
    Elementary Addition
    Control Text Name TextAlign Font Additional Properties
    Label 00 lblOperand1 Center Name: Tahoma
    Size:   48
    Bold:   True
    AutoSize: True
    ForeColor: Blue
    Label +   Center Name: Arial
    Size:   50
    Bold:   True
    AutoSize: True
    ForeColor: Maroon
    Label 00 lblOperand2 Center Name: Tahoma
    Size:   48
    Bold:   True
    AutoSize: True
    ForeColor: Blue
    Label =   Center Name: Arial
    Size:   50
    Bold:   True
    AutoSize: True
    ForeColor: Green
    TextBox 000 txtResult Center Name: Tahoma
    Size:   48
    Bold:   True
     
    Label New Operation lblNewOperation Center Name: Tahoma, Size: 28 Bold: True AutoSize: True
    BorderStyle: Fixed3D
    ForeColor: White
    BackColor:Maroon 
    Label Check lblCheckAnswer Center Name: Tahoma, Size: 28 Bold: True AutoSize: True
    BorderStyle: Fixed3D
    ForeColor: White
    BackColor:Maroon 
    Label Quit lblQuit Center Name: Tahoma, Size: 28 Bold: True AutoSize: True
    BorderStyle: FixedSingle
  3. Double-click the New Operation label and implement its event as follows:
    private void lblNewOperation_Click(object sender, EventArgs e)
    {
            int operand1;
            int operand2;
    
            Random rnd = new Random();
    
            operand1 = rnd.Next(99);
            operand2 = rnd.Next(99);
            int result = operand1 + operand2;
    
            lblOperand1.Text = operand1.ToString();
            lblOperand2.Text = operand2.ToString();
            txtResult.Text   = "";
            txtResult.Focus();
    }
  4. Return to the form and double-click the Check label
  5. Implement its event as follows:
    private void lblCheckAnswer_Click(object sender, EventArgs e)
    {
            int Operand1 = 0;
            int Operand2 = 0;
            int Result = 0;
    
            try
            {
                    Operand1 = int.Parse(lblOperand1.Text);
            }
            catch (FormatException)
            {
                    MessageBox.Show("Invalid Value");
            }
    
            try
            {
                    Operand2 = int.Parse(lblOperand2.Text);
            }
            catch (FormatException)
            {
                    MessageBox.Show("Invalid Value");
            }
    
            try
            {
                    Result = int.Parse(txtResult.Text);
            }
            catch (FormatException)
            {
                    MessageBox.Show("Invalid Answer");
            }
    
            if (Result == (Operand1 + Operand2))
                    MessageBox.Show("WOW - Good Answer");
            else
                    MessageBox.Show("PSSST - Wrong Answer");
    
            lblNewOperation_Click(sender, e);
    }
  6. Return to the form and double-click Quit
  7. Implement its event as follows:
    private void lblQuit_Click(object sender, EventArgs e)
    {
                Close();
    }
  8. Execute the application and test it
  9. Click the Close button to close the form and return to your programming environment

Characteristics of Text Boxes

 

Mnemonics

As mentioned already, a text box should be accompanied by a label that indicates what it is used for. To support this relationship, the Label control provides various properties. An accelerator character is a symbol of the label that provides easy access to its text box. On the label, such a character is underlined. An example would be First Name. The idea is that, if the user presses the Alt key in combination with the label’s underlined character, the text box it accompanies would receive focus.

To create an accelerator key, choose one of the label’s characters and precede it with an ampersand character when setting its caption. An example would be &First Name. If you want a label to display the accelerator character instead of a plain ampersand, set the label’s UseMnemonic property to true, which is already its default value. If you set it to true but need to display an ampersand, type two & characters where the ampersand would be shown.

The UseMnemonic property of a label is only used to indicate that the label would display an accelerator character and the & symbol typed on the label creates that accelerator character. To indicate which text box would receive focus when the accelerator character of the label is invoked, you must make sure you establish an appropriate tab sequence using the Tab Order menu item from the main menu or using the combination of TabStop/TabIndex properties. Typically, the label should have a Tab Order or TabIndex value that is just - 1 of that of the control it serves.

ApplicationApplication: Creating Text Boxes

  1. To start a new application, on the main menu, click File -> New Project (or File -> New Project)
  2. In the middle list, click Windows Application and set the name to PayrollProcessing1
  3. Click OK
  4. Design the form as follows:
     
    Payroll Processing
    Control Name Text Other Properties
    GroupBox GroupBox   Employee Identification  
    Label Label   &Employee Name:  
    TextBox TextBox txtEmployeeName    
    Label Label   Hourly &Salary:  
    TextBox TextBox txtHourlySalary    
    GroupBox GroupBox   Time Values  
    Label Label   Monday  
    Label Label   Tuesday  
    Label Label   Wednesday  
    Label Label   Thursday  
    Label Label   Friday  
    Label Label   Saturday  
    Label Label   Sunday  
    Label Label   First Week:  
    TextBox TextBox txtMonday1 0.00 TextAlign: Right
    TextBox TextBox txtTuesday1 0.00 TextAlign: Right
    TextBox TextBox txtWednesday1 0.00 TextAlign: Right
    TextBox TextBox txtThursday1 0.00 TextAlign: Right
    TextBox TextBox txtFriday1 0.00 TextAlign: Right
    TextBox TextBox txtSaturday1 0.00 TextAlign: Right
    TextBox TextBox txtSunday1 0.00 TextAlign: Right
    Label Label   Second Week:  
    TextBox TextBox txtMonday2 0.00 TextAlign: Right
    TextBox TextBox txtTuesday2 0.00 TextAlign: Right
    TextBox TextBox txtWednesday2 0.00 TextAlign: Right
    TextBox TextBox txtThursday2 0.00 TextAlign: Right
    TextBox TextBox txtFriday2 0.00 TextAlign: Right
    TextBox TextBox txtSaturday2 0.00 TextAlign: Right
    TextBox TextBox txtSunday2 0.00 TextAlign: Right
    GroupBox GroupBox   Payroll Processing  
    Label Label   Hours  
    Label Label   Amount  
    Label Label btnCalculate Calculate AutoSize: False
    Label Label   Regular  
    TextBox TextBox txtRegularTime 0.00 TextAlign: Right
    TextBox TextBox txtRegularAmount 0.00 TextAlign: Right
    Label Label   Net Pay:  
    TextBox TextBox txtNetPay 0.00 TextAlign: Right
    Label Label   Overtime  
    TextBox TextBox txtOvertime 0.00 TextAlign: Right
    TextBox TextBox txtOvertimeAmount 0.00 TextAlign: Right
    Label Label btnClose   AutoSize: False
  5. Double-click the Close label and implement its Click event as follows:
    private void btnClose_Click(object sender, EventArgs e)
    {
        Close();
    }
  6. Save all

The Read-Only Attribute

By default, a newly created text box is used to both display and receive text from the user. If you want the user to read text without being able to change it, set the ReadOnly Boolean property to True. Its default value is false.

ApplicationApplication: Setting the Read-Only Attribute

  1. On the form, click the text box at the intersection of Time and Regular
  2. In the Properties window, double-click ReadOnly to change its value to True
  3. Do the same for the following text boxes: txtRegularAmount, txtNetPay, txtOvertime, and txtOvertimeAmount

Auto-Completing a Text Box

If a text box allows the user to enter text in it, the user can click the control and start typing. If a certain text box usually receives some known or common strings, you can assist the user with completing the entry. The TextBox class supports this with three properties.

If you want to assist the user with completing the string entered in a text box, first specify where the necessary strings will come from. You have two options. You can use the AutoCompleteSource property, that is based on the AutoCompleteSource enumeration. Its members are: None, RecentlyUsedList, FileSystem, FileSystemDirectories, HistoryList, ListItems, AllSystemSources, AllUrl, and CustomSource.

If you want to specify your own-created list of items, use the AutoCompleteCustomSource property. At design time, to create a list of strings, access the Properties window for the text box. In the Properties window, click the ellipsis button of the AutoCompleteCustomSource field to open the String Collection Editor. Enter the strings separated by a hard Return, and click OK.

After specifying the source of the list that will assist the user to complete the entry of the text box, set it AutoCompleteMode property. This property is based on the AutoCompleteMode enumeration that has four members. None is the default value.

ApplicationApplication: Auto-Completing a Text Box

  1. On the form, click the txtEmployeeName text box
  2. In the Properties window, click AutoCompleteCustomSource and click its ellipsis button
  3. In the String Collection Editor, enter the following names:
    Micheline Hammond
    Paul Bertrand Yamaguchi
    Gertrude Monay
    Ernestine Ngaleu
    Andy Barang
    Christophe Yuen
    Jean Michel Kankan
  4. Click OK
  5. Click AutoCompleteSource, then click the arrow of its combo box and select CustomSource
  6. Click AutoCompleteMode, then click the arrow of its combo box and select Accept
  7. On the form, double-click the Calculate label and implement its event as follows:
    private void btnCalculate_Click(object sender, EventArgs e)
    {
            double monday1 = 0.00, tuesday1 = 0.00, wednesday1 = 0.00,
                        thursday1 = 0.00, friday1 = 0.00, saturday1 = 0.00,
                        sunday1 = 0.00, monday2 = 0.00, tuesday2 = 0.00,
                        wednesday2 = 0.00, thursday2 = 0.00,
             friday2 = 0.00, saturday2 = 0.00, sunday2 = 0.00;
             double totalHoursWeek1, totalHoursWeek2;
    
             double regHours1 = 0.00, regHours2 = 0.00,
                         ovtHours1 = 0.00, ovtHours2 = 0.00;
             double regAmount1 = 0.00, regAmount2 = 0.00,
                         ovtAmount1 = 0.00, ovtAmount2 = 0.00;
             double regularHours, overtimeHours;
             double regularAmount, overtimeAmount, totalEarnings;
    
             double hourlySalary = 0.00;
    
             // Retrieve the hourly salary
             try
             {
                    hourlySalary = double.Parse(txtHourlySalary.Text);
             }
             catch (FormatException)
             {
                    MessageBox.Show(
                        "The value you typed for the salary is invalid \n" +
                        "Please try again");
                    txtHourlySalary.Focus();
             }
    
             // Retrieve the value of each day worked
             try
             {
                    monday1 = double.Parse(txtMonday1.Text);
             }
             catch (FormatException)
             {
                    MessageBox.Show("You typed an invalid value\n" +
                             "Please try again");
                    txtMonday1.Focus();
             }
             try
             {
                    tuesday1 = double.Parse(txtTuesday1.Text);
             }
             catch (FormatException)
             {
                    MessageBox.Show("You typed an invalid value\n" +
                        "Please try again");
                    this.txtTuesday1.Focus();
             }
             try
             {
                    wednesday1 = double.Parse(txtWednesday1.Text);
             }
             catch (FormatException)
             {
                    MessageBox.Show("You typed an invalid value\n" +
                        "Please try again");
                    txtWednesday1.Focus();
             }
             try
             {
                    thursday1 = double.Parse(txtThursday1.Text);
             }
             catch (FormatException)
             {
                    MessageBox.Show("You typed an invalid value\n" +
                        "Please try again");
                    txtThursday1.Focus();
             }
    
             try
             {
                    friday1 = double.Parse(txtFriday1.Text);
             }
             catch (FormatException)
             {
                    MessageBox.Show("You typed an invalid value\n" +
                        "Please try again");
                    txtFriday1.Focus();
             }
    
             try
             {
                    saturday1 = double.Parse(txtSaturday1.Text);
             }
             catch (FormatException)
             {
                    MessageBox.Show("You typed an invalid value\n" +
                        "Please try again");
                    txtSaturday1.Focus();
             }
    
             try
             {
                    sunday1 = double.Parse(txtSunday1.Text);
             }
             catch (FormatException)
             {
                    MessageBox.Show("You typed an invalid value\n" +
                        "Please try again");
                    txtSunday1.Focus();
                }
                try
                {
                    monday2 = double.Parse(txtMonday2.Text);
                }
                catch (FormatException)
                {
                    MessageBox.Show("You typed an invalid value\n" +
                        "Please try again");
                    this.txtMonday2.Focus();
                }
                try
                {
                    tuesday2 = double.Parse(txtTuesday2.Text);
                }
                catch (FormatException)
                {
                    MessageBox.Show("You typed an invalid value\n" +
                        "Please try again");
                    this.txtTuesday2.Focus();
                }
                try
                {
                    wednesday2 = double.Parse(txtWednesday2.Text);
                }
                catch (FormatException)
                {
                    MessageBox.Show("You typed an invalid value\n" +
                        "Please try again");
                    this.txtWednesday2.Focus();
                }
                try
                {
                    thursday2 = double.Parse(txtThursday2.Text);
                }
                catch (FormatException)
                {
                    MessageBox.Show("You typed an invalid value\n" +
                        "Please try again");
                    txtThursday2.Focus();
                }
                try
                {
                    friday2 = double.Parse(txtFriday2.Text);
                }
                catch (FormatException)
                {
                    MessageBox.Show("You typed an invalid value\n" +
                        "Please try again");
                    txtFriday2.Focus();
                }
                try
                {
                    saturday2 = double.Parse(txtSaturday2.Text);
                }
                catch (FormatException)
                {
                    MessageBox.Show("You typed an invalid value\n" +
                        "Please try again");
                    txtSaturday2.Focus();
                }
                try
                {
                    sunday2 = double.Parse(txtSunday2.Text);
                }
                catch (FormatException)
                {
                    MessageBox.Show("You typed an invalid value\n" +
                        "Please try again");
                    txtSunday2.Focus();
                }
    
                // Calculate the total number of hours for each week
                totalHoursWeek1 = monday1 + tuesday1 + wednesday1 +
                      thursday1 + friday1 + saturday1 + sunday1;
                totalHoursWeek2 = monday2 + tuesday2 + wednesday2 +
                    thursday2 + friday2 + saturday2 + sunday2;
    
                // The overtime is paid time and half
                double ovtSalary = hourlySalary * 1.5;
    
                // If the employee worked under 40 hours, there is no overtime
                if (totalHoursWeek1 < 40)
                {
                    regHours1 = totalHoursWeek1;
                    regAmount1 = hourlySalary * regHours1;
                    ovtHours1 = 0.00;
                    ovtAmount1 = 0.00;
                } // If the employee worked over 40 hours, calculate the overtime
                else if (totalHoursWeek1 >= 40)
                {
                    regHours1 = 40;
                    regAmount1 = hourlySalary * 40;
                    ovtHours1 = totalHoursWeek1 - 40;
                    ovtAmount1 = ovtHours1 * ovtSalary;
                }
    
                if (totalHoursWeek2 < 40)
                {
                    regHours2 = totalHoursWeek2;
                    regAmount2 = hourlySalary * regHours2;
                    ovtHours2 = 0.00;
                    ovtAmount2 = 0.00;
                }
                else if (totalHoursWeek2 >= 40)
                {
                    regHours2 = 40;
                    regAmount2 = hourlySalary * 40;
                    ovtHours2 = totalHoursWeek2 - 40;
                    ovtAmount2 = ovtHours2 * ovtSalary;
                }
    
                regularHours = regHours1 + regHours2;
                overtimeHours = ovtHours1 + ovtHours2;
                regularAmount = regAmount1 + regAmount2;
                overtimeAmount = ovtAmount1 + ovtAmount2;
                totalEarnings = regularAmount + overtimeAmount;
    
                txtRegularTime.Text = regularHours.ToString("F");
                txtOvertime.Text = overtimeHours.ToString("F");
                txtRegularAmount.Text = regularAmount.ToString("F");
                txtOvertimeAmount.Text = overtimeAmount.ToString("F");
    
                txtNetPay.Text = totalEarnings.ToString("F");
            }
  8. Execute the application to see the result
     
    Payroll Information
  9. Close the form and return to your programming environment

Character Casing

A text box can be configured to display only lowercase characters, only uppercase characters, or a mix. This characteristic is controlled by the CharacterCasing property, which is an enumerator that holds the same name. The default value of this property is Normal, which indicates that the control can use a mix of lowercase and uppercase characters. If you set this property to Lower, all existing characters, if any, in the control would be converted to lowercase and all future characters typed in the control would be automatically converted to lowercase. If you set this property to Upper, all existing characters, if any, in the control would be converted to uppercase and all future characters typed in the control would be automatically converted to uppercase.

Character Password

Text typed in a text box appears with its corresponding characters unless you changed the effect of the CharacterCasing property from its default Normal value. This allows the user to see, and be able to read, the characters of the control. If you prefer to make the characters un-readable, you have two options.

The operating system uses a default character it uses to hide the contents of a text box. If you want to use that character, set the UseSystemPasswordChar property to true. If you prefer to specify your own character, you can use the PasswordChar property. Although this property is a char type of data, changing it actually accomplishes two things:

  • If you type a character in its field in the Properties window, for example if you type *, any character typed in it would be un-readable
  • Any character in the control would be replaced by the value of this property. You can use any alphabetic character or digit to represent the characters that would be typed but you must provide only one character

 

The Multi-Line Text Box

 

Introduction

The regular text box is meant to display one line of text. If the user enters text and presses Enter, nothing particular happens. If the user enters text and presses Tab, the focus moves to the next control in the tab sequence. You may want to create an application that goes further than the one-line limit. For example, if you have used Notepad, you would know that it shares the font characteristics of a text box but it also allows some text navigation features that require more than one line. You can create such an application based on the text box control.

Creating a Multi-Line Text Box

The TextBox control is equipped with one particular property that, when considered, changes the control tremendously. This property is called Multiline. Multiline is a Boolean property whose default value is false. If it is set to a true value, it allows the control to display multiple lines of text, unlike the normal text box that can display only one line.

ApplicationApplication: Introducing Printing

  1. Start Microsoft Visual C#
  2. Create a new Windows Application named CollegeParkAutoRepair1
  3. In the Solution Explorer, right-click Form1.cs and click Rename
  4. Type CollegeParkAutoRepair.cs and press Enter
  5. In the Menus & Toolbars section of the Toolbox, click MenuStrip and click the form
  6. Under the form, right-click menuStrip1 and click Insert Standard Items
  7. In the Menus & Toolbars section of the Toolbox, click StatusStrip and click the form
  8. Design the form as follows:
     
    College Park Auto Repair
    Control Name Text Other Properties
    GroupBox GroupBox   Order Identification  
    Label Label   Customer Name:  
    TextBox TextBox txtCustomerName    
    Label Label   Address  
    TextBox TextBox txtAddress    
    Label Label   City:  
    TextBox TextBox txtCity    
    Label Label   State:  
    TextBox TextBox txtState    
    Label Label   ZIP Code:  
    TextBox TextBox txtZIPCode   TextAlign: Right
    Label Label   Make / Model:  
    TextBox TextBox txtMake    
    TextBox TextBox txtModel    
    Label Label   Year:  
    TextBox TextBox txtCarYear   TextAlign: Right
    Label Label   Problem Description:  
    TextBox TextBox txtProblem   Mutltiline: True
    GroupBox GroupBox   Parts Used  
    DataGridView DataGridView dgvPartsUsed    
    Columns  
    Header Text Name Width
    Part Name/Description colPartName 215
    Unit Price colUnitPrice 80
    Qty colQuantity 30
    Sub-Total colSubTotal 60
    GroupBox GroupBox   Jobs Performed  
    DataGridView DataGridView dgvJobsPerformed    
    Columns  
    Header Text Name Width
    Job Performed colJobPerformed 320
    Cost colCost 60
    GroupBox GroupBox   Repair Summary  
    Label Label   Total Parts:  
    TextBox TextBox txtTotalParts 0.00 TextAlign: Right
    Label Label   Tax Rate:  
    TextBox TextBox txtTaxRate 5.75 TextAlign: Right
    Label Label   %  
    Label Label   Total Labor:  
    TextBox TextBox txtTotalLabor 0.00 TextAlign: Right
    Label Label   Tax Amount:  
    TextBox TextBox txtTaxAmount 0.00 TextAlign: Right
    Label Label   RepairTotal:  
    TextBox TextBox txtRepairTotal 0.00 TextAlign: Right
    Label Label   Recommendations  
    TextBox TextBox txtRecommendations   Multiline: True
    OpenFileDialog OpenFileDialog dlgOpen   DefaultExt: rpr
    Filter: Repair Orders (*.rpr)|*.rpr|All Files|
    Title: Open Existing Repair Order
    SaveFileDialog SaveFileDialog dlgSave  

    DefaultExt: rpr
    Filter: Repair Orders (*.rpr)|*.rpr|All Files|
    Title: Save Current Repair Order

    PrintDocument PrintDocument docPrint  

     

    PrintDialog PrintDialog dlgPrint   

    Document: docPrint

    PageSetupDialog dlgPageSetup   Document: docPrint
    PrintPreviewDialog Print Preview Dialog dlgPrintPreview   Document: docPrint
  9. On the form, click the data grid view in the Parts Used group
  10. In the properties window, click Events and double-click CellLeave
  11. Implement the event as follows:
    void CalculateTotal()
    {
        double taxRate = 0d, taxAmount = 0d;
        double totalParts = 0d, totalLabor = 0d, totalPartsAndLabor, repairTotal;
    
        foreach( DataGridViewRow record in dgvPartsUsed.Rows)
        {
            try
            {
                totalParts += double.Parse(record.Cells[3].EditedFormattedValue.ToString());
                txtTotalParts.Text = totalParts.ToString("F");
            }
            catch (FormatException)
            {
            }
        }
    
        foreach (DataGridViewRow record in dgvJobsPerformed.Rows)
        {
            try
            {
                totalLabor += double.Parse(record.Cells[1].EditedFormattedValue.ToString());
                txtTotalLabor.Text = totalLabor.ToString("F");
            }
            catch (FormatException)
            {
            }
        }
    
        try
        {
            taxRate = double.Parse(txtTaxRate.Text);
        }
        catch (FormatException)
        {
            MessageBox.Show("Invalid Tax Rate");
            txtTaxRate.Text = "5.75";
            txtTaxRate.Focus();
        }
    
        totalPartsAndLabor = totalParts + totalLabor;
    
        taxAmount = totalPartsAndLabor * taxRate / 100;
        repairTotal = totalPartsAndLabor + taxAmount;
    
        txtTotalParts.Text = totalParts.ToString("F");
        txtTotalLabor.Text = totalLabor.ToString("F");
        txtTaxAmount.Text = taxAmount.ToString("F");
        txtRepairTotal.Text = repairTotal.ToString("F");
    }
    
    private void dgvPartsUsed_CellLeave(object sender, DataGridViewCellEventArgs e)
    {
        if (e.ColumnIndex == 2)
        {
            double unitPrice = 0D;
            int quantity = 0;
            double subTotal = 0D;
            
            DataGridViewCell dgvcUnitPrice = dgvPartsUsed.Rows[e.RowIndex].Cells[1];
            DataGridViewCell dgvcQuantity = dgvPartsUsed.Rows[e.RowIndex].Cells[e.ColumnIndex];
    
            unitPrice = double.Parse(dgvcUnitPrice.EditedFormattedValue.ToString());
            quantity = int.Parse(dgvcQuantity.EditedFormattedValue.ToString());
            subTotal = unitPrice * quantity;
            dgvPartsUsed.Rows[e.RowIndex].Cells[3].Value = subTotal.ToString("F");
    
            CalculateTotal();
        }
    }
  12. Return to the form
  13. Click the Jobs Performed data grid view
  14. In the Events section of the properties window, double-click CellLeave
  15. Implement the event as follows:
    private void dgvJobsPerformed_CellLeave(object sender, DataGridViewCellEventArgs e)
    {
        CalculateTotal();
    }
  16. Return to the form
  17. On the form, click File and double-click New Repair Order
  18. Implement its Click event as follows:
    private void newToolStripMenuItem_Click(object sender, EventArgs e)
    {
        txtCustomerName.Text = "";
        txtAddress.Text = "";
        txtCity.Text = "";
        txtState.Text = "";
        txtZIPCode.Text = "";
        txtMake.Text = "";
        txtModel.Text = "";
        txtYear.Text = "";
        txtProblemDescription.Text = "";
    
        dgvPartsUsed.Rows.Clear();
        dgvJobsPerformed.Rows.Clear();
    
        txtTotalParts.Text = "0.00";
        txtTotalLabor.Text = "0.00";
        txtTaxRate.Text = "7.75";
        txtTaxAmount.Text = "0.00";
        txtRepairTotal.Text = "0.00";
    
        txtRecommendations.Text = "";
        txtCustomerName.Focus();
    }
  19. In the top section of the file, type the following:
    using System;
    using System.ComponentModel;
    using System.Collections;
    using System.Windows.Forms;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.IO;
    using System.Runtime.Serialization.Formatters.Binary;
  20. Return to the form
  21. On the form, click File and double-click Save As...
  22. Implement its Click event as follows:
    private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
    {
        // Just in case, calculate the order now
        CalculateTotal();
    
        // Check the folder that will contain the repair order.
        // If it exists, don't create it.
        // If it doesn't exist, then create it
        string strDirectory = @"C:\College Park Auto Repair";
        DirectoryInfo dirInfo = Directory.CreateDirectory(strDirectory);
    
        // Prepare to create a repair order
        RepairOrder order = new RepairOrder();
    
    
        // Display the Save As dialog box.
        // Select the above directory
        dlgSave.InitialDirectory = strDirectory;
        // Check if the user clicked OK
        if (dlgSave.ShowDialog() == System.Windows.Forms.DialogResult.OK)
        {
            // If the user clicked OK, create a repair order
            order.CustomerName = txtCustomerName.Text;
            order.Address = txtAddress.Text;
            order.City = txtCity.Text;
            order.State = txtState.Text;
            order.ZIPCode = txtZIPCode.Text;
            order.Make = txtMake.Text;
            order.Model = txtModel.Text;
            order.Year = int.Parse(txtYear.Text);
            order.ProblemDescription = txtProblemDescription.Text;
    
            // Check whether the Parts Used data grid view contains some records.
            // If it does, save them
            if (dgvPartsUsed.Rows.Count > 1)
            {
                List<Part> parts = new List<Part>();
    
                for (int row = 0; row < dgvPartsUsed.Rows.Count - 1; row++ )
                {
                    Part prt = new Part();
                    prt.PartName = dgvPartsUsed.Rows[row].Cells[0].EditedFormattedValue.ToString();
                    prt.UnitPrice = double.Parse(dgvPartsUsed.Rows[row].Cells[1].EditedFormattedValue.ToString());
                    prt.Quantity = int.Parse(dgvPartsUsed.Rows[row].Cells[2].EditedFormattedValue.ToString());
                    prt.SubTotal = double.Parse(dgvPartsUsed.Rows[row].Cells[3].EditedFormattedValue.ToString());
                    parts.Add(prt);
                }
                order.Parts = parts;
            }
            else // If the data grid view is empty, flag its value as null
                order.Parts = null;
    
            if (dgvJobsPerformed.Rows.Count > 1)
            {
                List<JobPerformed> work = new List<JobPerformed>();
    
                for (int row = 0; row < dgvJobsPerformed.Rows.Count - 1; row++)
                {
                    JobPerformed done = new JobPerformed();
                    done.Job = dgvJobsPerformed.Rows[row].Cells[0].EditedFormattedValue.ToString();
                    done.Cost = double.Parse(dgvJobsPerformed.Rows[row].Cells[1].EditedFormattedValue.ToString());
                    work.Add(done);
                }
    
                order.Jobs = work;
            }
    
            order.TotalParts = double.Parse(txtTotalParts.Text);
            order.TotalLabor = double.Parse(txtTotalLabor.Text);
            order.TaxRate = double.Parse(txtTaxRate.Text);
            order.TaxAmount = double.Parse(txtTaxAmount.Text);
            order.RepairTotal = double.Parse(txtRepairTotal.Text);
            order.Recommendations = txtRecommendations.Text;
    
            FileStream stmRepair = new FileStream(dlgSave.FileName,
                                                       FileMode.Create);
            BinaryFormatter bfmRepair = new BinaryFormatter();
            bfmRepair.Serialize(stmRepair, order);
    
            stmRepair.Close();
            newToolStripMenuItem_Click(sender, e);
        }
    }
  23. Return to the form
  24. On the form, click File and double-click Open...
  25. Implement the event as follows:
    private void openToolStripMenuItem_Click(object sender, EventArgs e)
    {
        dlgOpen.InitialDirectory = @"C:\College Park Auto Repair";
    
        if (dlgOpen.ShowDialog() == DialogResult.OK)
        {
            FileStream stmRepair = new FileStream(dlgOpen.FileName,
                                             FileMode.Open);
            BinaryFormatter bnrRepair = new BinaryFormatter();
            RepairOrder order = (RepairOrder)bnrRepair.Deserialize(stmRepair);
    
            txtCustomerName.Text = order.CustomerName;
            txtAddress.Text      = order.Address;
            txtCity.Text         = order.City;
            txtState.Text        = order.State;
            txtZIPCode.Text      = order.ZIPCode;
            txtMake.Text         = order.Make;
            txtModel.Text        = order.Model;
            txtYear.Text         = order.Year.ToString();
            txtProblemDescription.Text = order.ProblemDescription;
    
            int i = 0;
            foreach (Part prt in order.Parts)
            {
                dgvPartsUsed.Rows.Add();
    
                dgvPartsUsed.Rows[i].Cells[0].Value = prt.PartName;
                dgvPartsUsed.Rows[i].Cells[1].Value = prt.UnitPrice.ToString("F");
                dgvPartsUsed.Rows[i].Cells[2].Value = prt.Quantity.ToString();
                dgvPartsUsed.Rows[i].Cells[3].Value = prt.SubTotal.ToString("F");
                i++;
            }
    
            i = 0;
            foreach (JobPerformed jp in order.Jobs)
            {
                dgvJobsPerformed.Rows.Add();
    
                dgvJobsPerformed.Rows[i].Cells[0].Value = jp.Job;
                dgvJobsPerformed.Rows[i].Cells[1].Value = jp.Cost;
                i++;
            }
    
            txtTotalParts.Text  = order.TotalParts.ToString("F");
            txtTotalLabor.Text  = order.TotalLabor.ToString("F");
            txtTaxRate.Text     = order.TaxRate.ToString("F");
            txtTaxAmount.Text   = order.TaxAmount.ToString("F");
            txtRepairTotal.Text = order.RepairTotal.ToString("F");
            txtRecommendations.Text = order.Recommendations;
    
            stmRepair.Close();
        }
    }
  26. To execute the application, press F5
  27. Create a repair order. Here is an example:
     
    College Park Auto Repair
  28. On the main menu of the form, click File -> Save As...
  29. Set the name to 100001 and click Save
  30. Create another order, calculate it and save it
  31. Try opening a previously saved order
  32. Close the form and return to your programming environment

Characteristics of a Multi-Line Text Box

 

Introduction

The multi-line text box shares all of the properties of the single-line text box. These include the read-only attribute, the character casing, and the password options. Although these properties are valid, some of them may not be suitable for a multi-line text box, such as applying a password character to hide the text, trying to auto-complete a string while the user is typing it, etc. This is why, in most cases, we will tend to consider the single-line and the multiple line objects are separate controls.

The Lines of Text

By default, when you add a new text box to your form, it appears empty. When the application comes up, the user mostly reads and/or enters text in the multi-line text box when interacting with the control. At design time, you can set the text that would display when the multi-line text box comes up. To support multiple lines of text, the TextBox class is equipped with a property named Lines:

public string[] Lines { get; set; }

As you can see, the Lines proeprty is an array, which is also serializable. During design, to manually create the lines of text, in the Properties window, click the Lines field, then click its ellipsis button. That would open the String Collection Editor. Type the desired text and click OK. On the other hand, after the user has entered some text or a few lines of text in the control, it holds these lines. The lines of text of a text box are stored in an array represented by a property named Lines. This means that, at run time, you can create an array of lines of text and assign it to the text box. Or, to get the lines of text of the control, you can retrieve the value of the Lines property.

The Modified Attribute

When a multi-line text box opens, the compiler registers the content of the control. If the user has the ability to change the text in the control and if the user changes it, the compiler flags the control as Modified. This allows you to take actions. You can acknowledge this by programmatically setting the Modified property to true. If another control or some other action alters the contents of the multi-line text box, you can make sure that this property reflects the change. You can change this programmatically as follows:

private void button1_Click(object  sender, EventArgs  e)
{
    textBox1.Modified = true;
}

The Maximum Length of Text

The multi-line text box allows the user to enter up to 32767 characters. If you want to limit the maximum number of characters that the user can enter to a value lower than this, you can use the MaxLength property at design time. You can also change this programmatically. Here is an example:

private void button1_Click(object  sender, EventArgs  e)
{
    textBox1.MaxLength = 1020;
}

Using the Enter Key

If the control will be used to enter text, the user can press Enter at the end of a line to move to the next line. This ability is controlled by the Boolean AcceptsReturn property. By default, this property is set to False because this control is primarily created from a normal single-line TextBox control that has no formal action to take when the user presses Enter. If you are creating a multi-line text box and you expect your users to perform some type of text editing, you certainly should allow them to press Enter to move to the next line. Therefore, in most cases, when creating a multi-line text box, you should set its AcceptsReturn property to True. To set it programmatically, assign the desired value to the AcceptstReturn property. Here is an example:

private void button1_Click(object  sender, EventArgs  e)
{
        textBox1.AcceptsReturn = true;
}

Using the Tab Key

The user is accustomed to pressing Tab to insert tab characters in the text. By default, when the user presses Tab when interacting with your application, the focus moves from one control to the next, following the TabIndex values of the form. Even when using a multi-line text box to perform text editing, if the user presses Tab, the focus would switch to another control or to the form. If you want a multi-line text box to receive focus when the user presses the Tab key, set the AcceptTab property from False (the default), to True.

When entering text in a multi-line text box control, the characters start on the left side of the multi-line text box and are subsequently added on the right side. The ability to align text is controlled by the TextAlign property. For a multi-line text box control, the alignment is configured using the HorizontalAlignment enumerator.

Wrapping Text

As the user enters text in a multi-line text box box, the compiler considers that a paragraph starts from the user typing a character until he or she presses Enter. Therefore, a paragraph could be an empty space, a character, a word, a line of text, a whole page or an entire book. Depending on the width of the multi-line text box control, the text is incrementally added to the right side of each previous character. If the caret gets to the right border of the control, the text automatically continues to the next line, although it is still considered as one paragraph. To start a new paragraph, the user has to press Enter. The ability for the text to continue on the next line when the caret encounters the right border of the multi-line text box is controlled by the WordWrap property whose default Boolean value is set to true. If you do not want text to wrap to the subsequent line, set the WordWrap property to false. You can also set it programmatically as follows:

private void button1_Click(object  sender, EventArgs  e)
{
    textBox1.WordWrap = false;
}

Using Scroll Bars

When a text box has been configured to hold multiple lines and once its text becomes too long, part of the content could become hidden. To show the hidden part, the control should be equipped with scrollbars so the user can navigate up and down, left and right. To support the display of scrollbars, the TextBox class is equipped with the ScrollBars property. You can specify the option of this property at either the design time or the run time or both.

The TextBox.ScrollBars property is based on the ScrollBars enumeration that has four members:

  • None: This is the default value and its means that the text box would not display any scrollbar
  • Vertical: This option specifies that the text box should display a vertical scroll bar when its content becomes too long
  • Horizontal: This is valid only if the WordWrap property is set to false. In this case, the text box would display a horizontal scroll bar
  • Both: This allows displaying both the vertical and the horizontal scrollbars

ApplicationApplication: Adding Scroll Bars

  1. On the form, click one of the multiline text boxes
  2. In the Properties window, click ScrollBars, then click the arrow of its field, and select Vertical
  3. On the form, click the other multiline text boxes
  4. In the Properties window, double-click ScrollBars until it displays Vertical

Methods to Manage a Multi-Line Text Box

The multi-line text box control is based on the TextBox class. To dynamically create a multi-line text box, declare a TextBox variable and use its default constructor to initialize it. The other operations the user can perform on a multi-line text box can be controlled by methods such as Undo(), Cut(), Copy(), Paste(), Clear() or SelectAll() that we reviewed for the text box control and they function the same.

Here are examples: 

private void mnuEditUndo_Click(object  sender, EventArgs  e)
{
	 this.txtNotice.Undo();
}
private void mnuEditCut_Click(object  sender, EventArgs  e)
{
	 this.txtNotice.Cut();
}
private void mnuEditCopy_Click(object  sender, EventArgs  e)
{
	 this.txtNotice.Copy();
}
private void mnuEditPaste_Click(object  sender, EventArgs  e)
{
	 this.txtNotice.Paste();
}
 

Home Copyright © 2010-2014, FunctionX