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="http://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!

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="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MyApp"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://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 http://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();
        }
    }
}
Comments (15)

  1. Albertos says:

    hello and thanks for this control, is it possile to use it with binding ? Thanks

  2. Albertos says:

    Ok anwser was here in this page...this is a great control but I have some little things : the tile generated is not exactky the same as one which is on start screen ( with strictly same XML). I don't why, for background. If I set color like this :  tile.VisualElements.BackgroundColor = Color.FromArgb(127,50,60,50); The background is always blue...

    Thanks

  3. andrewbares7 says:

    Hey Albertos, sorry for not replying earlier! I meant to reply, but then lost track of this.

    As you noticed, binding isn't supported since I decided to model the API structure to be similar to the actual tile API's.

    For the background color, is it still not working for you? You're calling UpdateAsync() after assigning the background color?

  4. Gabi says:

    Hi! Where is the link for download your demo?

    1. andrewbares7 says:

      Hey Gabi, whoops, the code went missing from this post during the transition to WordPress, sorry about that!!

      I've put the code back on this post, refresh it and you should see the code sample (the code is all on the blog, it's just MainPage XAML and C#.

      Thanks for letting us know it was missing!

      1. Tim says:

        Tiles on start screen are larger than the preview tiles I use in my (same size, same content) app. Text doesn't fit etc. ??

        1. andrewbares7 says:

          You can assign the Density property (I think it's called Density or TileDensity), and that will change what size the tile will appear.

          You can pick from a few different densities, TileDensity.Desktop(), TileDensity.Tablet(), and TileDensity.Mobile(150);

          Notice that the Mobile one takes a custom density number... Tile sizes on Mobile depend on the user's display scaling setting, the user's screen size/resolution, and the user's "Show more tiles" option. So the easiest thing to do is just leave the PreviewTile at 100 density since calculating all of that is next to impossible.

  5. Matthias H. says:

    First of all: Nice work 🙂
    Setting and updating the properties in Code is no Problem. When I'm trying to set and update the properties in the MainViewModel.cs (using mvvm-light) the changes won't be applied.

    1. andrewbares7 says:

      Hey Matthias, thanks!

      Correct, you need to call tile.UpdateAsync(); in order for any of the properties that you changed to take effect. I mimicked the real Live Tile API's, which behave this way. But for a UI control, maybe I should have simply had the properties instantly take effect like every other UI control does... would you prefer that pattern?

  6. Ed Boelzner says:

    Love this NotificationsVisualizerLibrary... but I have run into a little bug. When using the control to preview a tile (Wide), the background image is shrunk by about 5px's horizontally and shifted to the right. To reproduce, create a 620X300px image with a 1px border around it and you will see the difference between the control display and the actual live tile displayed on the start screen.

    1. andrewbares7 says:

      Ah yeah, good catch Ed! I need to update the control to use StretchToFill, rather than UniformToFill for the background image. Right now it crops rather than distorts to compensate for the different aspect ratio.

    2. andrewbares7 says:

      Submitted version 1.0.5 of the Nuget package to fix this! Should be available already!

      1. Ed Boelzner says:

        Thank you very much... I will update my project and let you know how I made out.

      2. Ed Boelzner says:

        Albertos,
        Under Visual Studio 2017 and using Microsoft.NETCore.UniversalWindowsPlatform v5.3.1; if the property IsAnimationEnabled="True", the tile will not update... even when clearing! If IsAnimationEnabled="False"; all works as expected.

        Would love to help in anyway I can...

        Regards,
        Ed

        1. andrewbares7 says:

          Hey Ed, sorry for the delay in response. I still have this on my list of things to look into, but haven't had enough time to look into this yet. When I look into it (hopefully in the next couple weeks), I'll let you know!

Skip to main content