Working with tiles in a Windows Store business app using C#, XAML, and Prism
[This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation]
Learn how to create an app tile that is updated by periodic notifications, and how to create secondary tiles and deep links to promote specific content from an app onto the Start screen. The AdventureWorks Shopper reference implementation demonstrates this, and how to launch the app from a secondary tile using Prism for the Windows Runtime.
After you download the code, see Getting started using Prism for the Windows Runtime for instructions on how to compile and run the reference implementation, as well as understand the Microsoft Visual Studio solution structure.
You will learn
- How to create and update an app tile with periodic notifications.
- How to pin and unpin secondary tiles to the Start screen from within an app.
- How to launch the app to a specific page from a secondary tile.
- Windows Runtime for Windows 8.1
- Extensible Application Markup Language (XAML)
Making key decisions
A tile is an app's representation on the Start screen and allows you to present rich and engaging content to your users when the app is not running. Tiles should be appealing to users in order to give them great first-impression of your Windows Store app. The following list summarizes the decisions to make when creating tiles for your app:
- Why should I invest in a live tile?
- How do I make a live tile compelling to users?
- What shape should my tile be?
- What size should my tile image be?
- Which tile templates should I use?
- What mechanism should I use to deliver tile notifications?
- How often should my live tile content change?
- Should my app include the ability to pin secondary tiles to Start?
Tiles can be live, meaning they are updated through notifications, or static. For info about tiles, including why you should invest in a live tile, how to make a live tile compelling to users, what shape and size a tile should be, which tile templates you should use, how often your live tile content should change, and secondary tiles, see Guidelines for tiles and badges, Tile and toast image sizes, The tile template catalog, Sending notifications, and Secondary tiles overview.
The choice of which mechanism to use to deliver a tile notification depends on the content you want to show and how frequently that content should be updated. Local notifications are a good way to keep the app tile current, even if you also use other notification mechanisms. Many apps will use local notifications to update the tile when the app is launched or when state changes within the app. This ensures that the tile is up-to-date when the app launches and exits. Scheduled notifications are ideal for situations where the content to be updated is known in advance, such as a meeting invitation. Periodic notifications provide tile updates with minimal web or cloud service and client investment, and are an excellent method of distributing the same content to a wide audience. Push notifications are ideal for situations where your app has real-time data or data that is personalized for your user. Push notifications are also useful in situations where the data is time-sensitive, and where the content is generated at unpredictable times. Periodic notifications offer the most suitable notification solution for side-loaded apps, but don't provide notifications on demand. In addition, with periodic notifications, after the initial poll to the web or cloud service Windows will continue to poll for tile updates even if your app is never launched again. For more info see Choosing a notification delivery method.
Note Push notifications use the Windows Push Notification Services (WNS) to deliver updates to users. Before you can send notifications using WNS, your app must be registered with the Windows Store Dashboard. For more info see Push notification overview.
Tiles in AdventureWorks Shopper
The AdventureWorks Shopper reference implementation includes medium and wide default tiles, which were created according to the pixel requirements for each. Choosing a small logo that represents your app is important so that users can identify it when the tile displays custom content. For more info see Creating app tiles.
The default tiles are made live by updating them with periodic notifications, at 30 minute intervals, to advertise specific products to users on their Start screen. The periodic notifications use peek templates so that the live tile will animate between two frames. The first frame shows an image of the advertised product, with the second frame showing product details. Both wide and medium peek tile templates are used. While AdventureWorks Shopper will default to the wide tile, it can be changed to the medium tile by the user. For more info see Using periodic notifications to update tile content.
AdventureWorks Shopper includes the ability to create secondary tiles by pinning specific products to the Start screen from the ItemDetailPage. The following diagram shows the two frames of a secondary tile created from one of the products sold in AdventureWorks Shopper.
Selecting a secondary tile launches the app and displays the previously pinned product on the ItemDetailPage. For more info see Creating secondary tiles.
Creating app tiles
Tiles begin as a default tile defined in the app's manifest. A static tile will always display the default content, which is generally a full-tile logo image. A live tile can update the default tile to show new content, but can return to the default if the notification expires or is removed. The following diagrams show the default small, medium, and wide logo images that can be found in the Assets folder in the AdventureWorks Shopper Visual Studio solution. Each logo has a transparent background. This is particularly important for the small logo so that it will blend in with tile notification content.
30 x 30 pixels
150 x 150 pixels
310 x 150 pixels
Note Image assets, including the logos, are placeholders and meant for training purposes only. They cannot be used as a trademark or for other commercial purposes.
The Visual Studio manifest editor makes the process of adding the default tiles easy. For more info see Quickstart: Creating a default tile using the Visual Studio manifest editor. For more info about working with image resources, see Quickstart: Using file or image resources and How to name resources using qualifiers.
If only a medium logo is provided in the app's manifest file, the app's tile will always be square. If both a medium and a wide logo are provided in the manifest, the app's tile will default to a wide tile when it is installed. You must decide whether you want to allow a wide tile as well. This choice is made by providing a wide logo image when you define your default tile in your app manifest.
Using periodic notifications to update tile content
Periodic notifications, which are sometimes called polled notifications, update tiles at a fixed interval by downloading content directly from a web or cloud service. To use periodic notifications your app must specify the Uniform Resource Identifier (URI) of a web location that Windows polls for tile updates, and how often that URI should be polled.
Periodic notifications require that your app hosts a web or cloud service. Any valid HTTP or Secure Hypertext Transfer Protocol (HTTPS) web address can be used as the URI to be polled by Windows. The following code example shows the GetTileNotification method in the TileNotificationController class in the AdventureWorks.WebServices project, which is used to send tile content to the AdventureWorks Shopper reference implementation.
public HttpResponseMessage GetTileNotification()
var tileXml = GetDefaultTileXml("https://localhost:2112/Images/hotrodbike_red_large.jpg",
"Mountain-400-W Red, 42");
tileXml = string.Format(CultureInfo.InvariantCulture, tileXml, DateTime.Now.ToShortDateString(), DateTime.Now.ToShortTimeString());
// create HTTP response
var response = new HttpResponseMessage();
// format response
response.StatusCode = System.Net.HttpStatusCode.OK;
response.Content = new StringContent(tileXml);
//Need to return xml format to TileUpdater.StartPeriodicUpdate
This method generates the XML tile content, formats it, and returns it as a HTTP response. The tile content must conform to the Tile schema and be 8-bit Unicode Transformation Format (UTF-8) encoded. The tile content is specified using the TileWidePeekImage01 and TileSquarePeekImageAndText02 templates. This is necessary because while the app will use the wide tile by default, it can be changed to the square tile by the user. For more info see The tile template catalog.
At a polling interval of 30 minutes, Windows sends an HTTP GET request to the URI, downloads the requested tile content as XML, and displays the content on the app's tile. This is accomplished by the OnInitialize method in the App class, as shown in the following code example.
_tileUpdater = TileUpdateManager.CreateTileUpdaterForApplication();
_tileUpdater.StartPeriodicUpdate(new Uri(Constants.ServerAddress + "/api/TileNotification"), PeriodicUpdateRecurrence.HalfHour);
A new TileUpdater instance is created by the CreateTileUpdaterForApplication method in the TileUpdateManager class, in order to update the app tile. By default, a tile on the Start screen shows the content of a single notification until it is replaced by a new notification. However, you can enable notification cycling so that up to five notifications are maintained in a queue and the tile cycles through them. This is accomplished by calling the EnableNotificationQueue method with a parameter of true, on the TileUpdater instance. Finally, a call to StartPeriodicUpdate is made to poll the specified URI in order to update the tile with the received content. After this initial poll, Windows will continue to provide updates every 30 minutes, as specified. Polling then continues until you explicitly stop it, or your app is uninstalled. Otherwise Windows will continue to poll for updates to your tile even if your app is never launched again.
Note While Windows makes a best effort to poll as requested, the interval is not precise. The requested poll interval can be delayed by up to 15 minutes.
By default, periodic tile notifications expire three days from the time they are downloaded. Therefore, it is recommended that you set an expiration on all periodic tile notifications, using a time that makes sense for your app, to ensure that your tile's content does not persist longer than it's relevant. This also ensures the removal of stale content if your web or cloud service becomes unreachable, or if the user disconnects from the network for an extended period of time. This is accomplished by returning the X-WNS-Expires HTTP header to specify the expiration date and time.
Creating secondary tiles
A secondary tile allows a user to launch to a specific location in an app directly from the Start screen. Apps cannot pin secondary tiles programmatically without user approval. Users also have explicit control over secondary tile removal. This allows users to personalize their Start screen with the experiences that they use the most.
Secondary tiles are independent of the main app tile and can receive tile notifications independently. When a secondary tile is activated, an activation context is presented to the parent app so that it can launch in the context of the secondary tile.
The option to create a secondary tile is seen on the bottom app bar of the ItemDetailPage as the Pin to Start app bar button. This enables you to create a secondary tile for the product being displayed. Selecting the secondary tile launches the app and displays the previously pinned product on the ItemDetailPage. The following diagram shows an example of the flyout that is displayed when you select the Pin to Start button. The flyout shows a preview of the secondary tile, and asks you to confirm its creation.
Pinning and unpinning secondary tile functionality is provided by the SecondaryTileService class, which implements the ISecondaryTileService interface. In the OnInitialize method in the App class, the SecondaryTileService class is registered as a type mapping against the ISecondaryTileService type with the Unity dependency injection container. Then, when the ItemDetailPageViewModel class is instantiated, which accepts an ISecondaryTileService type, the Unity container will resolve the type and return an instance of the SecondaryTileService class.
The workflow AdventureWorks Shopper uses to pin a secondary tile to Start is as follows:
You invoke the PinProductCommand through the Pin to Start app bar button on the ItemDetailPage.
PinProductCommand = DelegateCommand.FromAsyncHandler(PinProduct, () => SelectedProduct != null);
AdventureWorks Shopper checks to ensure that the tile hasn't already been pinned by calling the SecondaryTileExists predicate in the SecondaryTileService instance.
bool isPinned = _secondaryTileService.SecondaryTileExists(tileId);
AdventureWorks Shopper calls the PinWideSecondaryTile method in the SecondaryTileService instance to create a secondary tile. The SelectedProduct.ProductNumber property is used as a unique ID.
isPinned = await _secondaryTileService.PinWideSecondaryTile(tileId, SelectedProduct.Title, SelectedProduct.ProductNumber);
The PinWideSecondaryTile method creates a new instance of the SecondaryTile class, providing information such as the short name, the display name, the logo, and more.
var secondaryTile = new SecondaryTile(tileId, displayName, arguments, _squareLogoUri, TileSize.Wide310x150); secondaryTile.VisualElements.ShowNameOnWide310x150Logo = true; secondaryTile.VisualElements.Wide310x150Logo = _wideLogoUri;
The RequestCreateAsync method is called on the SecondaryTile instance to display a flyout that shows a preview of the tile, asking you to confirm its creation.
bool isPinned = await secondaryTile.RequestCreateAsync();
You confirm and the secondary tile is added to the Start screen.
The workflow AdventureWorks Shopper uses to unpin a secondary tile from Start is as follows:
AdventureWorks Shopper invokes the UnpinProductCommand through the Unpin from Start app bar button on the ItemDetailPage.
UnpinProductCommand = DelegateCommand.FromAsyncHandler(UnpinProduct, () => SelectedProduct != null);
AdventureWorks Shopper checks to ensure that the tile hasn't already been unpinned by calling the SecondaryTileExists predicate in the SecondaryTileService instance.
bool isPinned = _secondaryTileService.SecondaryTileExists(tileId);
AdventureWorks Shopper calls the UnpinTile method on the SecondaryTileService instance to remove the secondary tile. The tile can be identified by the SelectedProduct.ProductNumber property as the unique ID.
isPinned = (await _secondaryTileService.UnpinTile(tileId)) == false;
The UnpinTile method creates a new instance of the SecondaryTile class, using the SelectedProduct.ProductNumber property as the unique ID. By providing an ID for an existing secondary tile, the existing secondary tile will be overwritten.
var secondaryTile = new SecondaryTile(tileId);
The RequestDeleteAsync method is called on the SecondaryTile instance to display a flyout that shows a preview of the tile to be removed asking you to confirm its removal.
bool isUnpinned = await secondaryTile.RequestDeleteAsync();
You confirm and the secondary tile is removed from the Start screen.
Note Secondary tiles can also be removed through the Start screen app bar. When this occurs the app is not contacted for removal information, the user is not asked for a confirmation, and the app is not notified that the tile is no longer present. Any additional cleanup action that the app would have taken in unpinning the tile must be performed by the app at its next launch.
Launching the app from a secondary tile
Whenever the app is launched the OnLaunched method in the MvvmAppBase class is called (the MvvmAppBase class is provided by the Microsoft.Practices.Prism.StoreApps library). The LaunchActivatedEventArgs parameter in the OnLaunched method will contain the previous state of the app and the activation arguments. If the app is launched by its primary tile, the TileId property of the LaunchActivatedEventArgs parameter will have the same value as the application Id in the package manifest. If the app is launched by a secondary tile, the TileId property will have an ID that was specified when the secondary tile was created. The OnLaunched method in the MvvmAppBase class will call the OnLaunchApplication method in the App class only if the app is not resuming following suspension, or if the app was launched through a secondary tile. The OnLaunchApplication method, which is shown in the following code example, provides app specific launch behavior.
protected override Task OnLaunchApplication(LaunchActivatedEventArgs args)
if (args != null && !string.IsNullOrEmpty(args.Arguments))
// The app was launched from a Secondary Tile
// Navigate to the item's page
// Navigate to the initial page
In this method the LaunchActivatedEventArgs parameter contains the previous state of the app and the activation arguments. If the app is being launched from the app tile then the activation Arguments property will not contain any data and so the HubPage will be navigated to. If the app is being launched from a secondary tile then the activation Arguments property will contain the product number of the product to be displayed. The ItemDetailPage will then be navigated to, with the product number being passed to the OnNavigatedTo override in the ItemDetailPageViewModel instance, so that the specified product is displayed.