HTML TextBlock
On the web, HTML is king. So when we create applications on the Windows Phone 7 that presents content from the web, we are bound to run into the HTML obstacle.
In this post I will dig into the ways in wich you can present HTML on the Windows Phone 7 and offer you an alternative.
Consider the HTML version of my previous post;
<p>So it has come to this, I’ve started a blog. Let me start off by introducing myself;</p> <p>I am Matthijs Krempel a part time Windows Phone 7 developer, full time .Net developer and life time father of two boys.</p> <p>With this blog I want to share the challenges and solutions of my development journeys on the Windows Phone 7 platform. The last year I have been developing the <a title=”Channel9 Client for Windows Phone 7″ href=”http://www.windowsphone.com/en-US/apps/7551da0c-bd88-e011-986b-78e7d1fa76f8” target=”_blank”>Channel9 Client for Windows Phone 7</a> and have developed some solutions to challenges that I think and hope you will find interesting.</p> <p>I will host all code on <a title=”Krempel’s codeplex project” href=”http://krempelwp7.codeplex.com/”>codeplex </a>and link to it from here. In my next post I will go into details about the HTML Textblock.</p> <br />
The good, the bad and the ugly
Say you want to use this content in an Windows Phone 7 application. A solution is to use the standard WebBrowser control.
You can navigate to HTML from an URI or from a string. Let’s Navigate to this HTML from string, this is what the end result looks like;
It’s a start, with some additional Html formatting (solution via Ben Geek);
That’s more like it! We can now present any HTML in the native style of the phone! However, it’s not all dandy.
The huge drawback in using the webbrowser control is that it handles gestures for it’s internal scrolling and zooming. This means that if you host this control in a scrollable region, it will capture the gestures and not scroll the parent container. There are solutions in wich you can disable vertical or horizontal scrolling by drilling into the Visual Tree, but the gesture will still not availible outside the webbrowser control. The user will not be able to navigate. The tradeoff could be that you can use the webbrowser control in a standalone page, like many news readers do.
So, you are limited in your options for using the webbrowser control to present HTML content, if you are not willing to sacrifice usability.
The alternative
With Windows Phone 7.1 (Mango) a new control was added to the standard library; the RichTextBox. The RichTextBox enables us to present (a subset of) flowdocument elements, natively.
Only three obstacles left to conquer;
- We have HTML and we would like RichTextBox XAML
- Length of the XAML must not exceed 1500 (or so) characters
- Height of the RichTextBox must be smaller then 2000 pixels (2000×2000 is the maximum size of any Windows Phone 7 visual element)
HTML Agility Pack
I’ve solved the first problem by using the HTML Agility Pack. There is a Windows Phone 7 version availible on codeplex, download the source, open the Trunk/HAPPhone.7.1 solution, add reference to System.Xml.XPath from the Silverlight 4.0 SDK, remove build scripts and compile! Now we have a effiecient way of navigating trough the HTML, all we have to do is translate the HTML to XAML objects. That solves obstacle 1.
We are left with two obstacles, 2 and 3. Wich we can solve quite easily. Instead of trying to create one huge RichTextBox with all the HTML in it, we create a whole host of RichTextBoxes. What I’ve done in the solution is to make a RichTextBox per paragraph. As long as the author of the comment or article refrains from using lenghty texts, we will be fine.
The end result looks something like;
You can host this HTMLTextBlock in any kind of scrollable container and the gestures work!
Source code and this example is available here!
The main goal of this control is to render the kind of HTML seen in blogs and comments, it’s not ment as a full blown browser, if you want those kinds of features fallback to the webbrowser control.
UPDATE;
New version is availible here!
Your control is awesome!
Please add it in NuGet, because there are some difficulties with building it 🙂
Panfilov F. (@ponfius) said this on March 11, 2012 at 9:38 pm |
Few more questions:
1. How to work with links?
2. How to customise link color, f.e.?
Panfilov F. (@ponfius) said this on March 11, 2012 at 10:32 pm |
Hi Panfilov,
Thank you for you suggestions!
Will add it to NuGet when I get the chance.
I will add a event and a command property to handle Navigation requests and a style for custom link colors (wich will be defaulted to the PhoneAccentColor).
Matthijs Krempel said this on March 12, 2012 at 10:31 am |
I have done custom colors and hyperlink button navigation 🙂
And, I hope, solve problem with large images.
Panfilov F. (@ponfius) said this on March 12, 2012 at 3:58 pm |
Sweet!
If you can share back, that would be great!
Matthijs Krempel said this on March 12, 2012 at 4:00 pm
With links and colors everything is easy:
Hyperlink hyperlink = new Hyperlink();
hyperlink.Foreground = new SolidColorBrush(Colors.Blue);
hyperlink.NavigateUri = new Uri(node.Attributes[“href”].Value, UriKind.Absolute);
hyperlink.TargetName = “_blank”;
in AppendHyperlink method.
In Foreground you can use not brush, but Resources[“PhoneAccentBrush”] (I don’t remember for sure 🙂
But with image size I still didn’t solve problem 😦
Panfilov F. (@ponfius) said this on March 12, 2012 at 8:59 pm |
I will update the component soon with some additional properties for styling.
Thank you for the feedback!
Matthijs Krempel said this on March 13, 2012 at 7:59 am |
I have something strange with links: they are not on the same line with previous text, but in html there is no tags between them 😦
Panfilov F. (@ponfius) said this on March 13, 2012 at 8:15 pm |
are you in control of the html? if yes, place them in a paragraph if no, adapt the control to not span across multiple richtextboxes, if still no send me the html at matthijsDOTkrempelAThotmailDOTcom
Matthijs Krempel said this on March 13, 2012 at 9:20 pm |
Congrats on the Hot Apps review!
Blogger Bontang (@bloggerbontang) said this on March 25, 2012 at 2:28 pm |
thanks!
Matthijs Krempel said this on March 25, 2012 at 3:23 pm |
Hi, you made a good job!
But how to implement bold?
Cedric Arnould said this on March 26, 2012 at 10:49 am |
Bold is done by the control, by giving the Run element a FontWeight of bold;
private void AppendBold(HtmlNode node, Paragraph paragraph, Span span)
{
Run run = new Run();
run.FontWeight = FontWeights.Bold;
if (span != null)
{
span.Inlines.Add(run);
}
else if (paragraph != null)
{
paragraph.Inlines.Add(run);
}
AppendChildren(node, paragraph, span);
}
It adds this on the ‘b’ or ‘strong’ element.
Matthijs Krempel said this on March 26, 2012 at 10:53 am |
Hi the “b” or “strong” tag doesn’t seem to work. Even with the
private void AppendBold(HtmlNode node, Paragraph paragraph, Span span)
{
Run run = new Run();
run.FontWeight = FontWeights.Bold;
if (run.FontFamily != this.FontFamily)
run.FontFamily = this.FontFamily;
if (run.FontSize != this.FontSize)
run.FontSize = this.FontSize;
if (run.FontStretch != this.FontStretch)
run.FontStretch = this.FontStretch;
if (run.FontStyle != this.FontStyle)
run.FontStyle = this.FontStyle;
if (run.Foreground != this.Foreground)
run.Foreground = this.Foreground;
if (span != null)
{
span.Inlines.Add(run);
}
else if (paragraph != null)
{
paragraph.Inlines.Add(run);
}
AppendChildren(node, paragraph, span);
}
my html goes like this This text is suppose to be bold
Ah pek said this on March 17, 2014 at 12:09 pm
Thanks for your answer!
I have another question, it seems that FontSize doesn’t work. Do you have the same problem?
Cedric Arnould said this on April 4, 2012 at 5:29 pm |
And this is the same with FontFamily
Cedric Arnould said this on April 4, 2012 at 5:32 pm |
i’ll check it out, how exactly are you using the control?
Matthijs Krempel said this on April 4, 2012 at 7:10 pm |
Hi,
I use it like this:
xmlns:krempel=”clr-namespace:Krempel.WP7.Core.Controls;assembly=Krempel.WP7.Core”
and
Cedric Arnould said this on April 5, 2012 at 9:35 am |
Cedric Arnould said this on April 5, 2012 at 9:35 am |
(sorry it didn’t appear correctly)
Cedric Arnould said this on April 5, 2012 at 9:37 am |
k r e m p e l : H t m l T e x t B l o c k x : N a m e = ” t b x R e s p o n s e 1 ” M a r g i n = ” – 1 2 , 0 ” F o n t F a m i l y = ” S e g o e W P S e m i L i g h t ” F o n t S i z e = ” 3 2 “
Cedric Arnould said this on April 5, 2012 at 9:37 am |
with anchor of course 🙂
Cedric Arnould said this on April 5, 2012 at 9:38 am |
I see what you mean, I did not implement this properly, I will fix soon!
Matthijs Krempel said this on April 5, 2012 at 10:09 am
Thank a lot!
Cedric Arnould said this on April 5, 2012 at 10:23 am |
Thanks a lot for this code!
Seems I have the following issue, if you have html code like the following, the code is treated like one block due to the and the paragraphs are not split in separate blocks:
Rob said this on April 8, 2012 at 9:19 am |
Thanks a lot for this code!
Seems I have the following issue, if you have html code like the following, the code is treated like one block due to the and the paragraphs are not split in separate blocks:
html code not showing in previous comment:
<div <p </p <p </p </div
Rob said this on April 8, 2012 at 9:21 am |
Hi, Maybe the previous comment was not correct and the error might be something else.
I include a link to a zip file containing html source, so you can test this datacontext yourself and see what is happening with the <div
Another thing I noticed was that if you have a paragraph with a link inside it, it will split the paragraph in three pieces, text-link-text, but it will not pass anymore the case "p": in AppendFromHtml, so it looks like it doesn't notice that there is a new paragraph. Maybe this is the bug for my previous comment
Link to zipped text file containing datacontext html:
https://skydrive.live.com/?cid=9ab6df3203913388&id=9AB6DF3203913388%21123
Rob said this on April 8, 2012 at 9:48 am |
Hi Rob, I will look into it. There are many many ways of doing things in HTML, so if you want full HTML support you should use the webbrowser component. This control has limited HTML support, it’s ment for blogpostings and comments.
Btw; do you still have problems playing back videos in the Channel9 app? I tried to contact you via twitter, but got no response.
Matthijs Krempel said this on April 8, 2012 at 10:57 am |
Hoi Matthijs, the htmltext component is just fine, the webbrowser might be too heavy for just showing some text, want to keep memory usage to the minimum. Willl try again the channel9.. Downloaded again, yes is wworking now 🙂
rob de beir said this on May 19, 2012 at 9:21 pm
mooi! mag ik je motiveren om je review te veranderen? 😉
Matthijs Krempel said this on May 20, 2012 at 8:45 pm
That’s a pretty cool little control, well done. Got one small question tho. I set the hyperlink’s foreground to green and have a white background. After clicking on the hyperlink and clicking on the physical back button I am back in my app and the color of the hyperlink is also white. It looks like the “pressed” state (or how else to call it..) is white? Any way to change this?
This also occurs when you keep your finger tabbed (it changes to white) and scroll (it changes back to, in my case, green).
Any ideas how I can fix this?
Koos said this on August 1, 2012 at 1:13 pm |
Hi,
How to change the foreground color in htmlTextBlock?
Yogesh Kumar said this on October 23, 2012 at 10:36 am |
Your control is great. I have a problem with embedding custom font in your control. When my html code is something like this “this is a sample para” , control shows it as “this is a para”. Could you help me fixing that.
Anonymous said this on November 8, 2012 at 5:11 am |
nice work. but the source code from your codeplex page, richtexblock is showing an error. and not executing. can you check on that
naifmhd said this on November 15, 2012 at 8:19 pm |
I will, thanks for the headsup!
Matthijs Krempel said this on January 23, 2013 at 9:48 am |
Is this compatible with the Windows Phone 8 SDK ?
Anonymous said this on November 20, 2012 at 9:48 pm |
Don’t know, havent tried yet.
Matthijs Krempel said this on January 23, 2013 at 9:48 am |
Hey there. How exactly does hyperlink handling work with this control? I’ve got the control working beautifully for my needs, except I can’t get it to follow any links. Basically, I want to make the link open in an actual web browser app. Is there an event that fires off that I could handle?
Gerry said this on December 15, 2012 at 3:22 am |
Well I must be blind. Here is an example for people scratching their head about the same question. I’m new to Windows Phone – been on iPhone for 6 years. This is what happens when you get used to an inferior SDK (iOS), haha!
Here’s the example: 🙂
…
void htmlTextBlock_NavigationEventHandler(object sender, System.Windows.Navigation.NavigationEventArgs args)
{
if (args.Content is Hyperlink)
{
Hyperlink link = args.Content as Hyperlink;
MessageBox.Show(“clicked a link: ” + link.CommandParameter.ToString());
}
}
…
myHtmlTextBlock.NavigationRequested += htmlTextBlock_NavigationEventHandler;
Gerry said this on December 15, 2012 at 3:42 am |
iOS is a good consumer platform, but the Microsoft eco system is the best developer platform in the world!
Glad you like the control 🙂
Matthijs Krempel said this on January 23, 2013 at 9:47 am
This is insanely useful, thanks so much for sharing. I needed to display 20 different blocks of HTML content in a ListBox and using a bunch of WebBrowser controls was a bit painful, especially given that I had to use JavaScript hacks to set the height of the controls to match my content. HTML TextBlock saved a lot of my sanity!
Greg said this on January 3, 2013 at 1:38 am |
Thank you for all your comments and suggestions.
As I am currently swamped with my daytime job, you will have to forgive the lack of updates.
When I get some more time, I will work on an update for 7.8 and 8.0.
Matthijs Krempel said this on January 23, 2013 at 9:45 am |
Hi, what’s the status of the 8.0 update? i need this control for my app =(
Matteo Murdocco said this on May 19, 2013 at 9:37 pm |
finally found this only to realize it doesn’t work on wp8 😦
nate said this on May 25, 2013 at 5:30 pm |
Hi, Looking for this control in WP8. Please update.
Anonymous said this on June 12, 2013 at 7:25 am |
Hi,
I’ve updated the library to support Windows Phone 8.
https://github.com/amarmesic/Krempel.WP8
Amar said this on August 24, 2013 at 3:53 pm |
amar,
awesome! thank you very much.
I will merge the bugfixes and release a wp8 nuget package!
Do you have a codeplex login?
Matthijs Krempel said this on August 24, 2013 at 6:08 pm |
Matthijs,
It was a minor fix, the Foreground color was stuck at PhoneForegroundBrush. Works with HtmlAgilityPack sl3-wp
My codeplex login: amarmesic
Amar said this on August 24, 2013 at 6:22 pm
i’ll grant you access as soon as I get home,.
Matthijs Krempel said this on August 24, 2013 at 6:53 pm
Hi!
I have a Windows Phone 8 application projects. Just like Channel 9 client app. Is Youtube video in html code. What should I do to show it?
And, and, and…
Also as photos in the links, only the picture shows. Touching on the image link should go. Urgent help me. Please!
Burak said this on November 30, 2013 at 10:52 am |
Hi,
Has the windows 8 version been added to nuget yet? I would really like to use it.
Ash said this on July 7, 2014 at 11:32 am |
How to add Binding element inside HtmlTextBlock control
I Have installed Krempel in my solution via project manager console and getting the HtmlTextBlock control by the namspace.
Please reply me fast. its Urgent
Vivek Gupta said this on September 17, 2014 at 11:46 am |
Hi Vivek, you can check out example code on codeplex;
http://krempelwp7.codeplex.com/
Matthijs Krempel said this on September 17, 2014 at 12:05 pm |
Hi, Looking for this control in Windows phone 8. Please update.
https://github.com/amarmesic/Krempel.WP8 –> Page not found
Thanks!
Hoàng Quang Quốc said this on March 20, 2015 at 9:51 am |
日本は、これはホラーで売るのかな?。 クロムハーツ チェーンネックレス
Davina Lompa said this on July 21, 2016 at 5:45 pm |
Whoa….such a handy site.|
Debi Fortier said this on July 21, 2016 at 6:17 pm |
that’s good, thanks for sharing,.. I think this is great blog
Walker Dangel said this on July 21, 2016 at 8:03 pm |
can we present strike through using this control ??
subbarao said this on September 29, 2016 at 1:03 pm |