My example once again brings Visual Studio Achievements for Windows Phone into the spotlight. I was working on a way to display user achievements in a decent manner, so the description blends with the general application structure. What would be the best solution here? Obviously, the first that comes to mind is a UI that is bound to a collection of achievements. For every achievement, there is a separate ItemTemplate in a ListBox that is a key part of the above mentioned UI. The achievement description is bound to a TextBlock, and here is where things get interesting.
Take a look at the page below:
Nothing wrong with the achievement descriptions here. It is all displayed correctly, to an extent. I am using the Channel9 Visual Studio Achievements API, and when the earned achievements are returned, I get a JSON representation for each of them that is similar to this:
Look at what I highlighted and try finding the source of potential problems. If you thought about back and forward slashes, you are thinking in the wrong key. I meant the link. The whole <a href="LINK"></a> block inside the description. It doesn't crash the application or cause any critical issues. However, TextBlock cannot process links in its default implementation, so the HTML code will be displayed to the end user. That is not a desirable scenario, and I had two possible solutions:
- Eliminate the link completely, either by using Regex or a standard string search.
- Use a WebBrowser control and use its NavigateToString capability to automatically process the HTML.
- Use a RichTextBox control.
Eliminating the link sounded like a good idea until I thought about potential API changes. Currently, links are only used to reference that an achievement is using FxCop. However, in the future links might represent additional requirements the user should be aware of. Therefore, it was clear that the link must be there. Especially since later on it might happen that a link block will be part of a description sentence.
Using a RichTextBox will require me to create an entire HTML/data processing block in the code-behind, since the control is un-bindable by default. The infrastructure can be eventually created, but there is no need for such when there is a more efficient workaround.
The WebBrowser control has some side-effects that require further modifications (e.g. scrolling, zooming), but its big benefit is the possibility of passing a HTML string and it will automatically process it. There is one small problem, though - there is no bindable property that would let me pass a string to it. Here is when I remembered that there are also attached properties. I ended up with something similar to what Nigel Sampson described here.
That way, I implemented the feature requested by one of the testers and avoided potential problems with returned API results in case more links are introduced in the description.