One of the attractive features of Windows Phone 7 is the tiles in the start menu. It’s pretty easy to point the main application tile (and secondary tiles) to static URLs. It’s a bit more difficult to create a dynamic image for a live tile.
Starting with tiles
The easiest way to start is by tweaking the WMManifest.xml file (or even easier, but less flexible) the Project Properties Application Tab:
The title appears as text under the background image. Ideally, the image should be 173×173 pixels in size. Otherwise, WP7 will stretch/crop as appropriate. The image must be a PNG or JPG file. Using a transparent PNG will make the phone’s accent color show through. Here’s an example with an alternate image (viewed with the emulator):
The manifest file contains more options than the above Properties section. This is how it looks now:
This is located in the lower part of the file. The Count element allows placing some number between 1 and 99 in the top right corner of the icon. Here’s how it looks when set to the number 5:
This may come in handy.
The new Mango version adds the ability to have a background tile as well, flipping every couple of seconds or so:
Here’s how the back tile looks:
Although there is a BackBacgroundImageUri, it doesn’t seem to work from the XML (but can be set in code).
Changing a Tile Programmatically
This is fine if all we want is something that does not change. To update a tile, however, or to create secondary tiles, we need some code.
Let’s create a quick notes application that allows adding notes that may be pinned to the start menu. The main tile would indicate the number of existing notes.
Updating the main tile can be done like so:
The ShellTile class is the main gateway to tiles. The ActiveTiles static collection is a list of all application tiles. The list includes at least the main tile (always the first tile), even if it’s not actually pinned.
To update the tile, we create a StandardTileData object and fill in the required properties. In this case, only the Count is changed, but any other property (such as Title and BackgroundImage can be changed).
Creating new tiles
How about creating new tiles? Essentially it’s not too difficult: fill in a StandardTileData object and call Shelltile.Create:
The first argument to Create is a URI that would be followed if the user clicks on the tile. In this case, I’m forwarding this to a XAML page in the app, that would use the query string to display the full note information.
What about the image of the tile? if it’s a predefined image (either within the app or on some server reachable by HTTP), then it’s easy – just set the BackgroundImage property to the appropriate URI. But what about something more dynamic?
Suppose we want the main note text to be displayed in the main tile area (as an image). How could we construct that?
There are 2 steps involved:
1. Create a dynamic image
2. Provide some URI that can reach it
The BackgroundImage property is a URI. I would have expected an ImageSource-derived object, but alas, that is not the case. We have to use a URI somehow.
We’ll use the WriteableBitmap class to create a dynamic image consisting of the note text. One of WriteableBitmap’s abilities is to render any UIElement inside it, so we’re practically not limited to anything.
First, we’ll create a user control that would host our content. Then we’ll render its contents into a WriteableBitmap. Here’s a simple user control markup suitable for our purposes:
This is essentially a simple TextBlock enclosed in a border, that is colored with the user’s theme (PhoneAccentBrush resource key).
Now let’s draw that into a bitmap:
Note that we need to call Measure and Arrange if the element to render is not part of a visual tree. Failing to do so will produce unpredictable results (try it!).
The next step is to somehow transform that into a URI. To do that, we’ll save this bitmap to isolated storage (the storage every application has) in a special folder named Shared/ShellContent and create a URI from that:
The SaveJpeg is an extension method for WriteableBitmap. It certainly comes in handy in this case. Note the new image URI starting with the “isostore:” prefix.
That’s it. We have a dynamic live tile (lower left):
Deleting (unpinning) a tile
To delete (unpin) a tile programmatically, just call the ShellTile.Delete instance method. Here’s an example:
We first must find the tile we want to remove using some properties we’re aware of (typically the NavigationUri property). Then the single call to Delete is all it takes to get rid of the tile.