First Tile
Here’s how Metro tile notifications work in the simplest way.
I created a basic Metro application that had a modified Package.appxmanifest.
First, I added a wide tile image. If you don’t do this the build complains that
there is no tile. In this case the tile was just a blue background with a bit of
text saying #1 Tile.

Don’t worry. It won’t last for long.
I set the “Lock screen notifications” to “Badge and tile text”
I also added to the “Declarations” tab so that included the “Background Tasks”
with the supported task type of “Timer”. This should stop the application being
suspended and allow the timer to run.
The XAML for the main screen is shown below:
<UserControl
x:Class="FirstTile.MainPage"
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"
d:DesignHeight="768"
d:DesignWidth="1366">
<Grid
x:Name="LayoutRoot" Background="#FF000080">
<TextBlock
Text="{Binding Count}" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
</Grid>
</UserControl>
Note that I used a TextBlock bound to a “Count” dependency property.
The code behind
Things go a little strange here if you’re used to WPF. There are some minor but
frustrating changes in Metro which can cause a bit of head scratching if you’re
not aware of them.
I created a Dependency Property for my MainPage class as shown below. Note how
the declaration of the actual DependencyProperty is different.
public int Count
{
get { return
(int)GetValue(CountProperty); }
set { SetValue(CountProperty,
value); }
}
private readonly
DependencyProperty CountProperty =
DependencyProperty.Register("Count", "Object",
typeof(MainPage).FullName,
new PropertyMetadata(0, CountChanged));
The Register method now expects the types as strings and one is buggy. I’m sure
this will go away in the post beta version.
Class fields
In the MainPage I added a field of type TileUpdater:
TileUpdater _updater =
null;
MainPage constructor
public MainPage()
{
InitializeComponent(); //Call the standard
method
//Here I obtained
the application’s TileUpdater and saved it
_updater =
TileUpdateManager.CreateTileUpdaterForApplication();
//I also enabled
the notification queue
_updater.EnableNotificationQueue(true);
//I set up a
simple timer to update the count every few seconds
//Don’t
do this too quickly as notifications can be missed
//due to the tile
animations taking more than a second
DispatcherTimer dt =
new DispatcherTimer();
dt.Interval = TimeSpan.FromSeconds(4);
dt.Tick += (s, e) => Count++;
dt.Start();
//Set our own
DataContext so the TextBlock can bind to the Count
DataContext = this;
}
Count changed handler
Whenever the Count dependency property is updated, in this case in response to
the timer ticking, the update is called. To avoid any problems with non UI
thread calls the dispatcher invokes the Update method on the UI thread. This is
a belt and braces approach.
static void
CountChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
MainPage mp = sender
as MainPage;
mp.Dispatcher.InvokeAsync(CoreDispatcherPriority.Normal,
(s, ev) => mp.UpdateTile(),
mp,
null);
}
Updating the tile
Here’s the good stuff. This method is invoked via the CountChanged handler. The
first thing is to get the desired XML for the tile. There are several different
ones depending on what you want to do. This example just updates the tile text
in as simple a way as possible.
The TileUpdateManager is uset to retrieve the tile XML. The XML document enables
us to get the <text> elements in the XML and the first one is given content that
displays the current value of the Count property.
A TileNotification is created from the tile template and the _updater field
which contains the TileUpdater for the application is used to do the tile
update.
private void
UpdateTile()
{
XmlDocument tile =
TileUpdateManager.GetTemplateContent(TileTemplateType.TileWideText01);
string s = tile.FirstChild.GetXml();
var attr = tile.GetElementsByTagName("text");
attr[0].AppendChild(tile.CreateTextNode(string.Format("Count={0}", Count)));
var tilenotification =
new TileNotification(tile);
_updater.Update(tilenotification);
}
Essential things
·
Modify the Package.appxmanifest to include a
Background Task declaration.
·
Get the TileUpdater
·
Get the tile template desired and modify it
accordingly
·
Using the modified tile template, create a
TileNotification and update the tile.
Supplementary info:
Here is a complete list of the contents of all the standard Metro tile templates:
TileTemplateType.TileSquareImage
<tile>
<visual lang="en-US">
<binding
template="TileSquareImage">
<image
id="1" src=""/>
</binding>
</visual>
</tile>
TileTemplateType.TileWideImageCollection
<tile>
<visual lang="en-US">
<binding
template="TileWideImageCollection">
<image id="1" src=""/>
<image
id="2" src=""/>
<image
id="3" src=""/>
<image
id="4" src=""/>
<image
id="5" src=""/>
</binding>
</visual>
</tile>
TileTemplateType.TileWideImageAndText
<tile>
<visual lang="en-US">
<binding
template="TileWideImageAndText">
<image
id="1" src=""/>
<text
id="1"></text>
</binding>
</visual>
</tile>
TileTemplateType.TileWideImage
<tile>
<visual lang="en-US">
<binding
template="TileWideImage">
<image
id="1" src=""/>
</binding>
</visual>
</tile>
TileTemplateType.TileWidePeekImageAndText
<tile>
<visual lang="en-US">
<binding
template="TileWidePeekImageAndText">
<image
id="1" src=""/>
<text
id="1"></text>
</binding>
</visual>
</tile>
TileTemplateType.TileWidePeekImageCollection01
<tile>
<visual lang="en-US">
<binding
template="TileWidePeekImageCollection01">
<image
id="1" src=""/>
<image
id="2" src=""/>
<image
id="3" src=""/>
<image
id="4" src=""/>
<image
id="5" src=""/>
<text
id="1"></text>
<text
id="2"></text>
</binding>
</visual>
</tile>
TileTemplateType.TileWidePeekImageCollection02
<tile>
<visual lang="en-US">
<binding
template="TileWidePeekImageCollection02">
<image
id="1" src=""/>
<image
id="2" src=""/>
<image
id="3" src=""/>
<image
id="4" src=""/>
<image
id="5" src=""/>
<text
id="1"></text>
<text
id="2"></text>
<text id="3"></text>
<text
id="4"></text>
<text
id="5"></text>
</binding>
</visual>
</tile>
TileTemplateType.TileWidePeekImageCollection03
<tile>
<visual lang="en-US">
<binding
template="TileWidePeekImageCollection03">
<image
id="1" src=""/>
<image
id="2" src=""/>
<image
id="3" src=""/>
<image
id="4" src=""/>
<image
id="5" src=""/>
<text
id="1"></text>
</binding>
</visual>
</tile>
TileTemplateType.TileWidePeekImageCollection04
<tile>
<visual lang="en-US">
<binding
template="TileWidePeekImageCollection04">
<image
id="1" src=""/>
<image
id="2" src=""/>
<image
id="3" src=""/>
<image
id="4" src=""/>
<image
id="5" src=""/>
<text
id="1"></text>
</binding>
</visual>
</tile>
TileTemplateType.TileWidePeekImageCollection05
<tile>
<visual lang="en-US">
<binding
template="TileWidePeekImageCollection05">
<image
id="1" src=""/>
<image
id="2" src=""/>
<image
id="3" src=""/>
<image
id="4" src=""/>
<image
id="5" src=""/>
<image
id="6" src=""/>
<text
id="1"></text>
<text
id="2"></text>
</binding>
</visual>
</tile>
TileTemplateType.TileWidePeekImageCollection06
<tile>
<visual lang="en-US">
<binding
template="TileWidePeekImageCollection06">
<image
id="1" src=""/>
<image
id="2" src=""/>
<image
id="3" src=""/>
<image
id="4" src=""/>
<image
id="5" src=""/>
<image
id="6" src=""/>
<text id="1"></text>
</binding>
</visual>
</tile>
TileTemplateType.TileWidePeekImage01
<tile>
<visual lang="en-US">
<binding
template="TileWidePeekImage01">
<image
id="1" src=""/>
<text
id="1"></text>
<text
id="2"></text>
</binding>
</visual>
</tile>
TileTemplateType.TileWidePeekImage02
<tile>
<visual lang="en-US">
<binding
template="TileWidePeekImage02">
<image
id="1" src=""/>
<text
id="1"></text>
<text
id="2"></text>
<text
id="3"></text>
<text
id="4"></text>
<text
id="5"></text>
</binding>
</visual>
</tile>
TileTemplateType.TileWidePeekImage03
<tile>
<visual lang="en-US">
<binding
template="TileWidePeekImage03">
<image
id="1" src=""/>
<text
id="1"></text>
</binding>
</visual>
</tile>
TileTemplateType.TileWidePeekImage04
<tile>
<visual lang="en-US">
<binding
template="TileWidePeekImage04">
<image
id="1" src=""/>
<text
id="1"></text>
</binding>
</visual>
</tile>
TileTemplateType.TileWidePeekImage05
<tile>
<visual lang="en-US">
<binding
template="TileWidePeekImage05">
<image
id="1" src=""/>
<image
id="2" src=""/>
<text
id="1"></text>
<text
id="2"></text>
</binding>
</visual>
</tile>
TileTemplateType.TileWidePeekImage06
<tile>
<visual lang="en-US">
<binding
template="TileWidePeekImage06">
<image
id="1" src=""/>
<image
id="2" src=""/>
<text
id="1"></text>
</binding>
</visual>
</tile>
TileTemplateType.TileWideSmallImageAndText01
<tile>
<visual lang="en-US">
<binding
template="TileWideSmallImageAndText01">
<image
id="1" src=""/>
<text
id="1"></text>
</binding>
</visual>
</tile>
TileTemplateType.TileWideSmallImageAndText02
<tile>
<visual lang="en-US">
<binding
template="TileWideSmallImageAndText02">
<image
id="1" src=""/>
<text
id="1"></text>
<text
id="2"></text>
<text
id="3"></text>
<text
id="4"></text>
<text
id="5"></text>
</binding>
</visual>
</tile>
TileTemplateType.TileWideSmallImageAndText03
<tile>
<visual lang="en-US">
<binding
template="TileWideSmallImageAndText03">
<image
id="1" src=""/>
<text id="1"></text>
</binding>
</visual>
</tile>
TileTemplateType.TileWideSmallImageAndText04
<tile>
<visual lang="en-US">
<binding
template="TileWideSmallImageAndText04">
<image
id="1" src=""/>
<text
id="1"></text>
<text
id="2"></text>
</binding>
</visual>
</tile>
TileTemplateType.TileWideText01
<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>
TileTemplateType.TileWideText02
<tile>
<visual lang="en-US">
<binding
template="TileWideText02">
<text
id="1"></text>
<text
id="2"></text>
<text
id="3"></text>
<text
id="4"></text>
<text
id="5"></text>
<text
id="6"></text>
<text
id="7"></text>
<text
id="8"></text>
<text
id="9"></text>
</binding>
</visual>
</tile>
TileTemplateType.TileWideText03
<tile>
<visual lang="en-US">
<binding
template="TileWideText03">
<text
id="1"></text>
</binding>
</visual>
</tile>
TileTemplateType.TileWideText04
<tile>
<visual lang="en-US">
<binding
template="TileWideText04">
<text
id="1"></text>
</binding>
</visual>
</tile>
TileTemplateType.TileWideText05
<tile>
<visual lang="en-US">
<binding
template="TileWideText05">
<text
id="1"></text>
<text
id="2"></text>
<text
id="3"></text>
<text
id="4"></text>
<text
id="5"></text>
</binding>
</visual>
</tile>
TileTemplateType.TileWideText06
<tile>
<visual lang="en-US">
<binding
template="TileWideText06">
<text
id="1"></text>
<text
id="2"></text>
<text
id="3"></text>
<text
id="4"></text>
<text
id="5"></text>
<text
id="6"></text>
<text
id="7"></text>
<text
id="8"></text>
<text
id="9"></text>
<text
id="10"></text>
</binding>
</visual>
</tile>
TileTemplateType.TileWideText07
<tile>
<visual lang="en-US">
<binding
template="TileWideText07">
<text
id="1"></text>
<text
id="2"></text>
<text
id="3"></text>
<text
id="4"></text>
<text
id="5"></text>
<text
id="6"></text>
<text
id="7"></text>
<text
id="8"></text>
<text
id="9"></text>
</binding>
</visual>
</tile>
TileTemplateType.TileWideText08
<tile>
<visual lang="en-US">
<binding
template="TileWideText08">
<text
id="1"></text>
<text
id="2"></text>
<text
id="3"></text>
<text
id="4"></text>
<text
id="5"></text>
<text
id="6"></text>
<text
id="7"></text>
<text
id="8"></text>
<text
id="9"></text>
<text
id="10"></text>
</binding>
</visual>
</tile>
TileTemplateType.TileWideText09
<tile>
<visual lang="en-US">
<binding
template="TileWideText09">
<text
id="1"></text>
<text
id="2"></text>
</binding>
</visual>
</tile>
TileTemplateType.TileWideBlockAndText01
<tile>
<visual lang="en-US">
<binding
template="TileWideBlockAndText01">
<text
id="1"></text>
<text
id="2"></text>
<text
id="3"></text>
<text
id="4"></text>
<text
id="5"></text>
<text
id="6"></text>
</binding>
</visual>
</tile>
Summary
You can see that the business of updating a tile is fairly simple despite what
the official examples seem to suggest. You can
download the FirstTile
application from here. Keep an eye out for other examples including more dynamic
updates, Toast and more good stuff.