This post is a part of a series of posts about the Social Media Dashboard Sample. This post was written by Dag König. For an introductionary blog post, click here.

Live Tiles are unique features that are available for both Windows 8 and Windows Phone. One can do very exciting things with them and it is an easy way to get their app stand out in the crowd. In the Social Media Dashboard Template (SMD), we have made it possible to create Live Tiles for both platforms.

SMD shows the latest post in a module in config.json, which there is one for each platform. This file is located in Assets/Config and it can looks like this.

{
    "appname" : "Windows Phone Developer News",
    "abouttext" : "This app shows information about Windows Phone development, including blogs, tutorial videos and tweets.",
    "privacypolicy" : "<TODO: insert your privacy policy here>",
    "privacypolicylink" : "<TODO: insert link to your privacy policy here>",
    "livetilemodule" : 3,
    "modules" : [
        { "type" : "customfeed-multi", "parameter": "Assets\\CustomFeeds\\windowsphone.json", "title": "" },
        { "type" : "blog-feed", "parameter": "http://blogs.windows.com/windows_phone/b/wpdev/rss.aspx", "title": "Windows Phone Developer blog" },
        { "type" : "youtube-query", "parameter": "windows phone development tutorial", "parameter2" : "", "title" : "Tutorial Videos" },
        { "type" : "flickr-query", "parameter": "lumia", "title": "Images" },
        { "type" : "twitter-query", "parameter": "wpdev", "title": "Tweets" },
    ],
}

In this post, we are only interested in the parameter livetilemodule. It saves the index, of the module in the list below, which should be the source of the Live Tile. (Set it to -1 to turn it off.)

Windows 8

The following diagram introduces the program flow for Windows 8. (I will not describe the whole flow.)

clip_image002_thumb[2]

LoadData is called once and it instantiate each module that is displayed in the app. For each module, it checks if it is the active Live Tile module and then calls Get<module type>Async. In my example, I show the method that instantiate a blog module with GetBlogPostAsync.

public static async Task LoadData(Config configuration)
{
    bool enableLiveTile = false;
    List<Task> tasks = new List<Task>();

    foreach (Module m in configuration.modules)
    {
        var moduleIndex = configuration.modules.IndexOf(m);
        if (configuration.livetilemodule == moduleIndex)
            enableLiveTile = true;
        else
            enableLiveTile = false;

        if (m.type == "youtube-channel")
        else if (m.type == "youtube-query") 
    else if (m.type == "blog-feed")
            tasks.Add(_hubDataSource.GetBlogPostsAsync(m.title, 
                      m.parameter, m.parameter2, moduleIndex, enableLiveTile));
...
}

GetBlogPostAsync retrieves the blog entries that from feedURIString. The app displays the blog if it exist and returns any items. If Live Tile is enabled for that module, it will then call ShowLiveTile.
public async Task GetBlogPostsAsync(string title, string feedURIString, string specificauthor, int moduleIndex, bool enableLiveTile)
{

    try
    {
        var postDataObject = await WebDataHelper.GetBlogPostsAsync(feedURIString);
        if (postDataObject.DataObjects.Count > 0)
        {
           ...
            if (group.Items.Count > 0)
            {
                this.AllGroups.Add(group);
                SortGroups();
                if (enableLiveTile)
                    ((BlogPostDataItem)group.Items[0]).ShowLiveTile();
            }
        }
    }
...
}

ShowLiveTile creates the Live Tile. This method is unique for each module type. ShowLiveTile is defined in an abstract class called HubDataItem and is inherited to a concrete class for each module type, in this example BlogPostDataItem. (See the diagram above.)

public override void ShowLiveTile()
{
    ITileWideBlockAndText02 tileContent = TileContentFactory.CreateTileWideBlockAndText02();
    tileContent.TextBodyWrap.Text = Title;
    tileContent.TextBlock.Text = PubDate.Day.ToString();
    DateTimeFormatter dateFormatter = new DateTimeFormatter("{month.abbreviated(3)}");
    tileContent.TextSubBlock.Text = dateFormatter.Format(PubDate);
    ITileSquareText01 squareContent = TileContentFactory.CreateTileSquareText01();
    squareContent.TextBody1.Text = Title;
    tileContent.SquareContent = squareContent;
    TileUpdateManager.CreateTileUpdaterForApplication().Update(tileContent.CreateNotification());
}

TileContentFactory is a helper class that creates an object based on a specific template. This class is part of a library called NotificationExtensions. (Windows 8 has several tile templates to choose from. Here is a catalog of them.)

With the method CreateTileWideBlockAndText02, we create a TileWideBlockAndText2 tile which is a tile with one string of regular text wrapped over a maximum of four lines on the left; large block text over a single, short string of bold, regular text on the right.

clip_image004_thumb[1]

The returning object tileContent, contains properties for the fields in the tile. TextBodyWrap is the text on the left; TextBlock is the large text on the right and TextSubBlock is the field below that text.

To support both wide and square tiles we need also to create a tile for the square tile. We do that next by calling CreateTileSquareText01 to get a tile with two fields, called TileSquareText01.

clip_image006_thumb[1]

With the method tileContent.SquareContent we add this tile to the tile definition in tileContent. Therefore, tileContent contains definitions for two tiles, one for the wide tile and one for the square tile.

Last, TileUpdateManager.CreateTileUpdaterForApplication().Update is called to register this tile with the system.

Windows Phone 8

If you compare this diagram with that above you see that it is very similar. The biggest difference between them are how they create and register the tile.

clip_image008_thumb[2]

The method ShowLiveTile look like this for Windows Phone.

public override void ShowLiveTile()
{
    ShellTile PrimaryTile = ShellTile.ActiveTiles.First();

    if (PrimaryTile != null)
    {
        StandardTileData tile = new StandardTileData();
        tile.BackBackgroundImage = new Uri("assets/TransparentImage.png", UriKind.Relative);
        tile.BackContent = this.Title;
        tile.BackTitle = this.Publisher;
        PrimaryTile.Update(tile);
    }
}

With ShellTile.ActiveTiles.First() we ask for the first tile in the collection ActiveTiles. It will at least contains one item, the primary tile.

Then we instantiate a new StandardTileData that we use to populate the tile with information.

Comment

In this example, we use the classes that exist in Windows Phone 7.x. They are still supported, but do not have support for the new tiles that was introduced in Windows Phone 8: FlipTileData, IconicTileData and CycleTileData. Read more here about the new tile features that Windows Phone 8 has.

Depending on the module type, we use different properties on StandardTileData. Last, we update the primary tile by calling Update(tile) with the StandardTileData as the parameter.

Links

· Tiles and notifications for Windows Phone

· Working with tiles, badges, and toast notifications (Windows Store apps using C#/VB/C++ and XAML)