Embed a live tile in your Windows 10 app!

Have you ever wanted to display a preview of your live tile in your app's settings page, so the user can instantly see how your various settings will affect their live tile?

Introducing the PreviewTile control! The PreviewTile is a XAML control that replicates the Start tiles, and fully supports displaying adaptive tile notifications. This is the same control that we use in the Notifications Visualizer.

Using the PreviewTile control is simple. The API's to update properties and send notifications are very similar to the API's you already use for the actual live tiles.

How to use the PreviewTile

The short answer is to install the NuGet package "NotificationsVisualizerLibrary", utilize the NotificationsVisualizerLibrary namespace, and then use the PreviewTile control in your XAML/code.

1. Install the NuGet package

The NuGet package is located here. The easiest way to install it is to open Visual Studio, right click your project in Solution Explorer and select "Manage NuGet Packages...". Search for "NotificationsVisualizerLibrary", and install the package.

2. Add a preview tile to your XAML page

In order to add the PreviewTile to XAML, you'll have to add a new XAML namespace so you can reference the control.

 <Page
    x:Class="MyApp.SampleSettingsPage"
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    ...
    xmlns:visualizer="using:NotificationsVisualizerLibrary">

Then, you can add the control wherever you'd like. We recommend disabling animations via the IsAnimationEnabled property when using this on a settings page, so the user sees instant changes rather than seeing a new notification animate in.

 <visualizer:PreviewTile
    x:Name="WidePreviewTile"
    IsAnimationEnabled="False"
    TileSize="Wide"/>

3. Updating tile properties

In order to set tile properties like the display name, background color, or logos, you will have to use code. The API's are similar to the SecondaryTile API's (you set the properties, and then you call Update in order to actually commit your changes). You cannot use data binding, and you cannot set these properties via XAML, since the call to Update is required.

 tile.DisplayName = "CSC 252";
tile.VisualElements.BackgroundColor = Colors.Red;
tile.VisualElements.ShowNameOnSquare150x150Logo = true;
tile.VisualElements.Square150x150Logo = new Uri("ms-appx:///Assets/PlannerAssets/Square150x150Logo.png");
tile.VisualElements.Wide310x150Logo = new Uri("ms-appx:///Assets/PlannerAssets/Wide310x150Logo.png");
tile.VisualElements.Square44x44Logo = new Uri("ms-appx:///Assets/PlannerAssets/Square44x44Logo.png");

// Commit the tile properties we changed
await tile.UpdateAsync();

4. Sending notifications

Sending notifications is very similar to the tile API's. You'll obtain a PreviewTileUpdater by using the CreateTileUpdater() method, and then you'll use the updater to clear or send notifications.

The updater takes the exact same TileNotification object as real tiles do, so you can use the same code to generate your tile notification, and then simply pass that to the PreviewTileUpdater.

 // Create the updater
PreviewTileUpdater updater = tile.CreateTileUpdater();

// OPTIONAL: Clear the preview tile
updater.Clear();

// Create a notification via your normal app logic
TileNotification notif = CreateTileNotification();

// And send the notification to the preview tile
updater.Update(notif);

Known issues

  • Badge doesn't support glyphs, only integers
  • Tile queue isn't supported

Apps using this control

Let us know if your app is using this control, and we'll feature it here!

My Calendar Power Planner

Full sample

Here's the entire XAML and C# pages used to create the settings page you saw at the top.

 <Page
    x:Class="MyApp.SampleSettingsPage"
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MyApp"
    xmlns:d="https://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    xmlns:visualizer="using:NotificationsVisualizerLibrary">

    <ScrollViewer Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" VerticalScrollBarVisibility="Auto">

        <StackPanel Margin="20">
            
            <visualizer:PreviewTile
                x:Name="MediumPreviewTile"
                IsAnimationEnabled="False"/>
            
            <visualizer:PreviewTile
                x:Name="WidePreviewTile"
                IsAnimationEnabled="False"
                TileSize="Wide"
                Margin="0,6,0,0"/>
            
            <ToggleSwitch
                x:Name="ToggleShowHomework"
                Header="Show incomplete homework"
                Margin="0,24,0,0"
                IsOn="True"/>
            
            <ToggleSwitch
                x:Name="ToggleShowExams"
                Header="Show upcoming exams"
                Margin="0,12,0,0"
                IsOn="True"/>
            
        </StackPanel>
        
    </ScrollViewer>
</Page>
 using NotificationsExtensions.Tiles;
using NotificationsVisualizerLibrary;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.UI;
using Windows.UI.Notifications;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238

namespace MyApp
{
    /// 
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// 
    public sealed partial class SampleSettingsPage : Page
    {
        public SampleSettingsPage()
        {
            this.InitializeComponent();
        }

        protected override async void OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);

            foreach (var tile in AllTiles())
            {
                await UpdateTilePropertiesAsync(tile);
            }

            UpdateTileNotifications();

            ToggleShowExams.Toggled += ToggleShowExams_Toggled;
            ToggleShowHomework.Toggled += ToggleShowHomework_Toggled;
        }

        private async Task UpdateTilePropertiesAsync(PreviewTile tile)
        {
            tile.DisplayName = "CSC 252";
            tile.VisualElements.BackgroundColor = Colors.Red;
            tile.VisualElements.ShowNameOnSquare150x150Logo = true;
            tile.VisualElements.Square150x150Logo = new Uri("ms-appx:///Assets/PlannerAssets/Square150x150Logo.png");
            tile.VisualElements.Wide310x150Logo = new Uri("ms-appx:///Assets/PlannerAssets/Wide310x150Logo.png");
            tile.VisualElements.Square44x44Logo = new Uri("ms-appx:///Assets/PlannerAssets/Square44x44Logo.png");

            // Commit the tile properties we changed
            await tile.UpdateAsync();
        }

        private IEnumerable AllTiles()
        {
            return new PreviewTile[]
            {
                MediumPreviewTile,
                WidePreviewTile
            };
        }

        private void UpdateTileNotifications()
        {
            // If both are disabled, there's nothing to show on the tile
            if (!ToggleShowHomework.IsOn && !ToggleShowExams.IsOn)
            {
                // Clear current content
                foreach (var tile in AllTiles())
                    tile.CreateTileUpdater().Clear();

                return;
            }

            // Using NotificationsExtensions.Win10 NuGet package
            TileBindingContentAdaptive bindingContent = new TileBindingContentAdaptive();

            // NOTE: In a real app, this data would probably be dynamically generated from actual user data

            // Add the date header
            bindingContent.Children.Add(new TileText()
            {
                Text = "In two days"
            });

            // Add exams
            if (ToggleShowExams.IsOn)
            {
                bindingContent.Children.Add(new TileText()
                {
                    Text = "Exam 2",
                    Style = TileTextStyle.CaptionSubtle
                });
            }

            // Add homework
            if (ToggleShowHomework.IsOn)
            {
                bindingContent.Children.Add(new TileText()
                {
                    Text = "Bookwork Pg 37-39",
                    Style = TileTextStyle.CaptionSubtle
                });

                bindingContent.Children.Add(new TileText()
                {
                    Text = "Lab report 4",
                    Style = TileTextStyle.CaptionSubtle
                });
            }

            TileBinding binding = new TileBinding()
            {
                Content = bindingContent
            };

            TileContent content = new TileContent()
            {
                Visual = new TileVisual()
                {
                    TileMedium = binding,
                    TileWide = binding,

                    Branding = TileBranding.NameAndLogo
                }
            };

            // And send the notification
            foreach (var tile in AllTiles())
                tile.CreateTileUpdater().Update(new TileNotification(content.GetXml()));
        }

        private void ToggleShowHomework_Toggled(object sender, RoutedEventArgs e)
        {
            UpdateTileNotifications();
        }

        private void ToggleShowExams_Toggled(object sender, RoutedEventArgs e)
        {
            UpdateTileNotifications();
        }
    }
}