Click here to Skip to main content
15,867,686 members
Articles / Desktop Programming / Windows Forms
Article

Persisting Rich Text

Rate me:
Please Sign up or sign in to vote.
4.69/5 (16 votes)
3 Mar 20064 min read 148.8K   2.4K   83   36
Extending the RichTextBox to support form persistance and data binding.

Note: This control is totally standalone. If you've downloaded it before, please do again as I accidenly left some third party references in the demo project.

Introduction

This article was prompted by comments about Rich Parson's RichTextBoxExtended Control. This is a very useful control that includes a tool bar to augment the existing RichTextBox control into a word processor.

Image 1

The comments from users were very positive, but there was a desire to be able to set the content of a rich text control via the Rtf property so it can be persisted in the form design. Secondly, for cases where the content is being edited at runtime, it makes sense to be able to data bind to the Rtf property. This article explains how to do both of these so you can build fully functional Rich Text forms with a minimum of effort.

Minor Changes

I made a few minor changes unconnected with persistence that I hope won't be controversial.

  • I changed the namespace so it has a different name from the control, as this will cause problems with the latest version of C#.
  • I added DefaultValue attributes to all the properties so they don't show up bold unless changed.
  • I introduced a number of additional properties which are self explanatory, such as ToolBarVisible, EditorBackColor, and BorderStyle.
  • I've commented out the properties, allowing direct access to the internal RichText and ToolBar controls, as this breaks the encapsulation, and providing alternative methods for setting the same property is confusing and can cause persistence issues.

Gotyas

When working with the existing RichTextBox control, there are two "features" that can catch you out. Firstly, as mentioned by Rich, if you set Rtf before the form initialization, the RichTextBox control will sometimes lose its formatting and just display plain text. Secondly, there is a bug in the Rtf property where it sometimes returns a null character as the very last character in the string. This causes no problems with designer form persistence when the RichTextBox control has a short content. However, once the content gets longer, the designer serialization code has a nervous breakdown and messes up the job of breaking the string into multiple lines. (Possibly, this is why MS made the Rtf property unavailable as standard in the property editor in Visual Studio.) This caused me more than a little bit of grief but it needn't cause you any if you use the RichTextBoxExtended included with this article.

How to get the Rtf property to work

In order for consumers of the Rtf property to be aware of changes, there needs to be a property change event called RtfChanged. This event will automatically be hooked to handle data binding or form designer serialization.

We must ensure that this event is triggered whenever the content has been updated. The obvious case is when the user has updated the content directly. This, we check in a Leave event handler. The Rtf property may be set directly so we need to trigger our event here also. Finally, Rtf could change indirectly as a result of a change to the Text property.

C#
[Category("Property Changed")]
public event EventHandler RtfChanged;

[
    System.ComponentModel.Description("Contents in Rtf format"),
    RecommendedAsConfigurable(true),
    Category("Data"),
    Bindable(true),
    Editor(typeof(Design.RichTextBoxExtendedEditor), 
           typeof(System.Drawing.Design.UITypeEditor))
]
public string Rtf
{
    get
    {    return rtb1.Rtf;
    }
    set
    {    rtb1.Rtf= value;
        if (RtfChanged!=null)
            RtfChanged(this,EventArgs.Empty);
    }
}
#endregion

private void rtb1_TextChanged(object sender, System.EventArgs e)
{
    if (RtfChanged!=null)
        RtfChanged(this,EventArgs.Empty);
}

private void rtb1_Leave(object sender, System.EventArgs e)
{
    if (this.rtb1.Modified && RtfChanged!=null)
        RtfChanged(this,EventArgs.Empty);
}

Providing a Property Editor for the Rtf Property

There's a pleasing recursion here, as the ExtendedRichText control is used to edit its own Rtf property.

Image 2

Implementing a property editor is accomplished by adding the Editor attribute to the Rtf property. This attribute specifies which UITypeEditor to invoke. The implementation of this UITypeEditor is fairly simple as shown below:

C#
class RichTextBoxExtendedRtfEditor:System.Drawing.Design.UITypeEditor
{
    public override System.Drawing.Design.UITypeEditorEditStyle 
                    GetEditStyle(ITypeDescriptorContext context)
    {
        if (context==null)
            return base.GetEditStyle(null);
        return System.Drawing.Design.UITypeEditorEditStyle.Modal;
    }

    public override object EditValue(ITypeDescriptorContext context, 
                           IServiceProvider provider, object value)
    {
        if (context!=null && provider!=null)
        {
            IWindowsFormsEditorService edSrv= 
              (IWindowsFormsEditorService)
              provider.GetService(typeof(IWindowsFormsEditorService));
            if (edSrv!=null)
            {
                RichTextBoxExtendedRtfEditorForm dialog= 
                  new RichTextBoxExtendedRtfEditorForm();
                if (value is String)
                    dialog.Value= (string)value;    
                if (edSrv.ShowDialog(dialog)==
                         System.Windows.Forms.DialogResult.OK)
                    value= dialog.Value;
                dialog.Dispose();
                dialog= null;
            }
        }
        return value;
    }
}

Data Binding and Automatic Binding

Once persistence of Rtf has been implemented for designer serialization, it will automatically work for data binding. The image of the included demo application shows two RichTextExtended controls - one is read only and is persisted in the form design. The other is editable and is data bound and persisted in a DataSet at runtime. To keep the sample simple to install, this DataSet is persisted in a text file as XML. In a real world application, persistence would probably be to a database and it works fine this way. Just make sure your database columns are large enough as the formatting information makes rich text bigger than you might expect.

A standalone solution (RichTextExtended.sln) has been provided in the demo project. If you use AgileStudio, a solution has also been included (RichTextBoxExtended2.sln) that implements automatic binding. In fact, I used this mechanism to knock together the demo app really quickly.

Conclusion

This modified RichTextBoxExtended now has a property editor to allow you to persist Rich Text as part of the form design. It also supports data binding to allow the editing of Rich Text from a data source at runtime. Now, you can knock together rich text apps without having to hand code your Rtf assignments.

However, if you want to go one step further, the automatic binding in AgileStudio makes it really fly as this automatically builds the SQL Server database and builds the stored procedures, typed datasets, and bindings when you just drop the ExtendedRichText control on the form.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Ireland Ireland
Declan Brennan is Chief Architect for Sekos Technology (www.sekos.com). Over the years he has worked in a huge range of technologies and environments and still gets a great thrill from the magic of computers.

Comments and Discussions

 
Questioncapturing delete key and cut\copy\paste keys Pin
Paul Hildebrandt27-Feb-11 12:10
Paul Hildebrandt27-Feb-11 12:10 
GeneralMy vote of 5 Pin
Amir Mehrabi-Jorshari2-Nov-10 21:01
Amir Mehrabi-Jorshari2-Nov-10 21:01 
QuestionRtf at design-time becomes plain-text at run-time Pin
JohnAndre29-Mar-10 10:18
JohnAndre29-Mar-10 10:18 
AnswerRe: Rtf at design-time becomes plain-text at run-time Pin
Declan Brennan30-Mar-10 6:41
Declan Brennan30-Mar-10 6:41 
GeneralCant get the plain text out from it. Pin
ivanchain@hotmail.com13-Apr-09 6:06
ivanchain@hotmail.com13-Apr-09 6:06 
QuestionHow I Can change color TextLink in RichtextboxEx Pin
Member 472222712-Dec-08 4:17
Member 472222712-Dec-08 4:17 
QuestionWant to send RichTextBox Data via E-mail Pin
salman kazi26-Sep-07 23:24
salman kazi26-Sep-07 23:24 
AnswerRe: Want to send RichTextBox Data via E-mail Pin
Declan Brennan27-Sep-07 0:23
Declan Brennan27-Sep-07 0:23 
QuestionRe: Want to send RichTextBox Data via E-mail Pin
salman kazi27-Sep-07 0:29
salman kazi27-Sep-07 0:29 
GeneralThis needs 3rd party add ons to use Pin
Medmerd16-Mar-07 8:16
Medmerd16-Mar-07 8:16 
GeneralRe: This needs 3rd party add ons to use Pin
Declan Brennan20-Mar-07 3:37
Declan Brennan20-Mar-07 3:37 
GeneralRe: This needs 3rd party add ons to use Pin
JohnAndre29-Mar-10 10:12
JohnAndre29-Mar-10 10:12 
QuestionPrint and Print Preview Contents of RTF Pin
NaughtyZute1-Mar-07 9:50
professionalNaughtyZute1-Mar-07 9:50 
AnswerRe: Print and Print Preview Contents of RTF Pin
Declan Brennan20-Mar-07 3:40
Declan Brennan20-Mar-07 3:40 
GeneralRe: Print and Print Preview Contents of RTF Pin
NaughtyZute20-Mar-07 10:57
professionalNaughtyZute20-Mar-07 10:57 
GeneralBinding as part of a master-detail type setup? [modified] Pin
Jefffarr20-Nov-06 8:28
Jefffarr20-Nov-06 8:28 
QuestionPersisting Rich Text Fails when Databinding Pin
ptemp21-Sep-06 3:52
ptemp21-Sep-06 3:52 
AnswerRe: Persisting Rich Text Fails when Databinding Pin
Declan Brennan22-Sep-06 0:46
Declan Brennan22-Sep-06 0:46 
QuestionHow to add a right click contenMenu to richTextControl? Pin
gafferuk28-Aug-06 13:15
gafferuk28-Aug-06 13:15 
GeneralStop paste images into control Pin
gafferuk28-Aug-06 7:57
gafferuk28-Aug-06 7:57 
GeneralBuilding data from http server Pin
gafferuk27-Aug-06 7:12
gafferuk27-Aug-06 7:12 
Im receiving data from a http server, how do i build up the data prior to applying it to the rich text control?

my code:
string totalResult;
HttpWebResponse objResponse = (HttpWebResponse)objRequest.GetResponse();
using (StreamReader sr =
new StreamReader(objResponse.GetResponseStream()))
{
string totalResult = "";
while ((result = sr.ReadLine()) != null)
{
totalResult += result + "\n";

}
richTextBoxExtended1.Rtf = totalResult.ToString();

}



how do I build the string because using "\n" as a line break is not working.
GeneralRe: Building data from http server Pin
gafferuk28-Aug-06 7:46
gafferuk28-Aug-06 7:46 
QuestionHow to set rtf data? Pin
gafferuk27-Aug-06 3:08
gafferuk27-Aug-06 3:08 
AnswerRe: How to set rtf data? Pin
gafferuk27-Aug-06 7:09
gafferuk27-Aug-06 7:09 
GeneralRTF datatype Pin
cookie king1-Aug-06 5:24
cookie king1-Aug-06 5:24 

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

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