Hands on Windows 8 development: Twitter and hyperlink hassles

I have been messing around with a Windows 8 app to present content from ITWriting.com in an app, mainly as a learning exercise. I came up with the idea of showing recent tweets on the main page of the app. Like this:

image

I thought this would be easy, but encountered several problems. I am developing in XAML and C#; this aspect would probably be easier in HTML.

The first problem: retrieving the tweets. The Twitter REST API version 1.1 has GET statuses/user_timeline which does what I want, except that it requires “user context”, in other words a Twitter log-in. That is an unacceptable requirement for a user simply viewing my tweets, rather than their own timeline.

The deprecated  Twitter RSS API on the other hand is perfect. Unfortunately:

Please note that there is no support for the RSS response format in API v1.1. Properly versioned API v1 URLs will cease functioning in March 2013

Never mind, it will do for the moment. I created a Twitter data source which retrieves the tweets as RSS. In my XAML I have a ListView which is bound to this data source. This ListView has an ItemTemplate which defines what appears in the list. I added a TweetItemTemplate in the Resources section of the XAML which displays each tweet in a TextBlock. So far so good.

image

No hyperlinks though – they are dead. What is the use of a tweet without hyperlinks? Not much. I thought of a hack which would let you click or tap an entire tweet, look to see if a hyperlink is there, and then launch it. Ugly, and would only work for one hyperlink per tweet.

TextBlock does not support hyperlinks. However there is a way to do this using RichTextBlock. This supports a collection of inline elements. You can have a Run element containing text, then an InlineUIContainer containing a HyperLinkButton, then another Run element and so on. The Hyperlink will be out of alignment, as shown here, but you can fix that by tweaking margins and padding.

Of course, this approach does mean parsing the tweet to extract the URLs and then building the RichTextBlock content. So in place of my simple TextBlock binding I now have this:

  <ContentControl Content="{Binding Path=Title,Converter={StaticResource tweetToBlocks}}"></ContentControl>

I have also written a converter class which takes the bound value, builds the RichTextBlock in C#, and returns it. This gets you the result in the first image in this post. Not too bad, and the links work.

What is annoying though is that the mouse pointer does not change to a hand icon when you hover over the link. I thought I could fix this by subclassing HyperLinkButton and adding code to change the cursor on the PointerEntered event:

Window.Current.CoreWindow.PointerCursor = new Windows.UI.Core.CoreCursor(Windows.UI.Core.CoreCursorType.Hand, 1);

This does not work. At least, you can see a flash as the cursor tries to change, but it is overridden by the RichTextBlock which changes it back to a text select cursor. I have not found a way round this yet.

I then tried another approach. You can use a RichEditBox which does support links. The approach is different; you set the text of the Document property and then use the Link method to assign a link to a TextRange within it. It works; but I was frustrated to find that the mouse pointer still does not change to a hand when over the link. The RichTextBlock actually works just as well and is more integrated with XAML.

image

I am sure you could fix this by using a WebView – embedded IE – for each tweet, but that seems to me an unduly heavyweight approach. Better perhaps would be a single web view showing all the tweets, which I might try when I have a moment.

Even so, I was surprised how tricky it is to show tweets with hyperlinks in a ListView.

7 thoughts on “Hands on Windows 8 development: Twitter and hyperlink hassles”

  1. Twitter turning off the version 0 API also broke this nice little demo:

    http://manual.qooxdoo.org/current/pages/mobile/tutorial.html#we-need-data-lots-of-data

    But the version 1 GET statuses/user_timeline still works, although it too will be going away next year. E.g.,

    https://api.twitter.com/1/statuses/user_timeline.json?screen_name=qooxdoo

    However, it looks as though you can use your own OAuth credentials in your app with the version 1.1 API so that your users don’t need to log in. See the 3rd item here:

    https://dev.twitter.com/discussions/10803?page=1

    Thanks.

    -Phil

  2. Tim,

    Yes, Metro RichTextBox is a bad joke. But the real problem is that you simply can’t implement you own text editor control using existing API’s. Unlike Silverlight and WPF, in WinRT you don’t have OnTextInput event so you can’t get what user actually type on keyboard.

    It seems that the best workaround is to put WebView control and load text as Html into it.

    WinRT is fast, stable and has very good object-oriented design but there is tons of missing API’s . We just published our diagramming application (Grapholite Diagrams) on Windows Store. This app was ported from Silverlight. For example, we had to rewrite all drawing procedures using DirectX just to implement export to image. Why? Because there is absolutely no way to capture controls visual tree as bitmap.

    I hope that WinRT 2.0 will allow to make real applications.

  3. Hello Tim.

    Here’s the answer to this problem… put an OnPointerMoved event on the link, and then set the hand in that OnPointerMoved event. I understand it’s not the most elegant answer, but it does work and it does provide you with what you need.

    Pseudo:

    private void [SomeEventNameHere] (o, e)
    {
    Window.Current.CoreWindow.PointerCursor = new Windows.UI.Core.CoreCursor(Windows.UI.Core.CoreCursorType.Hand, 1);
    }

  4. Aww C’mon all my pseudo XAML got wiped out by your comment moderation.

    Sad

    [RichTextBlock]
    [Paragraph]
    [TextBlock OnPointerMoved=”SomeEventNameHere” /]
    [/Paragraph]
    [/RichTextBlock]

  5. Hi Tim,

    Do you have the source code for the working example? RichEditBox won’t work as I expect.

Comments are closed.