Microsoft and Apple Training

This article -proudly- presents a WPF control that displays rich text from an HTML source: it has a Text dependency property that you can bind to a HTML-formatted string. It's designed to display -not edit- rich information messages like warnings, error messages, and other feedback e.g. from a localizable resource file. Here are a couple of examples, on the left side is the original HTML, on the right side is how it's displayed by the control:

Formatting:

Font sizes:

Colors:

Some issues with WPF's native RichTextBox control.

The HtmlTextBlock control is based on WPF's native RichTextBox control. This was not an obvious choice, since RichTextBox was actually designed as an editor control: by typing in the box and pressing toolbar buttons, a FlowDocument is created and displayed. This FlowDocument is accessible through the Document property, which unfortunately is

very complex to manipulate, compared to a formatted HTML or XAML string (you can't store it in a resource file), and

not a dependency property.

On the other hand, the FlowDocument has powerful text formatting features, so it really makes sense to try to leverage these.

Making a bindable RichTextBox

If you grab your favorite search engine and type "WPF Bindable RichTextBox" you'll find plenty of implementations. This one on CodePlex nicely explains the problems ànd solutions. Basically all you need to do is write a dependency property that is wrapped around the RichtTextBox' FlowDocument whilst converting it to and from a XAML-formatted string. Here's how this process looks like in code:

From TextBox to TextBlock

Since my control is a display panel instead of an edit box, I had to tweak the code in several places. Some extra properties were set in the constructor:

public RichTextBox()

{

Loaded += RichTextBox_Loaded;

//Added

this.IsReadOnly = true;

this.Focusable = false;

}

The original CodePlex control was not 100% percent bindable to a source: it was just Initializable from a source. After the source provided the initial value, all other updates were ignored. That was not compatible with my requirements: I wanted to bind the control to a dynamic value, like changing status information or an on-the-fly-localizable message. So I removed the code that inhibited long-term binding: the definition and all references and manipulation of the _textHasLoaded variable. Now the control does more, with less code.

All you need to do is bind the textbox to its source:

<uc:RichTextBox

Text="{Binding Message}"

</uc:RichTextBox>

And on every update of the source, the displayed text will also be updated:

this.Message = "The report was sent to <b>your local printer</b>.<br/><br/>Press <u style='color:red'>Enter</u> to continue or <u style='color:red'>Back</u> to print again.";

Here's the result:

Converting HTML to XAML, and back

The native WPF RichTextBox nicely displays plain text, RTF, and XAML, but no HTML. Fortunately a lot of attempts were already made to convert HTML into XAML and back. The code I'm currently using comes from MSDN. Its probably not the world's best converter, but it simply does what I was looking for: formatting (bold, italic, underline, size, color, and line breaks). It's not the best solution if you want to properly display tables, lists, headers and so. A more powerful convertor can be found on CodePlex in the HTML 2 RTB XAML project, which in its turn is based on HTML Agility Pack. Unfortunately the conversion code in the former project is tightly coupled to (Silverlight) controls. I didn't have the time to refactor this. (Take that as a hint )

Making the RichTextBox understand and speak HTML

The RichTextBox from the Extended WPF Toolkit -again from CodePlex- not only has a Text dependency property for data binding. It also introduces the concept of Text Formatters, allowing to declaratively and programmatically specify the format of the content. The three canonical Text Formatters are included; PlainTextFormatter, RtfFormatter, and XamlFormatter.

All I did was taking the code of the XamlFormatter and plugged in the Html converter. I also replaced the ASCII encoding by UTF8 encoding, since French text wasn't displayed correctly.

Yevgeniy

Apurva

Your control is very nice, the only problem I am having is that when the RichTextBox is part of a DataTemplate, it stops rendering the text as Html.

Any suggestions?
Thanks

yasin

2/22/2012 7:35:24 PM |

tank you for this paper.

so we use html,css for desing wpf ??

Eze

4/2/2012 6:50:55 AM |

Someone can make it work inside a DataTemplate?

Hicham

10/12/2012 10:45:50 AM |

Thanks for the control, very nice work.
As workaround for the DataTemplate rendering problem, you can set the HtmlFormatter as default Formatter in the TextFormatter Property.

Hicham

Birki

10/15/2012 11:22:09 PM |

Is this open source i.e. GPL or LGPL?

Diederik Krols

10/17/2012 9:06:38 PM |

@Birki: this is just a blog article. You're free to use the code you find here.

Hari

10/23/2012 8:14:55 PM |

Is it possible modified tag <u> for underline text , give it a space between word and underline ? What can i do for that ?

Thanks.

Matt

12/17/2012 1:34:45 AM |

Nice work, the only thing that makes the whole work in one snap bad ->

<B>bla<b
blabla

Will crash the whole thing, cause of non closed brackets

Daniel

2/6/2013 8:57:27 PM |

Hi,

Lovely work. Thank you.

I changed the constructor of the RichTextBox to make 'this.Focusable = true', instead of false. I wanted the text in the RTB to be selectable and this now allows that. If you think this will blow up in my face and you ever notice this comment, and you have a spare moment, then let me know!

Regards,

Daniel

César F. Qüeb

4/19/2013 6:14:08 AM |

Congratulations for this amazing article, really useful and appreciated. Using the Framework 3.5 with VS 2010 requires that you add following lines of code:

//Constructor section, next the InitalizeComponent():

Microsoft.Windows.Controls.HtmlFormatter htmlFormatter= new Microsoft.Windows.Controls.HtmlFormatter();
TextFormatter = htmlFormatter; // you can place into the consumer applcation side,
//at you assign to control.

Regards and Thanks a lot for share with us this gift.

Panos

1/8/2014 10:50:24 PM |

Excellent article! I know it is an old thread, but can you please tell me how to make the HTML hyperlinks clickable, within the RichTextBox control?
Thanks a bunch!

Diederik Krols

1/9/2014 2:35:12 AM |

Hi Panos,
that would involve drastically modifying the structure of the HtmlToXaml converter. You would have to insert HyperLink controls instead of Runs for the anchor tags. It might be easier to kind of flag the hyperlinks in the text, then find them with a regular expression, and insert an Hyperlink control in the content. That is more or less what I do here: blogs.u2u.be/.../...for-Windows-81-Store-apps.aspx

Loren Notik

3/2/2014 11:39:00 AM |

I was recommended this web site by my cousin. I am not sure whether this post is written by him as no one else know such detailed about my trouble. You are incredible! Thanks!

Lacie Tribou

About the author

Diederik is principal consultant at U2U Consult where he designs and develops C# & XAML apps for the Enterprise and the Store, with or without an Azure backend.

Mobile Development at U2U Consult

Based in Brussels, Belgium, U2U Consult has been offering consulting & development services in the EMEA region for over 10 years. We offer mobile development on all platforms from Apple to Android & Microsoft.