How To: Generate a custom live tile directly on the phone.

Live Tiles are cool, really cool. But for those of us who don't own a server to do push notifications, and still want to use this cool feature, Windows Phone 7.1 - Codename: Mango, have introduced the ability to generate the tiles directly in our application, and update them with a PeriodicTask.

However, the tile system is limted layout wise, as seen here. So to allow for a customized layout, we need to generate a background image ourself. Which proved not to be the easiest task in the world. Luckily, we can save the generated background image for the tile, to the phone's IsolatedStorage , and then ask the tile to retrieve it from there using the isostore uri scheme. 

To illustate how this is done, I've written a sample application. Here I'll do a walkthrough of the most important parts of it.

First of all, the goal. To render a custom live tile, showing the time of day, the current temperature, a image portraiting the current sky, and a location name. And for this, I've created a simple form, where we can fill in the values:

Livetileexample_2
This form is then used to generate the tile, which ends up looking like this:

Generatedtile
Do do this, I've defined a method named GenerateTile with the parameters reflecting the data that I wish to display. In this method I've then defined the individual controls I wish to render, with their respective values. So far so good.

Now there's two tricks here. First of all, you can't render the cloud image just like that. All images in XAML based frameworks needs to be opened before you can draw them to any other surface. This happens automatically, but not instantly. Thus we need to subscribe to the BitmapImage.ImageOpened event. Once this event is invoked, we can continue the actual drawing to our tile. 

The trick to do the drawing, is to use the WriteableBitmap class. It allows us to render multiple controls to a bitmap, which eventually can be saved to a file.

Each control has to be painted seperately, using the Render method. Make note of the order you render the elements in. Like in XAML, the first rendered element will be furthest behind, and the last element will be in absolute front. Once done painting the element, a call to Invalidate must be made. Otherwise, the image will not be rendered. 

After this, simply save the image to the IsolatedStorageFile stream, using the SaveJpeg extension. Take note, for the image to be accessable from a live tile, the image must be saved into the /Shared/ShellContent/ folder.

Lastly, we have to create or update our tile, which is done by creating a StandardTileData object, with our location set as title, and the background set to the generated image. This is where the isostore uri scheme comes into play, as the reference to the saved image have to be done with the isostore scheme. 

I hope this gave some good insight in how you can create advanced layouted tiles for your application. For details, look into the source code, which is also commented to a high degree, explaining the same steps as in this post, in more technical terms.