Some RichTextBox tricks

I have
recently been responsible for refactoring the Code Query Language
query editor in NDepend
to fix some imperfections.

 

 

 

The CQL
query editor implementation is based on a class derived from the System.Windows.Controls.RichTextBox
class. It was the opportunity to learn some tricks that I would
like to share in the current post.

 

Text Coloring

If you
google how to color the text displayed in a RichTextBox, you’ll certainly end up using the coloring selection
trick, using the RichTextBox method Select() and properties SelectionColor, SelectionBackColor:

 
Using a search
engine is very misleading here. We end up to the conclusion that this approach
comes with extremely bad performance, even on short text with just dozens of word to color.

 

A much
better way we found is to use the Rtf /
Rich Text Format

capabilities of the RichTextBox. You
just need to format a rtf string and use this code:

 

I won’t
detail the Rtf format here. The Rtf string for the query above looks like:

 

Notice that
using the SelectedRtf property is
also a good way to prevent improper formatted text copy/pasted from Microsoft Word or a Browse for example.

 

Avoid flickering problem

When you update
the content of your RichTextBox, you’ll
certainly notice some pesky flickering. Hopefully, an efficient
solution to this problem can be found here.
Basically the solution consists in disabling text redrawing by calling some
win32 APIs:

 

Testing for ScrollBars’
visibility

After
looking for a way to test if the RichTextBox’s ScrollBars are visible or
not, the only way I found is to infer this information from the delta between this.ClientRectangle and this.Size. This is certainly not the cleanest
way but it is working well in every context I tried:

 

Get/Set the ScrollBars’
positions

To achieve this I came to the conclusion that it must be done throught the good-old win32.
Being able to get and set the ScrollBars’ positions is especially useful to
avoid some pesky automatic RichTextBox content re-locating I notice in some
circumstances, such as inserting or modifying a long text. Here is the code:

 

Url Detection

Something
that I wasn’t aware: if you want to display Urls that can be clicked in
your text box, just set the RichTextBox.DetectUrls
property to true. You can then use the RichTextBox.LinkClicked
event to handle the url click.

 

 

This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • John Price

    Hi

    I think that

    if ((GetWindowLong((HWND)rtli->hWndRichText, GWL_STYLE) & WS_VSCROLL) != 0)
    {
    //Rich text is showing its vertical scroll bar
    }
    will detect scrollbar visibility

  • elielCT

    Dude u R da man! lol..
    After searching for ways to detect scrollbar visibility u put me on da right path i needed..

    i came up with this:
    Dim rect As New Rectangle
    rect = myRichTextBox.ClientRectangle

    If rect.Height < 40 Then
    ……….. ' Something happens
    End If

    As my rectangle starts with a height value of 40… When scrollbars appear it drops to 23.. So simple and stupid, i shoulda thought of this.. lmfao…

  • Kabar

    Just thanks! Very usefull.

  • http://www.blakerobertson.com Blake Robertson

    Just wanted to say thanks. I used your VScrollVisible trick in a AutoScalingRichTextBox control which has methods to make the font as large as possible in the given bounds of the control.

    I linked to this page here:
    http://stackoverflow.com/questions/791830/autoscale-font-in-a-textbox-control-so-that-its-as-big-as-possible-and-still-fits

  • Alejo

    Wich is the order of position of this Code in a operation of coloring?

  • Gowdhaman

    Good Collection… Resource of Rich Text Box

  • http://www.interfacingreality.blogspot.com/ Yann Trevin

    Thanks for the tips. I have been already disapointed in the past by the limitations of the RichTextBox control support in winform, although the capabilities of the control itself are amazing And I am generally relunctant on using P/Invoke on non hardware or driver related stuff. But except by using a web container control, there is indeed not too many other choices. Thank you for sharing the info.