Windows 8 – Html to RichTextBox Content

By Dries Marckmann
February 21, 2013
0

As I explained in my last posts (here and here) I want to use Diffbot to implement my offline reading feature. I want the text to show up looking as close to the real website as I can. This can be done with the RichTextBlock control. This can implement a very limited set of xaml elements. Read about it on http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.richtextblock.

Luckily DiffBot can send me the text in html, so the style isn’t lost. All I needed is a way to convert Html to Xaml. If you search NuGet for ‘RichTextBlock’ you get 2 results: RichTextBlock.Html2Xaml and WinRT Html2Xaml Converter . I tried them both, but the first uses an xslt template for parsing the html and that only works if the html can be processed as xml. If only every website was this tidy… So I ended up using the last one that uses HtmlAgilityPack to parse the html.

WinRT.Html2Xaml

I like the general idea of this project. Check out the code on https://winrthtml2xaml.codeplex.com/. Here’s how it works:

There is an attached property for the Html so we can bind a string in a class called Properties. Whenever the Html changes the HtmlChanged eventhandler is called. This method uses the converter to convert html to xaml, set this in a new RichTextBlock and then moves all the blocks from the new RichTextBlock into the existing one. Works like a charm.

The Html2XamlConverter is a static class with 1 public method: Convert2Xaml(string htmlString) (it also has an overload where you can specify extra attributes) which is called from the HtmlChanged eventHandler. It uses TagDefinitions to specify how a translation between html and xaml tags should be made.

Downside

Unfortunately, this package does not support parsing img tags to Images and it provided no good way of extending the processing to my needs. The Html2XamlConverter is a static class with a fixed set of TagDefinitions, there is no way to get in between.

Nothing to do but fork I guess.

Fixing extensibility

First of all, to allow dependency the static Html2XamlConverter must be changed to a non-static class. Secondly, I added an extra attached property Converter in the Properties class to allow setting converter in xaml (this has to be a resource though. Here’s how you use it:

<Page.Resources>

        <common:MyHtml2XamlConverter x:Key=”MyConverter” />

    </Page.Resources>


<RichTextBlock

h2xaml:Properties.Html=”{Binding Text}”

h2xaml:Properties.Converter=”{StaticResource MyConverter}” />

I can now specify which Converter I want to use. I can even bind it if I so want.

So I forked the code, refactored and will do a pull request soon. In the meanwhile get the code here: http://winrthtml2xaml.codeplex.com/SourceControl/network/forks/dmarckmann/extendableHtml2Xaml

Accidentally, I added support for img tag parsing also.

Here’s a little sample of a converter that will parse pre tags to allow the right view of c# code:

public
class
MyHtml2XamlConverter : Html2XamlConverter

    {

        public MyHtml2XamlConverter()

            : base()

        {

            tags.Add(“pre”, new
TagDefinition(parsePre) { MustBeTop = true });

        }

        private
void parsePre(StringBuilder xamlString, HtmlNode node, bool isTop)

        {

            xamlString.Append(“<Span FontFamily=”Consolas” FontSize=”14″>”);

            xamlString.Append(node.InnerText.Replace(“n”, “<LineBreak/>”).Replace(” “, “<Run Text=” “/>”));

            xamlString.Append(“</Span>”);

        }

    }

Now we’ll have to wait for someone to make us a converter that will parse pre tags with c# color coding… (Do I hear ‘challenge accepted!’? Anyone?)

Happy coding!

Comments: 0

Leave a Reply

Your email address will not be published. Required fields are marked *