.NET Building Blocks: Build a RichTextBox-Based Syntax-Highlighting Editor and IDE : Page 3
By using the RichTextbox as a base control, you can build an editor that highlights keywords and quoted strings—or even an editor that employs IDE-like smart indentation and runs script code interactively.
by Michael Sorens
Aug 1, 2007
Page 3 of 6
Get Under the SyntaxHilightTextBox's Covers
You can leverage a lot more power from the SyntaxHilightTextBox. First, consider the base class itself, the RichTextBox. I am sure that Microsoft has included details on the user interface somewhere in the RichTextBox documentation, but I have yet to find it. What I have gleaned from experimentation is that the RichTextBox control (and probably other Form controls) use most or all of the keystrokes common in most Windows applications. Table 1 lists these keystrokes and how the control reacts to them:
Table 1: RichTextBox Control Keystrokes: The table contains a list of common Windows keystrokes and a short description of how the control reacts to each.
Copies the selected text to the copy buffer.
Pastes text from the copy buffer to the cursor position.
Cuts the selected text, adding it to the copy buffer.
Advances to the next line in the control.
Advances the focus to the next control (that is, this control loses focus).
Move to the beginning of the line.
Move to the end of the line.
Move to the beginning of the text.
Move to the end of the text.
Move to the beginning of the window.
Move to the end of the window.
Scroll the window up one page.
Scroll the window down one page.
Move forward one character.
Move backward one character.
Move forward one word.
Move backward one word.
Position the cursor at the mouse position.
Select the word under the mouse pointer.
Select the line under the mouse pointer.
Shift in conjunction with movement keys extends the current selection.
Figure 12. Underlying RichTextBox Capabilities: The base class handles rich text, so stylized text retains its styling when pasted. The control's syntax-highlighting feature adds the color to pasted text automatically.
Note that the control does not operate on plain text, but on rich text. That means you could create text with a different size and different fontin Word, for exampleand then paste it into the control (see Figure 12), without losing the font and size settings. The control does not expose specific keystrokes to manipulate fonts, but it exposes properties that allow you to do so after you instrument your code appropriately. Also, with suitable code, you could load an RTF file into the control.
You can use the control to create a basic word processor, then, with little coding. How fancy you make it is up to you. The SyntaxHilightTextBox adds some additional built-in features and keystrokes to make it even easier for you to make a powerful user interface. Table 2 lists the additional keystrokes; I'll provide details on the operations in the table a little later in this article.
Table 2: SyntaxHilightTextBox Keystrokes: In addition to the keystrokes handled by the RichTextBox, the SyntaxHilightTextBox handles these keystrokes useful for code editing.
Comment the current selection.
Uncomment the current selection.
Shift the current selection to the right by adding a tab to the start of each line.
Shift the current selection to the left by removing a tab (or spaces) at the start of each line.
Reapply syntax highlighting.
Insert a tab character (or tab-equivalent spaces).
Increase the font size of the current selection.
Decrease the font size of the current selection.
In addition to supplementing the keystrokes the control handles, the SyntaxHilightTextBox also exposes properties that let you customize the control's behavior (see Figure 8). Here's a description of each public property.
AutoHilight. This Boolean property determines whether the control applies highlighting as users type. Because users are free to arbitrarily change content anywhere in the text box, either by typing or by cutting and pasting, I chose to re-highlight everything on any change. That might sound like a lot of overhead, but it executes nearly instantaneously. Instant highlighting has one drawback though, which is why this property is exposed to allow you to turn it on or off: The control adds highlighting to the queue of processed items just like any other overt user action, meaning that it includes every highlighting action in the list of things you can undo with the undo command (control-Z). Practically speaking, that makes the undo command almost useless when AutoHilight is turned on. You may want to give users a button or menu toggle to let them decide whether to use it. The default value of the Autohilight property is false.
RefreshDelay. This property is closely related to the AutoHilight property. The RefreshDelay property specifies the time to wait after the user pauses typing before invoking the automatic re-highlighting operation (if enabled). This value is specified in milliseconds. The default value is 500 milliseconds.
Figure 13. Two Comment Types: Both end-of-line comments (marked with "//") and closed comments (marked with "/*" and "*/") are illustrated here.
ClosedCommentStartMark, ClosedCommentEndMark, and EndOfLineCommentMark. These three properties are closely related. The first two work together to define what I call a closed comment. The similar EndOfLineCommentMark property defines the other type of comment, an end-of-line comment. Closed comments require a starting mark and an ending mark, and may span multiple lines. End-of-line comments require only a starting mark and terminate at the end of the line. The C# code in Figure 13 illustrates both types of comments. Note that code may continue after a closed comment, whether the comment occupies all or a portion of one or multiple lines. For an end-of-line comment, there is no closing character; the end-of line provides an implicit closing character. The defaults are /* and */ for closed comments, and // for end-of-line comments.
QuoteChars. This string property lets you specify zero, one, or multiple characters that may delineate a string constantone of the element types highlighted by the control. A matching pair of any specified character delineates a string; the user may not mix different characters to delineate a single string. The property defaults include both single and double quote characters.
KeywordColor, CommentColor, and QuotedColor. These three properties specify the colors of the three highlighted element types: language keywords, comments, and quoted string constants. The default colors are blue, green, and fuchsia, respectively.
ExpandTab. This Boolean property specifies whether to insert spaces (true) or tabs (false) during tab-related operations. There are two such operations available: the Ctrl-Enter key combination adds a tab (or the equivalent number of spaces), and right-shifting a text block adds either tabs or spaces. By default (false), the control adds tabs.
TabSize. Closely allied with the ExpandTab property, TabSize specifies the number of spaces to equate to a tab when ExpandTab is true. Conventionally, you may be used to a tab occupying eight spaces, but values of four and two are quite common as well. The default is four.
SelectedOrAllText. You can programmatically obtain all the text in a standard RichTextBox via the Text property, or a user-selected subset via the SelectedText property. But in a query browser or a script development tool, users are likely to want to operate on the entire contents of the container at some times, or just the selected portion at other times. A reasonable course of action, then, is to assume that if some text is selected, act on that; if not, then use all the text. The SyntaxHilightTextBox provides the aptly named SelectedOrAllText property that returns precisely that. You can look at the query browser sample program to see how it uses this property. There is no default for this property.