
Microsoft Style Dynamic Tiles for Windows Phone Mango
Update: I’ve published the code for this post on github. Get the code here.
Have you ever wanted to create a transparent tile for your app that mimics the way the built in Messaging and Mail apps work on your Windows Phone? I’m going to provide specifics on how to mimic the style and do it all on the phone. Prior to Mango, there were only a couple ways to do this and both were nasty. With Mango, we can easily manipulate the primary and secondary tiles for our apps in code.
My goal is to provide a visual way to setup your tile and eliminate the need to write any unnecessary code. There’s no need to write any code to manipulate what’s actually on the tile (i.e. text, images, etc.) since we’ve already been provided a sophisticated layout tool by Microsoft, the visual designer of Visual Studio or Expression Blend. I’ve provided a sample project with all the source code for you to use freely in your projects. The above image is what we’re trying to achieve.
Let’s break down some of the details we’re going to need:
- Font is Segoe WP Semibold 64 pt.
- Vertical center of text container should be at 80 pixels from the top of the image.
- Total height of usable area is 160. (This leaves room for the tile’s title. If you’re not using a title, you can use the entire height of 173 pixels)
User Control
As I said, we want to use these details and arrange the elements visually. To this end, we’re going to use a custom UserControl and use the XAML markup to specify how our tile works. I have a stand-in transparent png image to use as a glyph next to the numbers. Here’s the UserControl XAML:[sourcecode language=“xml”] <UserControl x:Class="MySuperTile.DynamicTile" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" d:DesignHeight="173" d:DesignWidth="173">
<Canvas Background="{Binding Background}" Width="173" Height="173" x:Name="layoutRoot">
<StackPanel Width="173" Height="160" Orientation="Horizontal">
<Image Source="/images/coffee-cup.png" Width="58" Height="98" HorizontalAlignment="Center" Margin="12,0,0,0" />
<TextBlock x:Name="numberText" Text="{Binding Text}" Width="103" FontFamily="Segoe WP Semibold" FontSize="64" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</StackPanel>
</Canvas>
</UserControl> [/sourcecode]
The user control contains a canvas that contains a stack panel. Note that the stack panel is only 160px tall. Then, the transparent PNG is placed first with the numerals next to it. That’s all we need for the XAML. I used sweet data binding to dynamically set the values of the background and text. You could easily make the image bindable to any image if you want to change it on the fly.
The code behind for the user control is:
[sourcecode language=“csharp”] public partial class DynamicTile : UserControl { /// <summary> /// Identifies <see cref="TextProperty"/> dependency property. /// </summary> public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(DynamicTile), null);
/// <summary>
/// Identifies <see cref="TitleProperty"/> dependency property.
/// </summary>
public static readonly DependencyProperty TitleProperty = DependencyProperty.Register("Title", typeof(string), typeof(DynamicTile), null);
/// <summary>
/// Gets or sets the text displayed in the tile.
/// This is a dependency property.
/// </summary>
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
/// <summary>
/// Gets or sets the title of the tile.
/// This is a dependency property.
/// </summary>
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
public DynamicTile()
{
InitializeComponent();
DataContext = this;
}
/// <summary>
/// Used to render the contents to a tile
/// </summary>
/// <returns>a <see cref="StandardTileData"/> with the contents of this control</returns>
public StandardTileData ToTile()
{
// Need to call these, otherwise the contents aren't rendered correctly.
this.Measure(new Size(173, 173));
this.Arrange(new Rect(0, 0, 173, 173));
// The png encoder is the work of the ImageTools API. http://imagetools.codeplex.com/
ExtendedImage tileImaged = this.ToImage();
Encoders.AddEncoder<PngEncoder>();
var p = new PngEncoder();
const string tempFileName = "/Shared/ShellContent/tileImage.png";
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
if (myIsolatedStorage.FileExists(tempFileName))
{
myIsolatedStorage.DeleteFile(tempFileName);
}
IsolatedStorageFileStream fileStream = myIsolatedStorage.CreateFile(tempFileName);
p.Encode(tileImaged, fileStream);
fileStream.Close();
}
var newTile = new StandardTileData
{
Title = Title,
BackgroundImage =
new Uri("isostore:" + tempFileName, UriKind.RelativeOrAbsolute)
};
return newTile;
}
}
[/sourcecode]
In this code, we have a couple of dependency properties (for data binding) and a method to transform the user control into a tile. The difference here is that most guides use the built in JPEG manipulation tools for setting the tile image. But remember I said we are doing a Microsoft style tile with transparency. To get that transparency, we’ll need a PNG image. Saving to PNG is not built into the platform, so I used a 3rd party piece of software called ImageTools (http://imagetools.codeplex.com) that will handle the PNG manipulation.
ImageTools provides an extension method “ToImage()” that takes a UIElement and transforms it into an ExtendedImage (which is part of the ImageTools). Then, using that ExtendedImage, we use the PNG encoder to save the image to IsolatedStorage; the image URI is then given to the tile. The other piece of code that is imperative is:
[sourcecode language=“csharp”] this.Measure(new Size(173, 173)); this.Arrange(new Rect(0, 0, 173, 173)); [/sourcecode]
If that’s not in there the elements will render, but not where they should be. So don’t forget those.
Dropping in the Tile
Now, to actually create the tile, we’ll use this code:[sourcecode language=“csharp”] var mySweetDynamicTile = new DynamicTile { Text = textCount.Text, Title = textCount.Text, Background = new SolidColorBrush(Colors.Purple) };
// Retrieve the contents of the tile as a StandardTileData var newTile = mySweetDynamicTile.ToTile();
// Use the new tile as the primary tile for this app. ShellTile primaryTile = ShellTile.ActiveTiles.First();
if (primaryTile != null) { primaryTile.Update(newTile); } [/sourcecode]
That code instantiates a DynamicTile, sets the title, text, and background color, then asks DynamicTile to create a tile of itself. That tile is then set as the primary tile and, voila, the tile of our app is now set to a dynamic, transparent, tile with Microsoft style numbering. There’s a lot you could do to customize this solution. For example, I used a solid color brush, but there’s nothing stopping you from creating an image brush or a gradient brush. Setting a transparent background (no background, basically), will allow the phone’s accent color to show through.
End Result

A sample project with all the source code is available here.
Comments or Questions? Let me know. Don’t forget to follow me on twitter (@kenstone).