Friday, May 18, 2012

[ C# ] - Using RichTextBox Control

1. Introduction

Just like textbox rich text box also similar kind of control, which accepts text input. What is the difference between typing a three-page document in notepad application and as well as Microsoft word application? Are you piling up the differences? OK. The difference that came in your mind is the difference between the "TextBox" versus "RichtextBox". This means unlike the normal textbox, in the RichTextBox you can mark the piece of the text and set different characteristics like bold/italic, different text colour etc.

You can save and load the content of the RichtextBox into a physical disc in two different formats. One is a "Plain Text (txt format)" format and the other one is "Rich Text Format (RTF format)". In this article, we will have a look at the basic usage of the RichTextBox control.


2. About the RichTextBox Sample

Below is the screenshot of the sample application.



You can type the text content in the left-hand side text area and perform some basic operation on the typed content on the right-hand side of the dialog.

The control on the right side pane is called RichTextBox. This control supports Plain text as well as Rich Text. The Plain text will not have any property like bold text, different colour or even different font. You may ask that the notepad is a utility supplied by windows that support plain text. But, I can change the Font and Font Size. What you should know is that the Font or Font size is applied to the whole document and when you save plain text the change in the font not saved to the disc. That means plain text is still plain text. But, the notepad (text viewer) applied the font change temporarily.

Right, Rich text can hold a variety of properties with them. When you save the rich text those properties also saved in the disc along with the text content. What property I am talking about? Well, its like font colours, Italic, text size etc.

The sample is divided into two panels. The left side panel has the whole area for typing the text contents. Right side panel has the action buttons and using you can perform various operations on the typed content. You can Save and Load the document by clicking the corresponding button on the right-hand side action panel. You can change the text contents by using the controls on section 2 of the panel. At present, you can set Bold, Italic, Underline, Font and Font size to the text contents. But rich text supports more such properties. I have picked those basic ones for demonstration (How do I miss the Colour?!).

The Normal text box supports copy and paste by default (Rich click on it). But rich text box does not provide that function by default. In section 3, you can perform Copy and Paste clipboard operation. Also here you can do Undo and Redo.

Undo will dismiss the effect of your last operation. Say for example you did the following operation (In the same sequence) on the Rich text content:


  1. Typed a line of Texts
  2. Applied a Font for it
  3. Then Changed the Font Size

Now the two consecutive Undo will cancel the effect of Font and Font size in the rich text content. The Redo option will simply cancel the last Undo Operation.


3. Preparing the Form

Two panels are placed on the Form. The first panel is docked to the right of the Form and resized enough to support the buttons and other controls on the right. The left panel is filled to the remaining area of the form. In the Left panel, Rich Text control is placed and Dock property (Richtext) is set to fill. Below are details:


  1. Form Place Holder for the two panels
  2. Left Panel’s "Dock Property" set to "Left" and it holds all the action buttons.
  3. Right Panel’s dock property set to "Fill" and holds only the RichTextBox control
  4. RichTextBox is placed on the Right side panel, and its dock property is set to Fill.

Note that the Right side panel is filled in the remaining portion of the form. The remaining portion is because of the occupation of left side command panel.  The richtextbox fills the entire area of the right side panel.
  

Video Steps


  1. First, a Panel is added to the form. Then it is docked to the right side edge of the form
  2. Then the panel is resized.  This right side panel will have all the command for the rich text box sample
  3. One more panel is added to the left of the command panel.
  4. This panel is asked to fill the remaining area. Later a rich text box is placed inside this Panel.




4. Saving the RichTextbox content

The "SaveFile() Method" of the RichTextBox control allows saving the content of the control in two different formats. One is plain text (.txt) and the other one is Rich text format (.rtf). We will pass the stream type to the above-said method specifying the format in which we want to save the data. The sample used SaveFileDialog to pick a file name and before displaying the dialog the filter types are set to *.txt and *.rtf. Below is the code for saving the content in the Rich text box. The RichTextBox enumeration type RichTextBoxStreamType is set to plain or rich based on the Filter type in the SaveFileDialog.

Below is the code:


//Richtext 01: Save Rich Text file context
private void btnSave_Click(object sender, EventArgs e)
{
    //Richtext 01_01: Create the Save File dialog Instance
    SaveFileDialog saveDlg = new SaveFileDialog();
    string filename = "";

    //Richtext 01_02: Set the Filters for the save dialog.
    saveDlg.Filter = "Rich Text File (*.rtf)|*.rtf|Plain Text File (*.txt)|*.txt"; //Don't include space when when typing *.ext. Because space is treated as extension
    saveDlg.DefaultExt = "*.rtf";
    saveDlg.FilterIndex = 1;
    saveDlg.Title = "Save the contents";

    //Richtext 01_03: Show the save file dialog
    DialogResult retval = saveDlg.ShowDialog();
    if (retval == DialogResult.OK)
        filename = saveDlg.FileName;
    else
        return;

    //Richtext 01_04: Set the correct stream type (Rich text or Plain text?)
    RichTextBoxStreamType stream_type;
    if (saveDlg.FilterIndex == 2)
        stream_type = RichTextBoxStreamType.PlainText;
    else
        stream_type = RichTextBoxStreamType.RichText;

    //Richtext 01_05: Now its time to save the content
    RT.SaveFile(filename, stream_type);
} 

The below video shows saving the Rich Text box content in a Plain text document.

Video Steps


  1. In the Richtext box, a three lines of texts are typed
  2. Then the content of the rich text box is saved in plain text format(.txt)
  3. The saved content is opened with the notepad that understands the plain text format




5. Loading RichTextBox content

The code implemented for loading the saved text look similar to the event handler for save button click. Below are the exceptions.


  1. In place of using the SaveFileDialog, Load Click handler uses the OpenFileDialog.
  2. "LoadFile() Method" of the RichTextBox is called to load the file from the disc.

Below is the Code for Loading the Content.

//Richtext 02: Open the Plain or Rich Text content
private void btnLoad_Click(object sender, EventArgs e)
{
    //Richtext 02_01: Create instance of Open file dialog
    OpenFileDialog file_open = new OpenFileDialog();

    //Richtext 02_02: Setup open file dialog before displaying it
    file_open.Filter = "Rich Text File (*.rtf)|*.rtf| Plain Text File (*.txt)|*.txt";
    file_open.FilterIndex = 1;
    file_open.Title = "Open text or RTF file";

    //Richtext 02_03: Display the dialog and grab the file name
    RichTextBoxStreamType stream_type;
    stream_type = RichTextBoxStreamType.RichText;
    if (DialogResult.OK == file_open.ShowDialog())
    {
        //Richtext 02_04: Set the correct stream type (Rich text or Plain text?)
        if (string.IsNullOrEmpty(file_open.FileName))
            return;
        if (file_open.FilterIndex == 2)
            stream_type = RichTextBoxStreamType.PlainText;
        //Richtext 02_05: Open the content of the selected file
        RT.LoadFile(file_open.FileName, stream_type);
    }
}

Loading already saved content is shown in the below video.

Video Steps


  1. Loads the plain text content saved in the previous video
  2. Shows the loaded content in the richtext box control




6. Setting Bold, Italic and Underline Style to RichTextBox

RichTextBox allows setting the portion of the text in bold, Italic and Underlined. The capability of setting these kinds of attributes makes it different from the normal textbox. Have look at the below piece of code:

Font SelectedText_Font = RT.SelectionFont;
if (SelectedText_Font != null)
    RT.SelectionFont = new Font(SelectedText_Font, SelectedText_Font.Style ^ FontStyle.Bold);

The code shown above changes the selected text (RT: RichTextBox) to Bold style. First, we had taken the Font object of the selected text by making use of the "SelectionFont Property" of the RichTextBox RT. Then a new font is constructed using the existing font returned by the SelectionFont property. During the construction, we used the Bitwise XOR operation (SelectedText_Font.Style ^ FontStyle.Bold) to negate the Bold style. That means if the selected font has bold property set, clicking the Bold again will remove the Bold Style from the Font.
Below is the Full Code for Bold, Italic and Underline.

//Richtext 03: Set Bold, Italic and Underline Styles to the Selection. First get the Font name
//                       from the selection and then apply the specific style.
private void btnBold_Click(object sender, EventArgs e)
{
    Font SelectedText_Font = RT.SelectionFont;
    if (SelectedText_Font != null)
        RT.SelectionFont = new Font(SelectedText_Font, SelectedText_Font.Style ^ FontStyle.Bold);
}

private void btnItalic_Click(object sender, EventArgs e)
{
    Font SelectedText_Font = RT.SelectionFont;
    if (SelectedText_Font != null)
        RT.SelectionFont = new Font(SelectedText_Font, SelectedText_Font.Style ^ FontStyle.Italic );
}

private void btnUnderline_Click(object sender, EventArgs e)
{
    Font SelectedText_Font = RT.SelectionFont;
    if (SelectedText_Font != null)
        RT.SelectionFont = new Font(SelectedText_Font, SelectedText_Font.Style ^ FontStyle.Underline );
}

Video shows applying Bold and Italic to the selected text

Video Steps


  1. Loads already saved plain text
  2. Applies bold, italic and underline style to some portion of the text
  3. Saves the result in Rich text format. (Note plain text won't support text attributes for different portions of the text)
  4. Loads the Rich Text content and checks applied text attributes.




7. Setting Font and FontSize of RichTextBox

It has more work to do. First, we should load the "System Fonts" to combo box shown in the sample app screen shot. Then we should load the "Font Sizes" in another combo box.  Then regardless of whether user changed the combo box selection for Font or FontSize we will re-construct the Font Object and set it to the selected text in the RichTextBox. Since both the combo boxes’ selection changed event does a similar job, we will write a custom function a call that for both the combo boxes.

1) In the Form Load handler, the font families are iterated through the FontFamily Array returned by the "GetFamilies()" static method of "FontFamily Class". The method requires a Graphic object and we get the Graphics object associated to the RichTextBox by calling the function "CreateGraphics()" (Graphics gr = RT.CreateGraphics(); ). Once we have the Font Family name, the name is added to the Font Combo box. Below is the code for it:

//04_1: Get all the Font Family names from the Graphics associated to Rich
//         text box. Then load the font name to combo box
Graphics gr = RT.CreateGraphics();
foreach (FontFamily F_family in FontFamily.GetFamilies(gr))
{
    cmbFont.Items.Add(F_family.Name);
}

2) Numeric values are filled in the Fontsize ComboBox. Below is the code, which does not require any explanation:

//04_2: Load the Font Sizes
for (int fsize = 7; fsize < 73; fsize++)
    cmbFontSize.Items.Add(fsize);

3) The SetNewFont function is written to change the font and font size of the selected text. Below is the Declaration required for the task :

//Richtext 05_01: Declarations that will feed Font Ctor
Font old_font;
Font new_font;
String FName;
float FSize = 8;
FontStyle style = 0;
byte charset = 0;

4) The FSize variable is set with a new font size by reading the currently selected text from the font size ComboBox. When a font size is not specified in the ComboBox, a default font of size 8 is assigned. Also we are storing the current font of the selected text in old_font.

//Richtext 05_02: Grab required information from UI
FName = cmbFont.Text;
if (string.IsNullOrEmpty(cmbFontSize.Text))
    FSize = 8;
else
    FSize = float.Parse(cmbFontSize.Text);
old_font = RT.SelectionFont;

5) Next, we store the font style and GDI Character Set from the existing font. The constructor of the Font class uses all the data that we are collecting here. Below is the Code:

//Richtext 05_03: Treat the situation of no font/selection text
if (old_font == null)
{
    style = FontStyle.Regular;
}
else
{
    style = old_font.Style;
    charset = old_font.GdiCharSet;
}

6) Finally, we construct the Font instance and set that Instance as the current selection font. The function Ends here. Below is the code for it:

//Richtext 05_04: All the parameters for the ctor is ready. Construct the Font
new_font = new Font(FName, FSize, style, GraphicsUnit.Point, charset);
RT.SelectionFont = new_font;

Note that all the information passed to the constructor is either given a default value or collected from the existing font of the selected text.

7) Next, we call the function SetNewFont from both the Combo Boxes "SelectedIndexChanged Event" Handler. Below is the code:

//Richtext 06: Set the font to the selection when either font name or font size changed
private void cmbFont_SelectedIndexChanged(object sender, EventArgs e)
{
    SetNewFont();
}
private void cmbFontSize_SelectedIndexChanged(object sender, EventArgs e)
{
    SetNewFont();
}

Below video shows setting different font and font size to a single line of text in RichTextBox control.


Video Steps


  1. Loads already saved plain text
  2. Select the second line of text
  3. Applies different font and font style
  4. Saves the content and reloads it for a cross check




8. Copy, Paste, Undo and Redo of RichText

1) All the functionality specified in the title is given as member function of the RichTextBox. So the Click event handler on the form for tasks copy, paste, Undo and Redo will simply call the associated member function of the RichTextBox. Below is the code:

//Richtext 07: Other baisc functionality of Richtext box
private void btnCopy_Click(object sender, EventArgs e)
{
    RT.Copy();
}
private void btnPaste_Click(object sender, EventArgs e)
{
    RT.Paste();
}
private void btnUndo_Click(object sender, EventArgs e)
{
    RT.Undo();
}
private void btnRedo_Click(object sender, EventArgs e)
{
    RT.Redo();
}

private void btnClear_Click(object sender, EventArgs e)
{
    RT.Clear();
}

Below video shows the Clipboard Operation on Rich Text. It also shows the use of Undo and Redo option on Richtext

Video Steps


  1. Copies #using statements from Source file
  2. Then passes the content to the rich text box
  3. From the posted content copies some portion of text to clipboard
  4. Opens the WordPad application and pastes it
  5. Finally applied some attributes and shows the undo and redo options




Source Code : Download

No comments:

Post a Comment

Leave your comment(s) here.

Like this site? Tell it to your Firend :)