Home

Other Text-Based Controls

 

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:

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();
}

The Masked Text Box

 

Introduction

The regular text box, also referred to as the edit control in Microsoft Windows (Win32), allows the user to enter any type of string in the control. As we saw in the previous sections, that control can also be changed into a multi-line memo control and allow you to create a type of Notepad application. In some cases, you may want to exercise more control on what the user can enter in a text box. For example, if you provide a text box for a date, the user can still enter a person's name. If you create a text box for a telephone number, the user may instead enter somebody's salary. To assist the user with entering a specific value into a text box, the .NET Framework provides the masked text box.

The masked text box allows you to configure one or more placeholders in the field of the control so that the control can accept some characters, must reject some characters, and/or can display some other characters you will have put so the user cannot delete them.

Creating a Masked Text Box

To create a masked text box, from the Common Controls section of the Toolbox, you can click MaskedTextBox MaskedTextBox and click the form. To programmatically create a masked text box, declare a variable of type MaskedTextBox, use the New operator to initialize it, and add it to the Controls collection of its container. Here is an example:

using System;
using System.Drawing;
using System.Windows.Forms;

public class Exercise : System.Windows.Forms.Form
{
    MaskedTextBox txtFunctional;

    public Exercise()
    {
        InitializeComponent();
    }

    void InitializeComponent()
    {
        txtFunctional = new MaskedTextBox();

        Controls.Add(txtFunctional);
    }
}

public class Program
{
    static int Main()
    {
        System.Windows.Forms.Application.Run(new Exercise());
        return 0;
    }
}

The masked text box uses the same common characteristics of other visual control: location, size, etc.

Characteristics of the Masked Text Box

 

Introduction

The masked text box uses the same common characteristics of other visual control: name, location, size, background color, border size, anchoring, docking, font, etc. Like the regular text box, the MaskedTextBox class is derived from TextBoxBase that provides its fundamental properties. This means that with the masked text box, you can cut or copy text from it, you can paste text to it, you can measure the length of its text, you can select some part of its text from a specific position to another, or you can select all of its text. Like the regular text box, the masked text box uses the AsciiOnly property, which indicates whether the control should accept or allow only ASCII characters.

The primary reason for using a masked text box is to control short lengths of text entered into it. For this reason, you should not consider some of the multi-line characteristics of a regular text box: word wrapping, scroll bars, the ability to use the Tab key inside the control, etc.

The Mask

Probably the most important property of a masked text box, which sets it apart from the (traditional) text box control, is its ability to control what the user can and cannot enter in the text side. To visually configure this text, the MaskedTextBox class is equipped with a property named Mask:

public string Mask { get; set; }

There are two main ways you can configure it:

Any of these actions would open the Input Mask dialog box:

Input Mask

The Input Mask dialog box provides some of the most regularly used masks in Windows and database applications (the contents of the Input Mask dialog box depends on the language settings of the computer on which you are using Microsoft Visual Studio. For example, the above Input Box is adapted for US English with the US Social Security Number and telephone format). To use an existing mask, you can click it and click OK.

If none of the masks in the list suits you, you can create your own. In the Input Mask dialog box, you can click <Custom>, click the masked text box, create the format, and click OK. Or, in the Properties window for the masked text box, you can click the Mask field and create your mask. To create a mask, you use some characters and combine them as you see fit. The characters you can use are:

Character Used For Placeholder Rule
0 Digit Any single digit: 0, 1, 2, 3, 4, 5, 6, 7, 8, or 9.
9 Digit or Empty Space Any single digit can be entered or an empty space can be left.
# Digit or Empty Space Any single digit, a "+" or a "-" sign can be entered, or an empty space can be left.
L Letter Any letter in either uppercase or lowercase MUST be entered and no empty space should be left. Digits and other non-literals are not allowed.
? Letter Any letter in either uppercase or lowercase can be entered or an empty space can be left. Digits and other non-literals are not allowed.
& Character Any letter, digit, or symbol, or empty space can be used. If the AsciiOnly property is True, this placeholder follows the ? behavior.
C Character Any letter, digit, or symbol, or empty space can be used. If the AsciiOnly property is True, this placeholder follows the & behavior.
A or a Letters and Digits A letter (lowercase and uppercase), a digit, or an empty space is allowed. No special characters. If the AsciiOnly property is True, only a letter is allowed.
> Uppercase Converter A letter in lowercase entered in this placeholder, and any letter in lowercase entered on the right side of this placeholder until the next < or I character, will be converted to uppercase. If the letter is entered in uppercase, nothing would happen.
< Lowercase Converter A letter in uppercase entered in this placeholder, and any letter in uppercase entered on the right side of this placeholder until the next < or I character, will be converted to lowercase. If the letter is entered in lowercase, nothing would happen.
| Conversion Remover Removes the < or > rule set on the left side of this placeholder. This means that, in this placeholder and others on the right side, letters will not be converted but will be kept "as is"
. Decimal Symbol The decimal symbol must be used.
, Thousands Separator The character for the thousands separator, which is the comma in US English, must be used.
: Time Separator The character used to separate the sections of a time value, which is ":" in US English, must be used.
/ Date Separator The character used to separate the sections of a date value, which is "/" in US English, must be used.
$ Currency Symbol The currency symbol, which is $ is US and Canada, will be used
\ Escape Sequence Makes the character follow the escape sequence rules.
  Any Other Character Except for the characters reviewed above, all other characters are kept "as is".

To programmatically specify a mask, create it in a string and assign that string to the Mask property. Here is an example:

public class Exercise : System.Windows.Forms.Form
{
    MaskedTextBox txtFunctional;

    public Exercise()
    {
        InitializeComponent();
    }

    void InitializeComponent()
    {
        txtFunctional = new MaskedTextBox();
        txtFunctional.Location = new Point(12, 12);
        
        txtFunctional.Mask = "999-000-0000";

        Text = "Mask Text Box";
        Controls.Add(txtFunctional);
    }
}

This would produce:

Mask

The Placeholder Character

When you create a mask, to indicate a placeholder for a letter, a digit, or a symbol, the control uses a specific character. The default character is the underscore. If you want, you can use a different character. To support this, the MaskedTextBox class is equipped with the PromptChar property, which is of type char:

public char PromptChar { get; set; }

To change it visually, access the Properties window for the control, click PromptChar and type the desired character. To programmatically specify the character of the placeholders, assign a string to the PromptChar property.

Entering the Wrong Character

When using the masked text box, the user must know the rules to follow based on the mask in the control: dates, telephone numbers, etc. The user must also enter only the allowed characters. If the user enters an invalid character, you can make the computer produce a sound (a beep). To assist you with this, the MaskedTextBox class is equipped with a Boolean property named BeepOnError:

public bool BeepOnError { get; set; }

When this property is set to True, if the user enters an invalid character, the computer produces the beep sound:

public class Exercise : System.Windows.Forms.Form
{
    MaskedTextBox txtFunctional;

    public Exercise()
    {
        InitializeComponent();
    }

    void InitializeComponent()
    {
        txtFunctional = new MaskedTextBox();
        txtFunctional.Location = new Point(12, 12);
        txtFunctional.Mask = "999-000-0000";

        txtFunctional.BeepOnError = true;

        Text = "Mask Text Box";
        Controls.Add(txtFunctional);
    }
}

Also, if the user enters an invalid character in the control, the control fires a MaskInputRejected event, which is carried by a class named MaskInputRejectedEventHandler:

public event MaskInputRejectedEventHandler MaskInputRejected

You can (continuously) use this event to find out whenever the user enters a wrong character so you can provide assistance.

Allowing the Placeholder Character for Input

After creating the control, you can then use it in your application. When the control comes up, it usually shows its placeholders using a specific character. The most regularly used character is the underscore. Put in reverse, the presence of the underscore indicates a placeholder. If you skip a placeholder by pressing the Space bar, an underscore displays in the space you left. This rule also apples for all other characters we reviewed. In some cases, you may want to formally use the character in the placeholder. To illustrate this, consider that you have applied a mask as &&&&&&. When the control comes up, if Fe_GT4, this would be considered as Fe GT4 (with an empty space where the _ was typed). In some cases, you may want the user to be able to enter the character of the placeholder so that Fe_GT4 would produce Fe_GT4. To assist you with this, the MaskedTextBox class is equipped with the AllowPromptAsInput Boolean property:

public bool AllowPromptAsInput { get; set; }

Hiding the Placeholder When Focus is Lost

By default, when the control comes up, it uses some characters, such as _, to show its placeholder(s). This allows the user to know where a character is expected and the number of characters that are expected. After the user has used the control and pressed Tab or clicked another control, the masked text box may still show its placeholders. If you want, you can hide the placeholders when the control looses focus. To assist you with this, the MaskedTextBox class is equipped with a Boolean property named HidePromptOnLeave. The default value of this property is False, which indicates that the control would always show its placeholder(s). Otherwise, you can set this property to true to hide the placeholder character when the control loses focus. Here is an example:

public class Exercise : System.Windows.Forms.Form
{
    MaskedTextBox txtFunctional;

    public Exercise()
    {
        InitializeComponent();
    }

    void InitializeComponent()
    {
        txtFunctional = new MaskedTextBox();
        txtFunctional.Location = new Point(12, 12);
        txtFunctional.Mask = "999-000-0000";
        txtFunctional.BeepOnError = true;

        txtFunctional.HidePromptOnLeave = true;

        Text = "Mask Text Box";
        Controls.Add(txtFunctional);
    }
}

Keeping the Format on Cut and Copy

In some cases, the user can enter less than the number of placeholders in the control. Unlike the regular text box, the user cannot enter characters beyond the number of placeholders. As a class derived from the TextBoxBase class, the masked text box is equipped with a context menu that allows the user to cut, copy, and paste. When the user performs any of these operations, you may want to control whether the mask characters would be included in the cut, copied, or pasted text. To control this, the MaskedTextBox class is equipped with a property named CutCopyMaskFormat, which is based on the MaskFormat enumeration:

public MaskFormat CutCopyMaskFormat { get; set; }

Its members are: ExcludePromptAndLiterals, IncludeLiterals, IncludePrompt, and IncludePromptAndLiterals.

Introduction to the Rich Text

 

Description

Text is considered rich if it can display various characters or paragraphs in different styles and features that make it more attractive than a regular ASCII text. Such a text can have some of its sections in different colors. Its paragraphs can have customized attributes or arranged independent of each other. Although you can create a complete rich but static text, the common use of a rich text is to let the user process most of the formatting.

Creating a Rich Text Control

To support a rich text, the .NET Framework provides the RichTextBox control that is implement from the RichTextBox class. Like TextBox, the RichTextBox class is based on TextBoxBase. Therefore, to have right text in an application, from the Common Controls section of the Toolbox, click RichTextBox and click the form.

To programmatically create rich text, declare a variable of type RichTextBox, use the new operator to allocate memory for it, and add it to the Controls collection of its parent. Here is an example:

using System;
using System.Drawing;
using System.Windows.Forms;

public class Exercise : System.Windows.Forms.Form
{
    RichTextBox rchNote;

    public Exercise()
    {
        InitializeComponent();
    }

    private void InitializeComponent()
    {
        rchNote = new RichTextBox();

        Controls.Add(rchNote);
    }
}

public class Program
{
    static int Main()
    {
        System.Windows.Forms.Application.Run(new Exercise());
        return 0;
    }
}

ApplicationApplication: Starting a Rich Text Application

  1. Start Microsoft Visual Studio
  2. Create a new Windows Forms Application named Notice2
  3. In the Solution Explorer, right-click Form1.cs and click Rename
  4. Type Editor.cs as the new name of the form and press Enter
  5. From the Dialogs section of the Toolbox, click OpenFileDialog OpenFileDialog and click the form
  6. In the Properties window, click DefaultExt and type rtf
  7. Click (Name) and type dlgOpen
  8. Click Filter and type Rich Text Format (*.rtf)|*.rtf|Text File (*.txt)|*.txt|All Files|
  9. From the Dialogs section of the Toolbox, click SaveFileDialog and click the form
  10. In the Properties window, click DefaultExt and type rtf
  11. Click (Name) and type dlgSave
  12. Click Filter and type Rich Text Format (*.rtf)|*.rtf|Text File (*.txt)|*.txt|All Files|
  13. From the Common Controls section of the Toolbox, click RichTextBox RichTextBox and click the form
  14. From the Menus & Toolbars section of the Toolbox, click MenuStrip and click the form
  15. On the form, click Type Here, type File and press Enter
  16. Under File, click Type Here, type New and press Enter
  17. On the right side of File, click Type Here, type Edit and press Enter
  18. Under Edit, click Type Here, type New and press Enter
  19. In the same way, complete the menu strip with the following items:
     
    Notice
  20. Double-click an unoccupied area of the form and change the file 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 Notice2
    {
        public partial class Editor : Form
        {
            string CurrentFileName;
    
            public Editor()
            {
                InitializeComponent();
            }
    
            private void Editor_Load(object sender, EventArgs e)
            {
                CurrentFileName = "<Not Allowed>";
                rchEditor.Modified = false;
            }
        }
    }
  21. Return to the form and click the rich text control
  22. In the Properties window, change the its properties as follows:
    Name: rchEditor
    AcceptsTab: True
    Font: Times New Roman, 12pt
    Dock: Fill
    ScrollBars: Vertical
  23. On the form, click Edit and double-click Undo
  24. Implement the event as follows:
    private void mnuEditUndo_Click(object sender, EventArgs e)
    {
        rchEditor.Undo();
    }
  25. Return to the form
  26. On the form, click Edit and double-click Redo
  27. Implement the event as follows:
    private void mnuEditRedo_Click(object sender, EventArgs e)
    {
        rchEditor.Redo();
    }
  28. Return to the form
  29. On the form, click Edit and double-click Cut
  30. Implement the event as follows:
    private void mnuEditCut_Click(object sender, EventArgs e)
    {
        rchEditor.Cut();
    }
  31. Return to the form
  32. On the form, click Edit and double-click Copy
  33. Implement the event as follows:
    private void mnuEditCopy_Click(object sender, EventArgs e)
    {
        rchEditor.Copy();
    }
  34. Return to the form
  35. On the form, click Edit and double-click Paste
  36. Implement the event as follows:
    private void mnuEditPaste_Click(object sender, EventArgs e)
    {
        rchEditor.Paste();
    }
  37. Return to the form
  38. On the form, click Edit and double-click Select All
  39. Implement the event as follows:
    private void mnuSelectAll_Click(object sender, EventArgs e)
    {
        rchEditor.SelectAll();
    }
  40. Return to the form
  41. Click Format and double-click Word Wrap
  42. Implement the event as follows:
    private void mnuFormatWordWrap_Click(object sender, EventArgs e)
    {
        rchEditor.WordWrap = true;
    }

The Text of a Rich Text Box

 

Introduction

Like the other graphical Windows controls, the right text box uses the common characteristics such as the location, the size, the minimum size, the maximum size, the anchor, the docking, the font, the ability to be visible or hidden, the ability to be enabled or disabled, and the border style. Like the TextBox control, the rich text control inherits various characteristics from the TextBoxBase class, including the Text property, the Lines collection, the read-only attribute, the ability to select and manipulate text. The rich text box also shares various characteristics with the multi-line text box such as the Multiline property, the scroll bars, the word wrap, the ability to accept the Tab and the Enter keys. Here is an example:

private void InitializeComponent()
{
        rchNote = new RichTextBox();
        rchNote.Size = new Size(Width, Height);
        rchNote.Multiline = true;
        rchNote.ScrollBars = RichTextBoxScrollBars.Both;
        rchNote.AcceptsTab = true;
        rchNote.Font = new Font("Verdana", 10.0F);
        string[] strLines =
        {
            "LeavingSydney",
            "When we decided to leave, we knew we were " +
            "making a hard decision. We had spent so much " +
            "time this had become our new home. A few " +
            "weeks or months before, we wanted to make " +
            "Sydney our newly found settlement, a " +
            "permanent place we could proudly call ours. " +
            "It appeared that, unpredictably, fate had " +
            "decided otherwise.",
            "Author: Arthur D. Pale",
            "Title: Stories Of My Life"
        };
        rchNote.Lines = strLines;

        Controls.Add(rchNote);
    }
}

Saving the Contents of a Rich Text Document

After creating and formatting a rich text document, you may want to save it for later use. To support this, the RichTextBox class provides a method named named SaveFile that is overloaded with three versions. One of the versions uses the following syntax:

public void SaveFile(string path);

This method takes as argument the name or path to a file. It will save the file as RTF. If you want the user to save a file that is either RTF, ASCII, or another format, to specify the desired format, you can use the following version of the method:

public void SaveFile(string path, RichTextBoxStreamType fileType);

As seen in the first version, the first argument is the name or path of the file. The second argument allows you to specify the type of file that is being saved, which could be a normal ASCII text. This argument is of type RichTextBoxStreamType, which is an enumeration. The members of the RichTextBoxStreamType enumeration are PlainText, RichNoOleObjs, RichText, TextTextOleObjs, or TextTextOleObjs.

Instead of directly using the name of the file, you can create it as a stream. In this case, the RichTextBox class provides the following version of the SaveFile() method:

public void SaveFile(Stream data, RichTextBoxStreamType fileType);

This version expects a Stream-based object such as a FileStream variable.

Opening a Rich Text File

To assist you with opening a rich text file, the RichTextBox class is equipped with the LoadFile() method overloaded with three versions. The simplest versions has the following syntax:

public void LoadFile(string path);

This method takes as argument the name or path to a file. The file must be in RTF format. If it is not, the file will not be opened and the compiler would throw an IOException exception. If you want to give the user the ability to open different types of files, you should use the following version of the LoadFile() method:

public void LoadFile(string path, RichTextBoxStreamType fileType);

The first argument is the same as a the single argument of the first version. The second argument allows you to specify the type of file that is being opened, which could be a normal ASCII text. This argument is of type RichTextBoxStreamType.

Instead of directly using the name of the file, you can create it as a stream. In this case, the RichTextBox class provides the following version of the LoadFile() method:

public void LoadFile(Stream data, RichTextBoxStreamType fileType);

This version expects a Stream-based object such as a FileStream variable.

ApplicationApplication: Opening a Rich Text File

  1. On the form, click File and double-click New
  2. Implement the event as follows:
    private void mnuFileNew_Click(object sender, EventArgs e)
    {
                // This is the question the user will have to answer
                DialogResult answer = MessageBox.Show(
                        "The document has changed. Do you want to save it?" +
                        "\nClick\n" +
                        "Yes:\tTo save the document and create a new one.\n" +
                        "No:\tNot to save the document but create a new one.\n" +
                        "Cancel:\tNot to do anything",
                        "Editor - Saving a File",
                        MessageBoxButtons.YesNoCancel,
                        MessageBoxIcon.Question);
    
                // When the user clicks File -> New to start a new document,
                // before creating a new document,
                // find out if the document is "dirty" ask the user whether to save or not
                if (rchEditor.Modified == true)
                {
                    // Present the message box to the user who 
                    // will decide whether to save
                    if (answer == DialogResult.Yes)
                    {
                        // If the user answers Yes
                        // Find out if the current document has never been saved
                        if (CurrentFileName == "<Not Allowed>")
                        {
                            // If it has never been saved, then display the Save dialog box
                            if (dlgSave.ShowDialog() == DialogResult.OK)
                            {
                                // Save the file
                                rchEditor.SaveFile(dlgSave.FileName);
                                // Change the current file name to something not allowed
                                CurrentFileName = "<Not Allowed>";
                                // Display Untitled name of the current file on the title bar
                                Text = "Parasol - Untitled";
                                // Since the document has been saved and the user wants 
                                // to create a new one, empty the control
                                rchEditor.Clear();
                                // Update the Modified attribute
                                rchEditor.Modified = false;
                            }
                            else // the user had clicked Cancel, don't do anything
                                return;
                        }
                        else // If the document was saved before, then simply update it
                        {
                            rchEditor.SaveFile(CurrentFileName);
                            // Change the current file name to something not allowed
                            CurrentFileName = "<Not Allowed>";
                            // Display Untitled name of the current file on the title bar
                            Text = "Parasol - Untitled";
                            rchEditor.Clear();
                            // Update the Modified attribute
                            rchEditor.Modified = false;
                        }
                    }
                    else if (answer == DialogResult.No)
                    {
                        // If the user answered No, 
                        // then simply start a new document
                        rchEditor.Clear();
                        // Change the current file name to something not allowed
                        CurrentFileName = "<Not Allowed>";
                        // Display Untitled name of the current file on the title bar
                        Text = "Parasol - Untitled";
                        // Update the Modified attribute
                        rchEditor.Modified = false;
                    }
                    else // If the user clicked Cancel, don't do anything
                        return;
                }
                else // If the document was not modified, then start a new one
                {
                    // If the user answered No, 
                    // then simply start a new document
                    rchEditor.Clear();
                    // Change the current file name to something not allowed
                    CurrentFileName = "<Not Allowed>";
                    // Display Untitled name of the current file on the title bar
                    Text = "Parasol - Untitled";
                    // Update the Modified attribute
                    rchEditor.Modified = false;
                }
    }
  3. Return to the form
  4. On the form, click File and double-click Open
  5. Implement the event as follows:
    private void mnuFileOpen_Click(object sender, EventArgs e)
    {
        // Find out if there was a document and if the document was "dirty"
        if(rchEditor.Modified == true)
        {
                    // Here is the question the user will answer
                    DialogResult answer = MessageBox.Show(
                            "The document has changed. Do you want to save it?" +
                            "\nClick\n" +
                            "Yes:\tTo save the document and open a new one.\n" +
                            "No:\tNot to save the document but open a new one.\n" +
                            "Cancel:\tNot to do anything",
                            "Editor - Opening a File",
                            MessageBoxButtons.YesNoCancel,
                            MessageBoxIcon.Question);
    
                    // Find out if the user wants to save the current document
                    if (answer == DialogResult.Yes)
                    {
                        // Find out if this is a new document
                        if (CurrentFileName == "<Not Allowed>")
                        {
                            // Since the user wants to save the document, display the Save dialog box
                            if (dlgSave.ShowDialog() == DialogResult.OK)
                            {
                                // Save the file
                                rchEditor.SaveFile(dlgSave.FileName);
                            }
                            else
                                return;
                        }
                        else
                        {
                            // This was not a new document,
                            // so, simply save it
                            rchEditor.SaveFile(CurrentFileName);
                        }
                    }
                    else if (answer == DialogResult.No)
                    {
                        // If the user answered No to the question, don't save
                        // Simply open the file
                        if (dlgOpen.ShowDialog() == DialogResult.OK)
                        {
                            // Open the new document after letting the user select it
                            rchEditor.LoadFile(dlgOpen.FileName);
                            // Change the file name of our archives
                            CurrentFileName = dlgOpen.FileName;
                            // Get the name of the file that the user selected
                            FileInfo fleParasol = new FileInfo(dlgOpen.FileName);
                            Text = "Parasol - " + fleParasol.Name;
                            rchEditor.Modified = false;
                        }
                        else
                            return;
                    }
                    else
                        return;
                }
                else
                {
                    if (dlgOpen.ShowDialog() == DialogResult.OK)
                    {
                        // Open the new document after letting the user select it
                        rchEditor.LoadFile(dlgOpen.FileName);
                        // Change the file name of our archives
                        CurrentFileName = dlgOpen.FileName;
                        // Get the name of the file that the user selected
                        FileInfo fleParasol = new FileInfo(dlgOpen.FileName);
                        Text = "Parasol - " + fleParasol.Name;
                        rchEditor.Modified = false;
                    }
                }
    }
  6. Return to the form
  7. On the form, click File and double-click Save
  8. Implement the event as follows:
    private void mnuFileSave_Click(object sender, EventArgs e)
    {
        // Find out if the current document has never been saved
        // but is not empty
        if( (rchEditor.Modified == true) &&
            (CurrentFileName == "<Not Allowed>") )
        {
            // Since the document is dirty, display the Save As dialog box
            if (dlgSave.ShowDialog() == DialogResult.OK)
            {
                        // Retrieve the new name file and display
                        // the file in the rich edit control
                        rchEditor.SaveFile(dlgSave.FileName);
                        // Change/Update the global and complete name of the file,
                        // including its path
                        CurrentFileName = dlgSave.FileName;
                        // Extract the name of the file
                        FileInfo fleParasol = new FileInfo(dlgSave.FileName);
                        // Display the name of the current file on the title bar
                        Text = "Parasol - " + fleParasol.Name;
                    }
                    else
                        return;
        }
        else
        {
            // It appears that this document already had a name
            // but the document was previously modified
            // Therefore, simply save it internally
            rchEditor.SaveFile(CurrentFileName);
        }
    }
  9. Return to the form
  10. On the form, click File and double-click Save As
  11. Implement the event as follows:
    private void mnuFileSaveAs_Click(object sender, EventArgs e)
            {
                if (dlgSave.ShowDialog() == DialogResult.OK)
                {
                    rchEditor.SaveFile(dlgSave.FileName);
                    // Change the file name of our archives
                    CurrentFileName = dlgSave.FileName;
                    // Get the name of the file that the user selected
                    FileInfo fleParasol = new FileInfo(dlgSave.FileName);
                    Text = "Parasol - " + fleParasol.Name;
                    rchEditor.Modified = false;
                }
            }
  12. Return to the form
  13. On the form, click File and double-click Exit
  14. Implement the event as follows:
    private void mnuFileExit_Click(object sender, EventArgs e)
    {
        // Is the document dirty?
        if (rchEditor.Modified == true)
        {
                    // Since the document is dirty, find out if the user wants to save it
                    DialogResult answer = MessageBox.Show(
                        "The document has changed. Do you want to save it?" +
                        "\nClick\n" +
                        "Yes:\tTo save the document and close the application.\n" +
                        "No:\tNot to save the document but close the application.\n" +
                        "Cancel:\tNot to do anything",
                        "Parasol - Saving a File",
                        MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
    
                    // If the user wants to save it
                    if (answer == DialogResult.Yes)
                    {
                        // Behave as if the user had clicked File . Save
                        mnuFileSave_Click(sender, e);
                        Close();
                    }
                    else if (answer == DialogResult.No)
                    {
                        // If the user doesn't want to save the document
                        Close();
                    }
                    // The user cancelled the action: do nothing
                    else
                        return;
    
        }
        else // There is no action to take
            Close();
    }
  15. Return to the form

Rich Text Formatting

 

Formatting Text

We saw that you could change the general font of a text box and you can change the color of the characters. If you do this on a text box, all of the characters are changed to the same font and the same color. One of the extended properties of a rich text box over a regular text box is the ability to change the font and/ the color of individual characters, words, or paragraphs and the change applies only to the desired characters.

Before changing a character or a word, you must first select it. To change the font of the text that is selected on the control, the selected text is identified with the SelectionFont property. To change the color of the text that is selected, the selected text is identified with the SelectionColor property.

To assist you with this, you can use the Font dialog box. After selecting the character or word, you can transfer their attributes to the Font dialog box before displaying it. After using the dialog box, if the user clicks OK, you can retrieve the font and color characteristics then apply them to the selected character or text.

ApplicationApplication: Formatting Text

  1. From the Dialogs section of the Toolbox, click FontDialog and click the form
  2. Click (Name) and type dlgFont
  3. Double-click ShowColor to set its value to True
  4. On the form, click Format and double-click Font
  5. Implement the event as follows:
    private void mnuFormatFont_Click(object sender, EventArgs e)
            {
                // Get the characteristics of the selected text
                // Apply them to the Font dialog box
                dlgFont.Font = rchEditor.SelectionFont;
                dlgFont.Color = rchEditor.SelectionColor;
    
                if (dlgFont.ShowDialog() == DialogResult.OK)
                {
                    // Display the Font dialog box
                    // If the user clicks OK, get the characteristics of the font
                    // Apply them to the selected text of the Rich Edit control
                    rchEditor.SelectionFont = dlgFont.Font;
                    rchEditor.SelectionColor = dlgFont.Color;
                }
            }
  6. Return to the form

The Paragraph Alignment

For a text-based control, a paragraph is a series of words that start with a letter or empty space until the flow of text is interrupted, which is usually made with a carriage return, or the end of the document. By itself, the paragraph controls its alignment and such details as Tab measurements or indentation. To set or change the properties of a paragraph, you must first select it. To select a paragraph, you don't need to formally select it or any portion of its text. As long as the cursor is positioned inside of the paragraph, any paragraph attribute you set or change would apply to the whole paragraph. To manipulate more than one paragraph at the same time, you or your user must select them. The paragraphs do not need to be wholly selected. As long as a section is selected on it, a paragraph is considered selected.

The most common property of a paragraph is its alignment, which states whether the paragraph is positioned to the left, the center, or the right. This characteristic is controlled by the SelectionAlignment property. The SelectionAlignment property is based on the HorizontalAlignment enumeration whose members are Left, Center, and Right. Because this property is applied on (individual) paragraphs, it is not available at design time.

To change the alignment at run time, assign the desired value to the SelectionAlignment property. In the following example, the alignment of the selected paragraph is set in response to the user clicking a button:

private void button1_Click(object  sender, EventArgs  e)
{
        richTextBox1.SelectionAlignment = HorizontalAlignment.Center;
}

Application Application: Aligning a Paragraph

  1. On the form, click Format and double-click Paragraph Align Left
  2. Implement the event as follows:
    private void mnuFormatAlignLeft_Click(object sender, EventArgs e)
    {
        rchEditor.SelectionAlignment = HorizontalAlignment.Left;
    }
  3. Return to the form, click Format and double-click Paragraph Align Center
  4. Implement the event as follows:
    private void mnuFormatAlignCenter_Click(object sender, EventArgs e)
    {
        rchEditor.SelectionAlignment = HorizontalAlignment.Center;
    }
  5. Return to the form, click Format and double-click Paragraph Align Right
  6. Implement the event as follows:
    private void mnuFormatAlignRight_Click(object sender, EventArgs e)
    {
        rchEditor.SelectionAlignment = HorizontalAlignment.Right;
    }
  7. Return to the form

The Indentation of a Paragraph

Indentation is the number of empty characters that separate a paragraph edge from one of the borders of the rich text control. Indentation refers to the left side or the right side of a paragraph. Based on this, left indentation refers to the number of empty characters from the left border of the rich text control to the left edge of a paragraph. The rich text control provides indentation through various properties.

To support indentation from the left side of a paragraph, the RichTextBox class is equipped with a property named SelectionIndent property. To indent from the right side, the RichTextBox is equipped with the SelectionRightIndent property.

Application Application: Indenting a Paragraph

  1. On the form, click Format and double-click Left Indent
  2. Implement the event as follows:
    private void mnuFormatLeftIndent_Click(object sender, EventArgs e)
    {
            rchEditor.SelectionIndent += 10;
    }
  3. Return to the form, click Format and double-click Right Indent
  4. Implement the event as follows:
    private void mnuFormatRightIndent_Click(object sender, EventArgs e)
    {
            rchEditor.SelectionRightIndent += 10;
    }
  5. Return to the form

A Bulleted Paragraph

Instead of just a regular section made only of text, you can create an unordered list of lines or paragraphs in your document. To support this, the RichTextBox class is equipped with a Boolean property named SelectionBullet. If you set this property to false on a paragraph, the paragraph would start with a bullet. If you apply this property to more than one consecutive paragraph, each would start with a bullet.

Application Application: Using a Rich Text Control

  1. On the form, click Format and double-click each button and implement their Click events as follows:
    private void mnuFormatBulletList_Click(object sender, EventArgs e)
    {
            rchEditor.SelectionBullet = true;
    }
  2. Execute the application and test the controls
  3. Close the form and return to your programming environment

Previous Copyright © 2004-2010 FunctionX Next