Click here to Skip to main content
Click here to Skip to main content

RichTextLabel WinForms Control

, 22 Mar 2004
Rate this:
Please Sign up or sign in to vote.
Embedding and displaying RTF resources to tweak the UI of an application easily and efficiently.

The article assumes that you're familiar with Visual Basic .NET and the Visual Studio .NET Windows Forms designer.

Introduction

A couple of weeks ago, I've had a busy weekend working on a soon-to-be-released .NET component. The feature I was working on was a nag dialog that the evaluation version of the component should display occasionally. Obviously, I wanted the dialog to show up quickly and also to look attractively. I also wanted to be able to display an active hyperlink that would take the user to the product's site when clicked.

Another possible example needing a similar functionality might be an 'About' dialog box. (I've seen a couple of 'About' dialogs containing just plain text, even with non-clickable homepage and 'purchase' hyperlinks). Splash screens could also have been more attractive displaying program information (name, version number...) in distinct fonts and colors, for example.

Details

Or, consider the various 'TIP:' labels scattered throughout dialog boxes in some applications. More often than not, decent formatting could have improved readability and thus the usability of the dialog. Let's go back to my nag dialog. As I said, I wanted to use formatted text and graphics to make it look nice and "cool". I've considered the following possible implementation options:

1. Several differently formatted Label and LinkLabel controls.

I've abandoned this option quickly, because the formatted text should appear as "flowing" and I wasn't able to layout the differently formatted labels correctly.

2. Third-party HTML rendering controls.

I've found a couple of ActiveX controls, but I didn't want to introduce any additional dependencies (and the interop overhead), so I didn't research the controls further.

3. Hosting the WebBrowser control.

This is an ActiveX control, so it suffers from the same drawbacks as the previous approach. It's also too slow for the purposes of my nag dialog.

4. The RichTextBox control.

The control supports text formatting and embedded graphics. It has also the DetectUrls property meaning it can underline properly formatted URLs, display the 'hand' cursor when an user hovers the mouse over the link and it can also raise the LinkClicked event when the link is clicked. The event can be handled with a small amount of code to show the URL in the user's browser.

In addition, by setting a couple of the control's appearance properties, it could be made to look and act like a non-editable, formatted label. And the control's display performance is really good.

For me, RichTextBox was a clear winner.

After deciding to use the RichTextBox, I've created an RTF file with the text for my nag dialog (I've used the good ol' WordPad to do this). I've added the RTF file to the component's project and marked it as an embedded resource:

I've added code to load the RTF text into the RichTextBox.Rtf property from inside the nag dialog Load event handler, which was rather easy:

' Get a reference to this type's assembly.
Dim Assm As [Assembly] = Me.GetType().Assembly

' Open the required resource and load the RTF text from it.
Dim RtfStream As System.IO.Stream = Assm.GetManifestResourceStream(
    "NagDialog.NagDialogText.rtf")
Me.RichTextBox1.LoadFile(RtfStream, RichTextBoxStreamType.RichText)
RtfStream.Close()
The stream returned from the Assembly.GetManifestResourceStream is simply passed to the RichTextBox.LoadFile method.

The Assembly.GetManifestResourceStream method requires a resource name in the form <Namespace>.<FileName>, where <Namespace> is the project's root namespace and <FileName> is the actual file name (as it appears in the Solution Explorer). Please bear in mind that the resource name is case sensitive.

I wanted the nag dialog to display the same product information that was already embedded into the assembly's manifest as attributes (i.e. AssemblyProductAttribute, AssemblyCompanyAttribute, etc.). In order to do that, I've used substitution strings inside the RTF text. After loading the text, I've replaced the substitution strings with the actual attribute values, for example:

Dim Attrs() As Object = Assm.GetCustomAttributes(
    GetType(AssemblyTitleAttribute), False)
If (Not Attrs Is Nothing) AndAlso (Attrs.Length > 0) Then
  Me.RichTextBox1.Rtf = Me.RichTextBox1.Rtf.Replace("[0]", 
    DirectCast(Attrs(0), AssemblyTitleAttribute).Title)
End If
My first attempt was to use substitution strings with curly braces (e.g. "{0}"), suitable for passing to the String.Format method. However, I've quickly realized that this approach won't work with RTF-formatted text, because curly braces have special meaning in RTF (they're are used to enclose RTF groups). The only other "forbidden" character is the backslash "\" character, so anything else can be used.

The other thing to watch out when using string substitution in RTF is to make sure that the whole substitution string doesn't contain different formatting. Otherwise the string will get escaped in the RTF text and you won't be able to replace it. For example, if you enter "(0)" as a substitution string with the closing brace formatted as bold, you'll get "(0\b )" as a result.

Let's recap quickly what you have to do in order to use RTF in a Form using the described technique:

  1. Write the RTF text in your RTF editor of choice (WordPad works quite well; Word adds too much overhead). Don't forget to add substitution strings for the product information that will be loaded from the assembly.
  2. Add the RTF file to your project and mark it as embedded resource (set the Build Action property of the file to 'Embedded Resource').
  3. Place a RichTextBox control on your dialog and set its properties that will make it look like a label (colors, TabStop, etc.).
  4. Write code to load the RTF into the RichTextBox control and to do the substitutions along the way.

It's quite boring, error prone work, so I've encapsulated the technique into an easy-to-use control - the RichTextLabel control:

The control is intended for reuse in source form. The accompanying solution contains both, the VB.NET version as well as the C# version of the control. The RichTextLabel control exposes just one, all important RtfResourceName property. You'll need to set the property to the name of the RTF text resource you wish to display in the control. Everything else is done automatically.

In order to use the RichTextLabel control within your project, you'll have to follow these steps:

  1. Add the RichTextLabel.vb or RichTextLabel.cs source file to you project and recompile. The RichTextLabel control is derived from UserControl, so it will be added to the Visual Studio .NET toolbox automatically.
  2. Add an RTF file to your project and set its build action to 'Embedded Resource'. You can have the following substitution strings in the file:
  3. Substitution String Replaced by this property's value
    [Title]AssemblyTitleAttribute.Title
    [Product]AssemblyProductAttribute.Product
    [Copyright]AssemblyCopyrightAttribute.Copyright
    [Company]AssemblyCompanyAttribute.Company
  4. Place the RichTextLabel control onto a Form and set its RtfResourceName property to the name of the RTF file you've added in step 2.

In order to make things easier for you, the RtfResourceName property has an associated type editor (RtfResourceNameEditor), which displays a popup list of all the RTF resource files available in the current assembly (see the image at the top of the article).

In order to keep the RichTextLabel control as small as possible, I've put the type editor in a separate LaMarvin.Windows.Forms.RichTextLabel.Design.dll assembly that needn't be directly referenced by the project containing the RichTextLabel control. If you want to take advantage of the richer design-time support, just copy the LaMarvin.Windows.Forms.RichTextLabel.Design.dll assembly to your project's output directory.

If you'd like to edit the RTF files added to your project comfortably from within the Visual Studio .NET IDE, you might want to associate the .RTF file extension with WordPad. Right-click on any RTF file in the Solution Explorer and select the "Open With..." command. In the Open With dialog box, add WordPad.exe to the list of available programs and set it as the default editor for .RTF files. After that, double-clicking an RTF file in the Solution Explorer will open the file in WordPad automatically.

History

  • Saturday, March 20, 2004 - Published.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

palomraz
Web Developer
Slovakia Slovakia
I live in Slovakia with my wife, two sons and two daughters. I've been doing Microsoft Windows development since 1988; primarily in VB. I'm a big fan of the MS .NET framework, publisher of the www.vbinfozine.com ezine and the author of components found at www.lamarvin.com.

Comments and Discussions

 
Questionread rtf from string PinmemberChris Anders7-Jun-14 1:07 
GeneralMy vote of 1 Pinmemberb0bi13-Aug-12 23:55 
GeneralA bug with embedded links Pinmemberjeffb4218-Apr-10 20:41 
GeneralRe: A bug with embedded links Pinmemberpalomraz7-May-10 6:39 
GeneralDoing the same in compact framework PinmemberOkyn18-Jun-07 22:29 
GeneralRe: Doing the same in compact framework Pinmemberpalomraz20-Jun-07 9:28 
GeneralVS2005 VB version error reading rtf file Pinmembera9192shark29-May-07 23:01 
GeneralRe: VS2005 VB version error reading rtf file Pinmemberpalomraz31-May-07 23:53 
GeneralRe: VS2005 VB version error reading rtf file Pinmembera9192shark1-Jun-07 5:24 
GeneralDesign time properties PinmemberBindu_Sharma20053-Aug-05 1:23 
GeneralRe: Design time properties Pinmemberpalomraz4-Aug-05 3:24 
GeneralCompliments &amp; Question Pinmemberdamian_jay3-Jun-05 23:13 
GeneralRe: Compliments & Question Pinmemberpalomraz8-Jun-05 6:11 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140721.1 | Last Updated 23 Mar 2004
Article Copyright 2004 by palomraz
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid