WP7: Link in text with RichTextBox on mango

While the first iteration of Windows Phone was based on Silverlight 3 the upcoming release, mango, is based on Silverlight 4. That means a lot of new functionality like implicit styling and and rich text controls. Especially the last was interesting as it gives you a lot more control over the displayed text. What I was looking for, was to place a link in the text and have it open a web page from the application. If you want to get to the core just jump to the end of the post but first a bit of background on the rich text box.

About the rich text box

In mango there is a control called RichTextBox, that boost a lot of functionality like right to left text and inline formatting. I’m going to focus on adding an inline link to an external web page, as for example in a tweet. Before mango this wasn’t possible to do in a text box. There was workarounds like using the wrap panel from the Silverlight for Windows Phone toolkit or write your own control and add the text word by word).

The RichTextBox consists of a bunch of child elements and a set of properties that handles text flow and overall style. In the textbox you will add Paragraphs of text that can be broken down into text parts with attributes like bold, italic, Inline images, etc. There is also the Run that can have it’s on style when it comes to font, size and so on. That way it’s quite easy to build up a complex text. However, there is no support for it in blend so you have to dig into the XAML or code to get what you want:


    
        The quick brown
        fox jumped
        over the lazy
        dog.
    

And on the phone you will get a little line of text like this:

quick01

You could do a lot more with it with both fonts and colors but the problem comes when you want to bind to it. You could do this in a few ways as well, if the text use some kind of markup you could have a converter do the work for you and translate this to elements needed or you can do (as I will show) an injection directly into the textbox. The XAML for what I want is like this:


    

So I the result I want is to inject links and accented text so that I can present a tweet to the user. This end result I want is something like this:

Capture

Mostly it just the matter of breaking down the text in words (just split on space) and then add them one by one in the rich text box. This is done in a loop for each word, added to a paragraph in the rich text box like this:

foreach (var tweetWord in tweetWords)
{
    if (tweetWord.StartsWith("http://"))
        TweetParagraph.Inlines.Add(GetAsLink(tweetWord + " "));
    else
        TweetParagraph.Inlines.Add(GetAsRun(tweetWord + " "));
}

I also identified words that start with # or @ and add these with accent color. You could of course add them with click functionality as well to handle things like navigating and showing a twitter user etc but I think you get the idea.

private Run GetAsRun(string tweetWord)
{
    if (tweetWord.StartsWith("#") || tweetWord.StartsWith("@"))
        return GetAsAccentedRun(tweetWord);

    return new Run { Text = tweetWord };
}

private Run GetAsAccentedRun(string tweetWord)
{
    return new Run
               {
                   Foreground = _accentColor,
                   Text = tweetWord
               };
}

But now for the actual link

At first I hade trouble with it, normally a link just points around in your application. It don’t target the browser and that goes for a hyperlink as well. So my first solution was to catch the click event and on that create a new browser task with the URL. But this seems a bit awkward for just a web link. And indeed there was a simple solution to make sure it opened in a browser window.

private Hyperlink GetAsLink(string tweetWord)
{
    var hl = new Hyperlink
    {
        NavigateUri = new Uri(tweetWord),
        TargetName = "_blank",
        Foreground = _accentColor
    };

    hl.Inlines.Add(tweetWord);

    return hl;
}

The trick here is in the TargetName using the _blank as you do in a normal HTML link ensures that you open a new browser window, even if the link is placed in you Windows Phone application. And if you want that directly in XAML then it will look like this:


    jayway.com

Neat!

Leave a Reply

Close Menu