Archived: Quickstart: Sending a local tile notification in Windows 10 (10586)


A tile begins as a default tile, which is defined in your manifest for a primary tile, and defined programmatically for a secondary tile. After a tile exists (your primary tile always exists, secondary tiles are created programmatically by your app's code), you can display notifications on your tile. 

Default Tile   With Notification

This Quickstart explains how to send a local tile notification to your primary tile in Windows 10 using adaptive tile templates. A local notification means that the notification is sent from the app’s code, rather than being pushed or pulled from a web server.

Note: Learn about adaptive tile templates

1. Install NuGet packages

We recommend installing NotificationsExtensions. Our code sample will use this package. We'll also provide the "Vanilla" code snippets that don't use any NuGet packages.

2. Add namespace declarations

Windows.UI.Notifications includes the tile APIs.

using Windows.UI.Notifications;
using NotificationsExtensions.Tiles; // NotificationsExtensions.Win10
using Windows.UI.Notifications;
using Windows.Data.Xml.Dom;

3. Create the notification content

In Windows 10, tile payloads are defined using adaptive tile templates, which allow you to create a custom visual layout for your notification. See the adaptive documentation to learn more about what's possible with adaptive. We recommend using NotificationsExtensions (the NuGet package we told you about) to generate these notification payloads, but alternatively you can go the "Vanilla" route and construct the XML by hand.

// In a real app, these would be initialized with actual data
string from = "Jennifer Parker";
string subject = "Photos from our trip";
string body = "Check out these awesome photos I took while in New Zealand!";


// Construct the tile content
TileContent content = new TileContent()
{
    Visual = new TileVisual()
    {
        TileMedium = new TileBinding()
        {
            Content = new TileBindingContentAdaptive()
            {
                Children =
                {
                    new TileText()
                    {
                        Text = from
                    },

                    new TileText()
                    {
                        Text = subject,
                        Style = TileTextStyle.CaptionSubtle
                    },

                    new TileText()
                    {
                        Text = body,
                        Style = TileTextStyle.CaptionSubtle
                    }
                }
            }
        },

        TileWide = new TileBinding()
        {
            Content = new TileBindingContentAdaptive()
            {
                Children =
                {
                    new TileText()
                    {
                        Text = from,
                        Style = TileTextStyle.Subtitle
                    },

                    new TileText()
                    {
                        Text = subject,
                        Style = TileTextStyle.CaptionSubtle
                    },

                    new TileText()
                    {
                        Text = body,
                        Style = TileTextStyle.CaptionSubtle
                    }
                }
            }
        }
    }
};
// In a real app, these would be initialized with actual data
string from = "Jennifer Parker";
string subject = "Photos from our trip";
string body = "Check out these awesome photos I took while in New Zealand!";

// TODO - all values need to be XML escaped

// Construct the tile content as a string
string content = $@"
<tile>
    <visual>

        <binding template='TileMedium'>
            <text>{from}</text>
            <text hint-style='captionSubtle'>{subject}</text>
            <text hint-style='captionSubtle'>{body}</text>
        </binding>

        <binding template='TileWide'>
            <text hint-style='subtitle'>{from}</text>
            <text hint-style='captionSubtle'>{subject}</text>
            <text hint-style='captionSubtle'>{body}</text>
        </binding>

    </visual>
</tile>";

The above notification content will look like the following when displayed on the Medium tile...

4. Create the notification

Once you have your notification content, you need to create a new TileNotification. The constructor takes a WinRT XmlDocument, which if you're using NotificationsExtensions, you can obtain from the GetXml() method on the TileContent class.

// Create the tile notification
var notification = new TileNotification(content.GetXml());
// Load the string into an XmlDocument
XmlDocument doc = new XmlDocument();
doc.LoadXml(content);

// Then create the tile notification
var notification = new TileNotification(doc);

5. Optional: Set an expiration time for the notification

By default, local tile and badge notifications do not expire and push, periodic, and scheduled notifications expire after three days. It is a best practice to set an expiration time, particularly on local tile and badge notifications, using a time that makes sense for your app. Your tile's content should not persist longer than it is relevant. In this case, the notification will expire and be removed from the tile in ten minutes.

tileNotification.ExpirationTime = DateTimeOffset.UtcNow.AddMinutes(10);

6. Send the notification

Sending a tile notification locally is quite simple, but it is slightly different depending on whether you're sending the notification to a primary or secondary tile.

To send a notification to a primary tile, simply use the TileUpdateManager to create a tile updater for the primary tile, and send the notification by calling "Update". Your primary tile always implicitly exists, so you can send notifications to it even when it's not pinned. If the user pins your primary tile later, the notifications you sent will appear.

To send a notification to a secondary tile, you'll first want to make sure the secondary tile exists. If you try to create a tile updater for a secondary tile that doesn't exist (for example, if the user unpinned the secondary tile), an exception will be thrown. You can use SecondaryTile.Exists(tileId) to discover if your secondary tile is pinned. Then you create a tile updater for the secondary tile and send the notification.

// And send the notification
TileUpdateManager.CreateTileUpdaterForApplication().Update(notification);
// If the secondary tile is pinned
if (SecondaryTile.Exists("MySecondaryTile"))
{
    // Get its updater
    var updater = TileUpdateManager.CreateTileUpdaterForSecondaryTile("MySecondaryTile");

    // And send the notification
    updater.Update(notification);
}
Default Tile   With Notification

7. Optional: Clear your tile's notifications

In most cases, you should clear a notification once the user has interacted with the content. For example, when the user launches your app, you might want to clear all the notifications from the tile. Note that if your notifications are time-bound, setting an expiration time on the notification is a better choice than explicitly clearing it.

TileUpdateManager.CreateTileUpdaterForApplication().Clear();

For a tile with the notification queue enabled and notifications in the queue, calling the Clear method empties the queue.

Note that you cannot clear a notification via your app's server. Only your local app's code can clear notifications. Periodic or push notifications can only add new notifications (or replace existing notifications). A local call to the Clear method will clear the tile regardless of whether the notifications themselves came via push, periodic, or local. Note that scheduled notifications that haven't yet appeared are NOT cleared by this method.

With Notification   After Clear

Next steps

Now that you've performed your first tile update, you can expand your tile's functionality by enabling a notification queue.

This Quickstart sent the tile update as a local notification. You can also explore the other methods of notification delivery: scheduled, periodic, and push. For more information, see Delivering notifications.

P.S. Here’s an XmlEncode method (not necessary if you use NotificationsExtensions)

public string XmlEncode(string text)
{
    StringBuilder builder = new StringBuilder();
    using (var writer = XmlWriter.Create(builder))
    {
        writer.WriteString(text);
    }

    return builder.ToString();
}

Resources

Skip to main content