The RichTextBox is similar to the TextBox, but it has additional formatting capabilities. Whereas the TextBox control allows the Font property to be set for the entire control, the RichTextBox allows you to set the Font, as well as other formatting properties, for selections within the text displayed in the control.
When considering the difference between the TextBox and RichTextBox controls, compare Notepad and WordPad, the two text editors that are included with Windows. Notepad, based on the TextBox control, has no formatting applicable to selections within the text. WordPad, on the other hand, is practically a full-fledged word processor, with such features as bullets, hanging indents, fonts, and character styles applicable to selections within the text.
The default file format for the RichTextBox is the Rich Text Format (RTF), a file format that can carry formatting information.
The RichTextBox control inherits all the properties, methods, and events from the TextBoxBase class, so it behaves much like the TextBox control. In addition, it has many properties, methods, and events specific to itself. Many of the most commonly used RichTextBox-specific properties are listed in Table 12-7.
Property |
Value type |
Description |
---|---|---|
AllowDrop |
Boolean |
Read/write. If true, drag-and-drop operations allowed for the control. |
AutoWordSelection |
Boolean |
Read/write. If false (the default), automatic word selection is disabled. If true, selecting any part of a word in the control causes the entire word to be selected. Note: this can be seen when extending a selection from one word to the next with the mouse, but not if extending the selection with the keyboard. |
BulletIndent |
Integer |
Read/write. Number of pixels to indent text after a bullet character when the bullet style is applied. Default is zero. |
CanRedo |
Boolean |
Read-only. If true, the operations that have been undone can be reapplied. Used in conjunction with the Redo method, described in Table 12-11. |
DetectUrls |
Boolean |
Read/write. If true (the default), the control will automatically detect and format URLs as a link when they are entered in the control. The LinkClicked event allows handling of clicks on the link. |
RightMargin |
Integer |
Read/write. Maximum width, in pixels, of each line of text, measured from the left edge of the control (that is correct, the left edge). Text hitting that margin will be treated as though it had hit the right edge of the control. |
Rtf |
String |
Read/write. The text to be displayed by the control in Rich Text Format (RTF). See the sidebar for a description of RTF. |
ScrollBars |
RichTextBoxScrollBars |
Read/write. Specifies which scrollbars are displayed in the control and under what circumstances. Valid values are members of the RichTextBoxScrollBars enumeration, listed in Table 12-10. |
SelectedRtf |
String |
Read/write. The selected text, including the RTF formatting codes. |
SelectionAlignment |
HorizontalAlignment |
Read/write. Valid values are members of the Horizontal-Alignment enumeration listed in Table 12-8. |
SelectionBullet |
Boolean |
Read/write. If true, the current selection or insertion point will have the bullet style applied. |
SelectionCharOffset |
Integer |
Read/write. Number of pixels that selected text appears above or below the baseline. Valid values can range from -2000-2000. Positive values raise the text above the baseline; negative values lower the text. Default is zero, which puts the text on the baseline. |
SelectionColor |
Color |
Read/write. The color of the currently selected text or the text on the current line. |
SelectionFont |
Font |
Read/write. The Font of the currently selected text or the text on the current line. If selection contains more than one font, the value is null (in C#) or Nothing (in VB.NET). |
SelectionHangingIndent |
Integer |
Read/write. Distance, in pixels, from the left edge of the first line in the paragraph to the left edge of second and subsequent lines in that paragraph. |
SelectionIndent |
Integer |
Read/write. Distance, in pixels, from the left edge of the paragraph to the left edge of the control. |
SelectionProtected |
Boolean |
Read/write. If false (the default), the currently selected text or the paragraph containing the insertion point is not protected. If true, the Protected event is raised if the user attempts to change the current text selection. Will return true only if the entire selection consists of protected text. |
SelectionRightIndent |
Integer |
Read/write. Distance, in pixels, from the right edge of the paragraph to the right edge of the control. |
SelectionTabs |
Integer array |
Read/write. An array of integers in which each member specifies a tab offset, in pixels. |
SelectionType |
RichTextBoxSelectionTypes |
Read-only. Bitwise combination of values from the RichTextBoxSelectionTypes enumeration, listed in Table 12-9. |
ShowSelectionMargin |
Boolean |
Read/write. If true, the control contains a selection margin along the left side of the control. Clicking in the selection margin selects the adjacent line of text; double-clicking selects the entire paragraph. Default is false. |
ZoomFactor |
Float / single (VB.NET) |
Read-only. Measures how fast the application is. Just kidding. Actually, it is read/write, getting or setting the current zoom level when viewing the control. Legal values range from 0.74 to 64.0. 1.0 indicates that no zoom is applied. Works best with TrueType fonts. Non-TrueType fonts use integer values for ZoomFactor. |
Value |
Description |
---|---|
Center |
Aligned in the center of the control. |
Left |
Aligned to the left of the control. |
Right |
Aligned to the right of the control. |
Value |
Description |
---|---|
Empty |
No text in the current selection. |
MultiChar |
More than one text character is currently selected. |
MultiObject |
More than one OLE object is currently selected. |
Object |
At least one OLE object is currently selected. |
Text |
Only text is currently selected. |
Value |
Description |
---|---|
Both |
Displays both horizontal and vertical scrollbars when the text is either wider or longer than the text box. |
ForcedBoth |
Always displays both horizontal and vertical scrollbars. |
ForcedHorizontal |
Always displays a horizontal scrollbar, as long as the RichTextBox WordWrap property is set to false. |
ForcedVertical |
Always displays a vertical scrollbar. |
Horizontal |
Displays a horizontal scrollbar if the text is wider than the text box, as long as the RichTextBox WordWrap property is set to false. |
None |
No scrollbars are displayed. |
Vertical |
Displays a vertical scrollbar if the text is longer than the text box. |
The properties listed in Table 12-7 that begin with the word "Selection," such as SelectionAlignment or SelectionBullet, behave similarly: the property applies to the currently selected text. However, if there is currently no selected text, then it will generally apply to the current text insertion point (the caret) and to all text on that line (from the prior new line character to the next new line character). If text is entered after the insertion point, the property will apply to it, until the property is changed. Some selection properties, such as SelectionFont, do not apply to pre-existing but non-selected text, but only to currently selected text, or text entered at the insertion point.
The listing in Example 12-5 demonstrates many RichTextBox properties using C#. Since this program is lengthy and virtually identical in VB.NET (aside from the normal syntactic differences), only the C# version will be presented in its entirety. Sections of code that are significantly different in VB.NET will be shown. The complete VB.NET source code can be downloaded from http://www.LibertyAssociates.com (click on Books).
This example creates a stripped-down version of WordPad, with a rich text box that fills the form client area and a truncated menu. (Menus will be covered in detail in Chapter 18.) Many properties and menu items used in this example are the same as those demonstrated for TextBox controls in Example 12-1 and Example 12-2. An analysis of the code follows.
When the program is compiled and run, you will get something like Figure 12-3.
Figure 12-3. RichTextBox
Example 12-5. RichTextBox properties in C# (RichTextBoxes.cs)
using System; using System.Drawing; using System.Windows.Forms; using System.IO; namespace ProgrammingWinApps { public class RichTextBoxes : Form { RichTextBox rtxt; public RichTextBoxes( ) { Text = "RichTextBox"; Size = new Size(400, 500); rtxt = new RichTextBox( ); rtxt.Parent = this; rtxt.Text = "Enter text here."; rtxt.Rtf = "{\rtf1\pard Some RTF text.}"; rtxt.Multiline = true; rtxt.BorderStyle = BorderStyle.Fixed3D; rtxt.WordWrap = false; rtxt.ScrollBars = RichTextBoxScrollBars.ForcedBoth; rtxt.Dock = DockStyle.Fill; rtxt.DetectUrls = true; // true is the default value rtxt.AutoWordSelection = true; rtxt.BulletIndent = 10; rtxt.ShowSelectionMargin = true; // Menus // File menu items MenuItem mnuImport = new MenuItem("&Import", new EventHandler(mnuImport_Click)); MenuItem mnuFile = new MenuItem("&File", new MenuItem[ ] {mnuImport}); // Edit menu items MenuItem mnuDash1 = new MenuItem("-"); MenuItem mnuDash2 = new MenuItem("-"); MenuItem mnuUndo = new MenuItem("&Undo", new EventHandler(mnuUndo_Click), Shortcut.CtrlZ); MenuItem mnuCut = new MenuItem("Cu&t", new EventHandler(mnuCut_Click), Shortcut.CtrlX); MenuItem mnuCopy = new MenuItem("&Copy", new EventHandler(mnuCopy_Click), Shortcut.CtrlC); MenuItem mnuCopyRtf = new MenuItem("Copy &Rtf", new EventHandler(mnuCopyRtf_Click)); MenuItem mnuPaste = new MenuItem("&Paste", new EventHandler(mnuPaste_Click), Shortcut.CtrlV); MenuItem mnuDelete = new MenuItem("&Delete", new EventHandler(mnuDelete_Click)); MenuItem mnuSelectAll = new MenuItem("Select &All", new EventHandler(mnuSelectAll_Click), Shortcut.CtrlA); MenuItem mnuSelect5 = new MenuItem("Select First &5", new EventHandler(mnuSelect5_Click), Shortcut.Ctrl5); MenuItem mnuClear = new MenuItem("Clea&r", new EventHandler(mnuClear_Click)); MenuItem mnuEdit = new MenuItem("&Edit", new MenuItem[ ] {mnuUndo, mnuDash1, mnuCut, mnuCopy, mnuCopyRtf, mnuPaste, mnuDelete, mnuDash2, mnuSelectAll, mnuSelect5, mnuClear}); // View Menu items MenuItem mnuScrollToCaret = new MenuItem("&Scroll to Caret", new EventHandler(mnuScrollToCaret_Click)); MenuItem mnuView = new MenuItem("&View", new MenuItem[ ] {mnuScrollToCaret}); // Alignment menu items MenuItem mnuAlignLeft = new MenuItem("Align&Left", new EventHandler(mnuAlignLeft_Click)); MenuItem mnuAlignRight = new MenuItem("Align&Right", new EventHandler(mnuAlignRight_Click)); MenuItem mnuAlignCenter = new MenuItem("Align&Center", new EventHandler(mnuAlignCenter_Click)); // Format Menu items MenuItem mnuBullet = new MenuItem("&Bullet", new EventHandler(mnuBullet_Click)); MenuItem mnuAlign = new MenuItem("&Align", new MenuItem[ ] {mnuAlignLeft, mnuAlignRight, mnuAlignCenter}); MenuItem mnuRed = new MenuItem("&Red", new EventHandler(mnuRed_Click)); MenuItem mnuBold = new MenuItem("Bo&ld", new EventHandler(mnuBold_Click)); MenuItem mnuHang = new MenuItem("&Hanging Indent", new EventHandler(mnuHang_Click)); MenuItem mnuIndent = new MenuItem("&Indent", new EventHandler(mnuIndent_Click)); MenuItem mnuRightIndent = new MenuItem("&Right Indent", new EventHandler(mnuRightIndent_Click)); MenuItem mnuFormat = new MenuItem("For&mat", new MenuItem[ ] {mnuBullet, mnuAlign, mnuRed, mnuBold, mnuHang, mnuIndent, mnuRightIndent}); // Main menu Menu = new MainMenu(new MenuItem[ ] {mnuFile, mnuEdit, mnuView, mnuFormat}); } // close for constructor static void Main( ) { Application.Run(new RichTextBoxes( )); } private void mnuImport_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog( ); ofd.InitialDirectory = @"c:"; ofd.Filter = "RTF files (*.rtf)|*.rtf|" + "All files (*.*)|*.*"; ofd.FilterIndex = 1; // 1 based index if (ofd.ShowDialog( ) = = DialogResult.OK) { try { StreamReader reader = new StreamReader(ofd.FileName); rtxt.Rtf = reader.ReadToEnd( ); reader.Close( ); } catch (Exception ex) { MessageBox.Show(ex.Message); return; } } } private void mnuUndo_Click(object sender, EventArgs e) { if (rtxt.CanUndo = = true) { rtxt.Undo( ); rtxt.ClearUndo( ); } } private void mnuCut_Click(object sender, EventArgs e) { if (rtxt.SelectedText != "") rtxt.Cut( ); } private void mnuCopy_Click(object sender, EventArgs e) { if (rtxt.SelectionLength > 0) rtxt.Copy( ); } private void mnuCopyRtf_Click(object sender, EventArgs e) { if (rtxt.SelectionLength > 0) { Clipboard.SetDataObject(rtxt.SelectedRtf); } } private void mnuPaste_Click(object sender, EventArgs e) { if (Clipboard.GetDataObject( ).GetDataPresent(DataFormats.Text) = = true) { if (rtxt.CanUndo = = true) { if (rtxt.SelectionLength > 0) { if (MessageBox.Show( "Do you want to overwrite the currently selected " + "text?", "Cut & Paste", MessageBoxButtons.YesNo) = = DialogResult.No) rtxt.SelectionStart = rtxt.SelectionStart + rtxt.SelectionLength; } rtxt.Paste( ); } } } private void mnuDelete_Click(object sender, EventArgs e) { if (rtxt.SelectionLength > 0) rtxt.SelectedText = ""; } private void mnuClear_Click(object sender, EventArgs e) { rtxt.Clear( ); } private void mnuSelect5_Click(object sender, EventArgs e) { if (rtxt.Text.Length >= 5) { rtxt.Select(0,5); } else { rtxt.Select(0,rtxt.Text.Length); } } private void mnuSelectAll_Click(object sender, EventArgs e) { rtxt.SelectAll( ); } private void mnuScrollToCaret_Click(object sender, EventArgs e) { rtxt.ScrollToCaret( ); } private void mnuBullet_Click(object sender, EventArgs e) { rtxt.SelectionBullet = !rtxt.SelectionBullet; } private void mnuAlignLeft_Click(object sender, EventArgs e) { rtxt.SelectionAlignment = HorizontalAlignment.Left; } private void mnuAlignRight_Click(object sender, EventArgs e) { rtxt.SelectionAlignment = HorizontalAlignment.Right; } private void mnuAlignCenter_Click(object sender, EventArgs e) { rtxt.SelectionAlignment = HorizontalAlignment.Center; } private void mnuRed_Click(object sender, EventArgs e) { if (rtxt.SelectionColor = = Color.Red) rtxt.SelectionColor = Color.Black; else rtxt.SelectionColor = Color.Red; } private void mnuBold_Click(object sender, EventArgs e) { if (rtxt.SelectionFont.Bold ) rtxt.SelectionFont = new Font(rtxt.SelectionFont, FontStyle.Regular); else rtxt.SelectionFont = new Font(rtxt.SelectionFont, FontStyle.Bold); } private void mnuHang_Click(object sender, EventArgs e) { if (rtxt.SelectionHangingIndent = = 10 ) rtxt.SelectionHangingIndent = 0; else rtxt.SelectionHangingIndent = 10; } private void mnuIndent_Click(object sender, EventArgs e) { if (rtxt.SelectionIndent = = 10 ) rtxt.SelectionIndent = 0; else rtxt.SelectionIndent = 10; } private void mnuRightIndent_Click(object sender, EventArgs e) { if (rtxt.SelectionRightIndent = = 50 ) rtxt.SelectionRightIndent = 0; else rtxt.SelectionRightIndent = 50; } } // close for form class } // close form namespace
The program starts off by declaring a single class member variable, rtxt, representing the RichTextBox control. The equivalent VB.NET line of code would be:
dim rtxt as RichTextBox
In the constructor, both a Text property and an Rtf property are set. However, when you run the program, you will see that only the Rtf property is displayed in the control. If the order of these two lines of code are reversed, then the Text property rather than the Rtf would be visible in the control. Both properties control what is displayed in the control: the Text property assumes plain text and the Rtf property assumes valid RTF formatted text.
Since RTF files use a backslash as a control character, and the backslash character is an escape character in C#, you must double the backslashes before they are properly escaped. Alternatively, you can use an @-quoted string literal in C#, as in:
rtxt.Rtf = @"{ tf1pard Some RTF text.}";
VB.NET does not use the backslash character as an escape character, so the equivalent line of code in VB.NET would be:
rtxt.Rtf = "{ tf1pard Some RTF text.}"
The ScrollBars property is set to ForcedBoth, which causes both a horizontal and vertical scrollbar to be present at all times, even if the contents of the control do not warrant them.
|
The DockStyle property is set to Fill, which forces the rich text box to fill the client area of the form. The DockStyle property was explained in Chapter 7.
The DetectUrls property is set to true, although the line is not strictly necessary, since this is the default value. However, by changing it to false, you can see the different behavior when you enter any valid URL in the control.
The AutoWordSelection property is set to true. This property causes the entire word to be selected if any part of the word is selected.
|
The BulletIndent and ShowSelectionMargin properties work as described in Table 12-7.
The menus are similar to those used in Example 12-1 and Example 12-2, with some additional menu items. The main menu now has File, Edit, View, and Format items. Under File, an Import command lets you import an RTF file. The Edit menu item has an additional command, CopyRtf, which allows you to copy the selected text as RTF rather than plain text. The View menu has only the Scroll To Caret command, while the Format menu is entirely new, demonstrating several of the rich text box formatting capabilities.
The menu item declarations use a different syntax in VB.NET from that in C# for assigning event handlers. A typical menu item declaration looks like:
MenuItem mnuUndo = new MenuItem("&Undo", new EventHandler(mnuUndo_Click), Shortcut.CtrlZ);
dim mnuUndo as new MenuItem("&Undo", _ new EventHandler(AddressOf mnuUndo_Click), _ Shortcut.CtrlZ)
These menu item declarations were described briefly in conjunction with Example 12-1 and Example 12-2 and will be detailed in Chapter 18.
The File Import menu item is handled by the method mnuImport_Click. This method uses the common dialog OpenFile, described in Chapter 6. The equivalent VB.NET version of this method looks like this:
private sub mnuImport_Click(ByVal sender As Object, _ ByVal e As EventArgs) dim ofd as new OpenFileDialog( ) ofd.InitialDirectory = "c:\" ofd.Filter = "RTF files (*.rtf)|*.rtf|" + _ "All files (*.*)|*.*" ofd.FilterIndex = 1 ' 1 based index if ofd.ShowDialog( ) = DialogResult.OK then try dim reader as new StreamReader(ofd.FileName) rtxt.Rtf = reader.ReadToEnd( ) reader.Close( ) catch ex as Exception MessageBox.Show(ex.Message) return end try end if end sub
In either language, a new OpenFileDialog is instantiated and several properties, including InitialDirectory, Filter, and FilterIndex, are set. The dialog is displayed by using the ShowDialog method. If that method returns OK, then the selected file is read into the control by using a StreamReader object. The StreamReader object required that the System.IO namespace be referenced at the beginning of the program:
using System.IO;
imports System.IO
|
The next method of note is mnuCopyRtf_Click, which implements the Edit Copy Rtf command. This method determines whether anything is selected by testing if the SelectionLength property is greater than zero. If so, it uses the static Clipboard.SetDataObject method, passing in the SelectedRtf property as an argument. This property includes the RTF formatting codes, so if the contents are pasted into another control or application, the RTF codes are visible. This is in contrast to the Copy method used in mnuCopy_Click, which copies the selection to the Clipboard directly. If the contents of the Clipboard are pasted into Notepad, it is pasted as plain text, but if pasted into WordPad, it is pasted in with the formatting preserved. To see this concept in action, consider the instance of RichTextBoxes shown in Figure 12-4 with some formatted text entered and selected.
Figure 12-4. RichTextBox with selected text
If the Edit Copy Rtf command is executed and then pasted in WordPad, and then the Edit Copy command is executed on the same selection and then pasted into the same WordPad session, the WordPad session will look like Figure 12-5.
Figure 12-5. WordPad with pasted RTF selections
The Format menu looks like that shown in Figure 12-6. This is hardly a full-featured format menu, but it demonstrates a representative sampling of properties.
Figure 12-6. RichTextBoxes Format menu
Most of these menu items are simple toggles (e.g., if the selection is not bulleted, then bullet it; otherwise, unbullet it). In the case of the SelectionBullet property, which is a Boolean, a single line of code accomplishes the task:
rtxt.SelectionBullet = !rtxt.SelectionBullet;
rtxt.SelectionBullet = not rtxt.SelectionBullet
The Format Red command simply toggles the selection between red and black. The code is slightly more complex:
if (rtxt.SelectionColor = = Color.Red) rtxt.SelectionColor = Color.Black; else rtxt.SelectionColor = Color.Red;
if rtxt.SelectionColor.Equals(Color.Red) then rtxt.SelectionColor = Color.Black else rtxt.SelectionColor = Color.Red end if
|
The Bold, Hanging Indent, Indent, and Right Indent formatting commands are similar to the Red formatting command (which tests to see if the desired property is current and sets the property accordingly).
|
The final formatting commands are the three Align commands: AlignLeft, AlignCenter, and AlignRight. Although these commands are not toggles, apply the appropriate property:
rtxt.SelectionAlignment = HorizontalAlignment.Center;
12.3.1 RichTextBox Methods and Events
As you would expect, the RichTextBox control has several methods and events in addition to those it inherits. Some of the most commonly used methods are listed in Table 12-11, with commonly used events listed in Table 12-16. (Tables Table 12-12 through Table 12-15 contain detailed information about the methods.)
The listing in Example 12-6 demonstrates several of the RichTextBox methods and events using C#. As with the previous example, this program is lengthy and virtually identical to the VB.NET version (aside from the normal syntactic differences). Only the C# version is presented in its entirety. Sections of code that are significantly different in VB.NET will be shown. The complete VB.NET source code can be downloaded from http://www.LibertyAssociates.com (click on Books).
Method |
Description |
---|---|
CanPaste |
Returns true if the data in the Clipboard can be pasted to the control in the specified format, false otherwise. |
Find |
Overloaded. Finds text within the control. If found, highlights the text and returns the zero-based index of the search result, or returns -1 if not found. The overloaded forms are listed in Table 12-12. |
GetCharFromPosition |
Takes a point structure as an argument. Returns the character within the control closest to that point. |
GetCharIndexFromPosition |
Takes a point structure as an argument. Returns the zero-based index of the character within the control closest to that point. |
GetLineFromCharIndex |
Takes a zero-based character index as an argument. Returns the zero-based line number containing that character. |
GetPositionFromCharIndex |
Takes a zero-based character index as an argument. Returns the location of that character. |
LoadFile |
Overloaded. Loads a text file or existing data stream into the control. The overloaded forms are listed in Table 12-14. |
Paste |
Overloaded. Pastes the contents of the Clipboard into the control. The overloaded form takes a DataFormats.Format as an argument, pasting an object of that format. |
Redo |
Reapplies the last operation that was undone. |
SaveFile |
Overloaded. Saves the contents of the control to a file or an existing data stream. The types of files that can be saved are contained in the RichTextBoxStreamType enumeration, listed in Table 12-15. |
Method |
Description |
---|---|
char[ ] |
Searches for first occurrence of a character in character array. Case sensitive. |
string |
Searches for string. Cannot find string if it spans more than one line in the control. Not case sensitive. |
char[ ], int |
Searches for first occurrence of a character in character array starting at a specified position in the control. If the starting index is zero, it searches from the beginning. Case sensitive. |
string, RichTextBoxFinds |
Searches for string with options specified by the bitwise combination of RichTextBoxFinds (listed in Table 12-13). Cannot find string if it spans more than one line in the control. |
char[ ], int, int |
Searches for first occurrence of a character in character array starting at a specified position in the control and ending at a specified position. If the starting index is zero, it searches from the beginning. If the ending index is -1, the search goes to the end. Case sensitive. |
string, int, RichTextBoxFinds |
Searches for string starting at a specified position in the control with options specified by the bitwise combination of RichTextBoxFinds (listed in Table 12-13). If the starting index is zero, it searches from the beginning. Cannot find string if it spans more than one line in the control. |
string, int, int, RichTextBoxFinds |
Searches for string starting at a specified position in the control and ending at a specified position with options specified by the bitwise combination of RichTextBoxFinds (listed in Table 12-13). If the starting index is zero, it searches from the beginning. If the ending index is -1, the search goes to the end. Cannot find string if it spans more than one line in the control. |
Value |
Description |
---|---|
MatchCase |
Casing must match exactly. |
NoHighlight |
If found, search text will not be highlighted. |
None |
Locate all instances, whether whole words or not. |
Reverse |
Start search at end and search to the beginning. |
WholeWord |
Locate only whole words. |
Method |
Description |
---|---|
string |
Loads the RTF file specified in the argument into the control. |
stream, RichTextBoxStreamType |
Loads an existing data stream into the control. The type of the data stream is specified by the RichTextBoxStreamType argument, whose legal values are listed in Table 12-15. |
string, RichTextBoxStreamType |
Loads file into the control. The type of the file is specified by the RichTextBoxStreamType argument, whose legal values are listed in Table 12-15. |
Value |
Description |
---|---|
PlainText |
Plain ASCII text stream with no formatting. OLE objects are replaced with spaces. |
RichNoOleObjects |
RTF stream. OLE objects are replaced with spaces. Only valid for use with the SaveFile method. |
RichText |
RTF stream. |
TextTextOleObjs |
Plain text stream. OLE objects are replaced textual representation. Only valid for use with the SaveFile method. |
UnicodePlainText |
Same as PlainText, except text is encoded as Unicode. |
Event |
Event argument |
Description |
---|---|---|
HScroll |
EventArgs |
Raised when the horizontal scrollbar is clicked. |
LinkClicked |
LinkClickedEventArgs |
Raised when user clicks on a link in the control. Event argument provides a LinkText property. |
Protected |
EventArgs |
Raised when the user attempts to modify protected text. Text is protected by setting the SelectionProtected property true for selected text. The program can perform actions such as warning that this is protected text or provide a dialog for specific formatting. |
SelectionChanged |
EventArgs |
Raised when the selection has changed. |
VScroll |
EventArgs |
Raised when the vertical scrollbar is clicked. |
Example 12-6. RichTextBox methods and events in C# (RichTextBoxMethodsEvents.cs)
using System; using System.Drawing; using System.Windows.Forms; using System.IO; namespace ProgrammingWinApps { public class RichTextBoxMethodsEvents : Form { RichTextBox rtxt; string strFileName; public RichTextBoxMethodsEvents( ) { Text = "RichTextBox Methods & Events"; Size = new Size(400, 500); rtxt = new RichTextBox( ); rtxt.Parent = this; rtxt.Rtf = "{\rtf1\pard Some RTF text.}"; rtxt.Multiline = true; rtxt.BorderStyle = BorderStyle.Fixed3D; rtxt.ScrollBars = RichTextBoxScrollBars.ForcedVertical; rtxt.Dock = DockStyle.Fill; rtxt.AutoWordSelection = true; rtxt.BulletIndent = 10; rtxt.ShowSelectionMargin = true; rtxt.LinkClicked += new LinkClickedEventHandler(Link_Click); rtxt.SelectionChanged += new EventHandler(Selection_Changed); // Menus // File menu items MenuItem mnuImport = new MenuItem("&Import...", new EventHandler(mnuImport_Click), Shortcut.CtrlI); MenuItem mnuLoad = new MenuItem("&Load...", new EventHandler(mnuLoad_Click), Shortcut.CtrlL); MenuItem mnuSaveAs = new MenuItem("Save &As...", new EventHandler(mnuSaveAs_Click)); MenuItem mnuFile = new MenuItem("&File", new MenuItem[ ] {mnuImport, mnuLoad, mnuSaveAs}); // Edit menu items MenuItem mnuFind = new MenuItem("&Find", new EventHandler(mnuFind_Click), Shortcut.CtrlF); MenuItem mnuRedo = new MenuItem("&Redo", new EventHandler(mnuRedo_Click)); MenuItem mnuEdit = new MenuItem("&Edit", new MenuItem[ ] {mnuFind, mnuRedo}); // Main menu Menu = new MainMenu(new MenuItem[ ] {mnuFile, mnuEdit}); } // close for constructor static void Main( ) { Application.Run(new RichTextBoxMethodsEvents( )); } private void mnuImport_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog( ); ofd.InitialDirectory = @"c:"; ofd.Filter = "RTF files (*.rtf)|*.rtf|" + "All files (*.*)|*.*"; ofd.FilterIndex = 1; // 1 based index if (ofd.ShowDialog( ) = = DialogResult.OK) { try { StreamReader reader = new StreamReader(ofd.FileName); rtxt.Rtf = reader.ReadToEnd( ); reader.Close( ); } catch (Exception ex) { MessageBox.Show(ex.Message); return; } } } private void mnuLoad_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog( ); ofd.InitialDirectory = @"c:"; ofd.Filter = "RTF files (*.rtf)|*.rtf|" + "Text files (*.txt)|*.txt|" + "All files (*.*)|*.*"; ofd.FilterIndex = 1; // 1 based index if (ofd.ShowDialog( ) = = DialogResult.OK) { try { // Determine the file extension if (ofd.FileName.EndsWith(".rtf")) rtxt.LoadFile(ofd.FileName); else { if (ofd.FileName.EndsWith(".txt")) rtxt.LoadFile(ofd.FileName, RichTextBoxStreamType.PlainText); else MessageBox.Show("Invalid file format."); } } catch (Exception ex) { MessageBox.Show(ex.Message); return; } } } private void mnuSaveAs_Click(object sender, EventArgs e) { SaveFileDialog sfd = new SaveFileDialog( ); sfd.InitialDirectory = @"c:"; sfd.Filter = "RTF files (*.rtf)|*.rtf|" + "Text files (*.txt)|*.txt|" + "All files (*.*)|*.*"; sfd.FilterIndex = 1; // 1 based index if (strFileName != null) sfd.FileName = strFileName; else sfd.FileName = "*.rtf"; if (sfd.ShowDialog( ) = = DialogResult.OK) { try { strFileName = sfd.FileName; // Determine the file extension if (strFileName.EndsWith(".rtf")) rtxt.SaveFile(strFileName); else { if (strFileName.EndsWith(".txt")) rtxt.SaveFile(strFileName, RichTextBoxStreamType.PlainText); else MessageBox.Show("Invalid file format."); } } catch(Exception ex) { MessageBox.Show(ex.Message); return; } } } private void mnuFind_Click(object sender, EventArgs e) { // use the current selection as the string to find. if (rtxt.SelectionLength > 0) { string str = rtxt.SelectedText; int intStart = rtxt.Find(str, rtxt.SelectionStart + rtxt.SelectionLength, -1, RichTextBoxFinds.None); if (intStart < 0) MessageBox.Show("String not found."); } else MessageBox.Show("Nothing to find."); } private void mnuRedo_Click(object sender, EventArgs e) { if (rtxt.CanRedo) rtxt.Redo( ); } private void Link_Click(object sender, LinkClickedEventArgs e) { System.Diagnostics.Process.Start(e.LinkText); } private void Selection_Changed(object sender, EventArgs e) { if (rtxt.SelectionLength > 0) MessageBox.Show("You have changed the selection to "" + rtxt.SelectedText + """); } } // close for form class } // close form namespace
When the program listed in Example 12-6 is compiled and run, it looks similar to that shown for the previous example in Figure 12-3, except that the menu is sparser and there is no horizontal scrollbar.
The code in Example 12-6 is similar to that listed in Example 12-5.
The constructor has two lines that add two event handlers for LinkClicked and SelectionChanged events, respectively:
rtxt.LinkClicked += new LinkClickedEventHandler(Link_Click); rtxt.SelectionChanged += new EventHandler(Selection_Changed);
AddHandler rtxt.LinkClicked, AddressOf Link_Click AddHandler rtxt.SelectionChanged, AddressOf Selection_Changed
The menu is significantly trimmed down, with only File and Edit top-level menu items, and fewer menu items overall.
As before, most action occurs in the event handler methods. The event handler for importing an RTF file, mnuImport_Click, is unchanged from the previous example. It is left in here simply as a comparison with the Load menu item. The handler for that item, mnuLoad_Click, uses the same OpenFileDialog common dialog, but rather than use a StreamReader to stream the file into the Rtf property of the control, it uses the LoadFile instance method.
Another difference between the Import and Load event handlers is that the Load event handler allows both RTF and text files, reflected in the OpenFileDialog Filter property:
ofd.Filter = "RTF files (*.rtf)|*.rtf|" + "Text files (*.txt)|*.txt|" + "All files (*.*)|*.*";
Then within the try block where the selected file is actually loaded, the string EndsWith instance method determines if the selected file is an RTF or a TXT file. If it is the former, the LoadFile method is invoked with only the filename as an argument. If it is the latter, then the LoadFile method is invoked with RichTextBoxStreamType.PlainText passed as an argument:
try { // Determine the file extension if (ofd.FileName.EndsWith(".rtf")) rtxt.LoadFile(ofd.FileName); else { if (ofd.FileName.EndsWith(".txt")) rtxt.LoadFile(ofd.FileName, RichTextBoxStreamType.PlainText); else MessageBox.Show("Invalid file format."); } } catch (Exception ex) { MessageBox.Show(ex.Message); return; }
try ' Determine the file extension if ofd.FileName.EndsWith(".rtf") then rtxt.LoadFile(ofd.FileName) else if (ofd.FileName.EndsWith(".txt")) rtxt.LoadFile(ofd.FileName, RichTextBoxStreamType.PlainText) else MessageBox.Show("Invalid file format.") end if end if catch ex as Exception MessageBox.Show(ex.Message) return end try
The File Save As command is implemented in the mnuSaveAs_Click event handler method. This is analogous to the Load event handler, except that it uses the SaveFileDialog common dialog box and invokes the SaveFile method rather than the LoadFile method. As with the Load event handler, it tests the extension of the specified filename to determine if the file should be saved as RTF or a plain text file, using the same arguments as the LoadFile method.
Most real-world applications implement a Find function by presenting a dialog box for the user to enter the search string. The Edit Find command implemented in this example forgoes the dialog box and uses the current selection as the search string. If nothing is selected, as determined by testing the SelectionLength property, then the Find method is not invoked.
Assuming there is something selected, the selected text is assigned to a string variable, which is then passed to the Find method, along with several other arguments. Seven overloaded forms of the Find method are listed in Table 12-12, providing the ability to search for either a character or a string, either in the entire control or in a specified range. If it is a string, it uses a combination of RichTextBoxFinds enumeration values, listed in Table 12-13, to refine the search.
In any case, if the search is successful, the Find method returns the zero-based index of the first character of the string that is found. It also highlights the found string. If nothing is found, then the method returns -1.
In this example, four arguments are passed to the Find method: the search string, the starting index, the ending index, and a RichTextBoxFinds enumeration value:
int intStart = rtxt.Find(str, rtxt.SelectionStart + rtxt.SelectionLength, -1, RichTextBoxFinds.None);
dim intStart as integer = rtxt.Find(str, _ rtxt.SelectionStart + rtxt.SelectionLength, _ -1, RichTextBoxFinds.None)
Notice that the starting index is set to the index at the start of the selection plus the length of the selection, which effectively starts the search at the end of the selection. If you started the search at the start of the selection, it would just find itself.
The ending index is set to -1, which has the effect of searching to the end of the control contents. The following line would be equivalent to the line used:
int intStart = rtxt.Find(str, rtxt.SelectionStart + rtxt.SelectionLength, RichTextBoxFinds.None);
Since none of the overloaded forms of the method allows searching for a string from a specified starting point without passing a RichTextBoxFinds parameter, even if there is no refinement to the desired search, the None enumerated value is passed in.
If the search is successful, the found text is highlighted and the character index of the first character of the found string is assigned to the integer intStart. If nothing is found, then -1 would be returned. intStart is tested and if it is negative, a message is displayed.
The Edit Redo menu item demonstrates the Redo method as invoked in the mnuRedo_Click event handler. It first tests the CanRedo property to see if there is anything to redo. If so, the Redo method is called. This has the effect of reversing the previous Undo operation.
|
Two event handlers in Example 12-6 are not associated with any menu item.
The Link_Click event handler is invoked whenever a URL in the control is clicked. This event handler was assigned to the LinkClicked event back in the constructor with the following line:
rtxt.LinkClicked += new LinkClickedEventHandler(Link_Click);
AddHandler rtxt.LinkClicked, AddressOf Link_Click
This event passes an event argument of type LinkClickedEventArgs, which contains the text of the URL that was clicked. This text is then passed as an argument to the Process.Start method of the System.Diagnostics namespace, which starts an instance of the default application for the passed-in link text, which depends on the link. For example, if the link text is www.LibertyAssociates.com, then a browser will be opened and navigate to that web site. If the link text is file:c: est.txt, then that file will be opened in Notepad.
The SelectionChanged event is raised every time the selection is changed in the text box. It is assigned to the Selection_Changed event handler method with the appropriate line of code.
rtxt.SelectionChanged += new EventHandler(Selection_Changed);
AddHandler rtxt.SelectionChanged, AddressOf Selection_Changed
The Selection_Changed event handler first tests to see if anything is selected (i.e., the selection length is greater than zero) to prevent the message box from popping up every time you deselect. Anything that is selected is displayed in a message box.
Windows Forms and the .NET Framework
Getting Started
Visual Studio .NET
Events
Windows Forms
Dialog Boxes
Controls: The Base Class
Mouse Interaction
Text and Fonts
Drawing and GDI+
Labels and Buttons
Text Controls
Other Basic Controls
TreeView and ListView
List Controls
Date and Time Controls
Custom Controls
Menus and Bars
ADO.NET
Updating ADO.NET
Exceptions and Debugging
Configuration and Deployment