Thursday, September 22, 2011

Metro App Tile Notification


In my last post I showed you how to configure the start menu tile for a Windows 8 Metro app. The tiles can be used for more the just displaying a static startup icon, they can also display content that is relevant to your app so that the user can get information from the app without even leaving the start menu.
There are a couple ways to do this. The first one I will show is notifications. A notification displays some content on the tile instead of its default text and icon. A good example of this is the Stocks app that comes with Windows 8. When you start the app the current stock information will be setup as notifications so when you go back to the start menu you will see the tile rotate through the values for each stock market. Let's take a look at how you do a notification in a C# Metro app.
Note: The current version of Windows 8 is pre-beta and still a little buggy. I have found this especially true with the notifications, sometime they just don't work for no apparent reason.

The appearance of a notification is controlled by an XML template, so the first step in sending a notification is to get a template to work with like this:

Note: You will want to include the Windows.UI.Notifications namespace.

var xmlTemplate = TileUpdateManager.GetTemplateContent(TileTemplateType.TileWideText01);

This command will return an XmlDocument object containing the TileWideText01 template that you can fill out with the data you want to display. You can see a full list of all the templates here. Unfortunately that page doesn't show the actual XML in the template which you need to know before you can modify it. You may want to put a TextArea on your application form and set it's Text property to xmlTemplate.GetXml() to see the XML. The XML for the TileWideText01 template looks like this:

<?xml version="1.0" encoding="utf-16"?> 

<tile>
  <visual lang="en-US">
    <binding template="TileWideText01">
      <text id="1"></text>
      <text id="2"></text>
      <text id="3"></text>
      <text id="4"></text>
      <text id="5"></text>
    </binding>
  </visual>
</tile> 

and the resulting 

tile will look something like this:

clip_image002

To get our text into the notification we need to modify the XML. Here I use XPath to select the first text node and set its value:

var textNode = xmlTemplate.SelectSingleNode("/tile/visual/binding/text[@id='1']"); 
var newText = xmlTemplate.CreateTextNode(text); 
textNode.AppendChild(newText); 

Next we need to create a tileNotification object from the xml:

var tileNotification = new TileNotification(xmlTemplate); 

Finally we need to update the notification on the tile:

var tileUpdater = TileUpdateManager.CreateTileUpdaterForApplication(); 
tileUpdater.Update(tileNotification); 

If you put this code in the form constructor of a C# Metro app, run the app, and then switch to the Start screen you will momentarily see the default startup tile, then the notification will slide into view. The notification will continue to be displayed even if the application is terminated, the computer restarted, or even if the app is un-installed and re-installed (I think this is un-intended and may change in later versions.)

There are two ways for you to remove the notification. The first way is to replace it with a different notification. The second way it to clear it with the following command:

TileUpdateManager.CreateTileUpdaterForApplication().Clear(); 

This will remove the notification and restore the tile to the initial startup appearance.

Normally you can only have one notification active at a time, but there is also a way to show multiple notifications. First execute this command:

TileUpdateManager.CreateTileUpdaterForApplication()

.EnableNotificationQueue(true); 

Then add up to five notifications and the tile will rotate between them. If you add more than five the most recent five added will be shown.

One other thing you can do with notifications is set an expiration date and time. You do that like this:

tileNotification.ExpirationTime = new DateTimeOffset(DateTime.Now.AddMinutes(5)); 

This command will make a notification expire 5 minutes after it has been added to the tile. After the notification expires the initial startup tile will be displayed just like when you use the Clear command.

2 comments:

Zéiksz said...

Hi!

var textNode = xmlTemplate.SelectSingleNode("/title/visual/binding/text[@id='1']");

is "TILE", not "title".

Have a nice day:
Péter

Dan Boris said...

Thanks for pointing that out, I have fixed it in the post.