Using Live Tiles on the Phone

patterns & practices Developer Center

On this page: Download:
You Will Learn | Overview of the Solution | Inside the Implementation - The Application Tile, Secondary Tiles Download code samples
Download book as PDF

You Will Learn

  • How to update an Application Tile on Start from an application.
  • How to create a secondary Tile on Start from an application.
  • How to navigate to the correct application page when a secondary Tile is tapped.

The Tailspin mobile client must be able to support pinning Tiles to Start. This section describes how Tailspin designed and implemented this functionality.

A Tile is a link to an application displayed in Start. There are two types of Tiles:

  1. The Application Tile is the Tile created when a user pins an application to Start. Tapping a pinned Application Tile navigates the user to the application's opening page.
  2. A secondary Tile is created programmatically by an application based on an interaction from the user. A typical use for a secondary Tile is to pin a page other than the homepage to Start, for quick access. The application's code provides the Tile with launch parameters to customize the navigation destination of the Tile. For example, tapping on a secondary Tile that represents a survey would open the survey in the Tailspin mobile client application.
Hh821023.note(en-us,PandP.10).gifChristine Says:
Christine
                You can have secondary Tiles for an application on Start without having an Application Tile.</td>

An Application Tile can be created by the user only when the user taps and holds the application name in the Application List and then selects pin to start. Therefore, when an Application Tile is created, the application is already deactivated. Secondary Tiles can be created only as a result of user input in the application, and when a secondary Tile is created, the application is deactivated. For more information see, "Tiles Overview for Windows Phone," on MSDN.

Tiles are two-sided and display information by flipping between the front and back sides of the Tile.

The elements on the front of a Tile are:

  • A background PNG or JPG image for the Tile that should be 173 pixels wide by 173 pixels high
  • A title string that overlays the background image
  • A count value that overlays the background image; for example, the number of new surveys available

The elements on the back of a Tile are:

  • A background PNG or JPG image for the Tile that should be 173 pixels wide by 173 pixels high
  • A title string that overlays the background image at the bottom of the Tile
  • A content string that overlays the background image in the body of the back of the Tile

If none of the properties on the back side of the Tile are set, the Tile will not flip over and only the front side of the Tile will be displayed. For guidelines about how to design a Tile, see the “Start Tiles” section in “Essential Graphics, Visual Indicators, and Notifications for Windows Phone” on MSDN.

Overview of the Solution

There are two separate pinning scenarios that Tailspin wanted the mobile client to support:

  • The mobile client must be capable of pinning an Application Tile to Start that includes a count of the number of new surveys that have been downloaded since the application was last opened. Tapping the tile should launch the application. In addition, when the application is deactivated, the count value on the Application Tile should be reset.
  • The mobile client must be capable of pinning surveys to secondary Tiles on Start. Each secondary Tile should contain a title string that represents the survey name. Tapping the tile should launch the application and navigate the user to the page containing the survey.

Based upon these scenarios, it was not necessary to use two-sided tiles.

Inside the Implementation

Now is a good time to walk through the code that implements live tiles in more detail. As you go through this section, you may want to download the Windows Phone Tailspin Surveys application from the Microsoft Download Center.

The Application Tile

The RunPeriodicTask method of the ScheduledAgent class calls the GetNewSurveys method of the SurveysSynchronization class. The GetNewSurveys method downloads new surveys from the Tailspin cloud service through the background agent. In addition, it is responsible for updating the Application Tile Count property that represents the number of new surveys that have been downloaded since the application was last opened. The following code example shows the GetNewSurveys method.

public IObservable<TaskCompletedSummary> GetNewSurveys(ISurveyStore surveyStore)
{
  var getNewSurveys =
    surveysServiceClientFactory()
    .GetNewSurveys(surveyStore.LastSyncDate)
    .Select(surveys =>
    {
      surveyStore.SaveSurveyTemplates(surveys);

      ...

      var tile = ShellTile.ActiveTiles.First();
      var tileData = new StandardTileData()
      {
        Count = this.UnopenedSurveyCount
      };
      tile.Update(tileData);

      ...
    })
    ...

    return getNewSurveys;
}

The method retrieves the Tile for the application and then updates the Count property of the Tile to the value of the UnopenedSurveyCount property, which is the number of surveys that have been downloaded since the mobile client application was deactivated, before updating the Tile on Start.

The UnopenedSurveyCount property simply retrieves the value of the UnopenedCount property in the SurveysList class. The GetNewSurveys method calls the SaveSurveyTemplates method to save the newly downloaded surveys and the SaveSurveyTemplates method updates the UnopenedCount property. The following code example shows the SaveSurveyTemplates method.

public void SaveSurveyTemplates(IEnumerable<SurveyTemplate> surveys)
{
  foreach (var s in surveys)
  {
    s.IsNew = true;
  }

  var newSurveys = surveys.Where(ns => !AllSurveys.Templates.Any(
    s => s.SlugName == ns.SlugName && s.Tenant == ns.Tenant));

  AllSurveys.UnopenedCount += newSurveys.Count();
  SaveUnopenedCount();

  AllSurveys.Templates.AddRange(newSurveys);
  SaveTemplates();
}

The method marks each downloaded survey as new, through the SurveyTemplate.IsNew property. It then builds a collection of new surveys before incrementing the UnopenedCount property of the AllSurveys collection by the number of surveys in the newSurveys collection. The call to the SaveUnopenedCount method saves the value of the UnopenedCount property to isolated storage.

Hh821023.note(en-us,PandP.10).gifJana Says:
Jana Downloaded surveys are marked as new until the user has opened them. Then they are marked as read.

As has been previously mentioned, the count value on the Application Tile represents the number of new surveys that have been downloaded since the application was last opened. When the mobile client application is closed by the user navigating backwards past the first page of the application, the ResetUnopenedSurveyCount method of the SurveyListViewModel is called, which resets the count value on the Application Tile. The following code example shows the ResetUnopenedSurveyCount method.

public void ResetUnopenedSurveyCount()
{
  synchronizationService.UnopenedSurveyCount = 0;
  var tile = shellTile.ActiveTiles.First();
  var tileData = new StandardTileData()
  {
    Count = 0
  };
  tile.Update(tileData);
}

The method resets the UnopenedSurveyCount property of the SurveysSynchronizationService class to 0, which updates both the AllSurveys collection and isolated storage. The method then retrieves the Application Tile for the application and resets the Count property of the Tile to 0, before updating the Tile on Start.

Secondary Tiles

Surveys can be pinned to Start as secondary Tiles from two locations in the mobile client application.

  • From a context MenuItem on each survey in the SurveyListView. This binds to the PinCommand property in the SurveyTemplateViewModel class.
  • From an ApplicationBarButtonCommand in the TakeSurveyView. This binds to the PinCommand property in the TakeSurveyViewModel.

The following code example shows the initialization of the PinCommand property from the SurveyTemplateViewModel class, and the Actions executed by it.

private readonly IShellTile shellTile;
public DelegateCommand PinCommand { get; set; }
...

public SurveyTemplateViewModel(
    SurveyTemplate surveyTemplate,
    INavigationService navigationService,
    IPhoneApplicationServiceFacade phoneApplicationServiceFacade,
    IShellTile shellTile,
    ILocationService locationService)
{
  ...
  this.shellTile = shellTile;
  ...
  
  this.PinCommand = new DelegateCommand(PinToStart, () => IsPinnable);  
  ...
}

public bool IsPinnable
{
  get
  {
    return shellTile.ActiveTiles.FirstOrDefault(
      x => x.NavigationUri.ToString() == 
     string.Format(Constants.PinnedSurveyUriFormat, 
     this.Template.SlugName)) == null;
  }
}

public void PinToStart()
{
  var tile = shellTile.ActiveTiles.FirstOrDefault(
    x => x.NavigationUri.ToString() == 
    string.Format(Constants.PinnedSurveyUriFormat, 
    this.Template.SlugName));
  if (tile == null)
  {
    var tileData = new StandardTileData
    {
      Title = this.Template.Title,
      BackgroundImage = new Uri("/Background.png", UriKind.Relative)
    };

    shellTile.Create(new Uri(string.Format(
      Constants.PinnedSurveyUriFormat, this.Template.SlugName), 
      UriKind.Relative), tileData);
  }
}

In the SurveyTemplateViewModel constructor the PinCommand is initialized so that its execute Action is set to the PinToStart method, and it can execute Action is set to the IsPinnable property.

The IsPinnable property checks to see if the survey is already pinned to Start by comparing the NavigationUri of each secondary Tile to a string that will be the NavigationUri of the survey. If the two match, the property is set to false and the user will not be given the option to pin the survey.

The PinToStart method checks if the survey is already pinned to Start by comparing the NavigationUri of each secondary Tile to a string that will be the NavigationUri of the survey. If the survey is not present on Start, a new secondary Tile is pinned to Start by a call to shellTile.Create. The Tile data includes a title string and a background image. A launch parameter is also specified in order to specify that the navigation destination of the Tile is the survey represented by its SlugName.

When the user attempts to pin a survey from the TakeSurveyView, the PinCommand in the TakeSurveyViewModel class examines the IsPinnable property in the SurveyTemplateViewModel class to see if the survey can be pinned and if it can be, the PinToStart method in the SurveyTemplateViewModel class is executed.

The following code example shows the OnNavigatedTo method in the TakeSurveyView class. When the user taps on a secondary Tile, this method is called.

protected override void OnNavigatedTo(NavigationEventArgs e)
{
  if (((TakeSurveyViewModel)this.DataContext).TemplateViewModel == null)
  {
    string surveyId;
    if (NavigationContext.QueryString.ContainsKey("surveyID"))
    {
      surveyId = NavigationContext.QueryString["surveyID"];
    }
    else
    {
      surveyId = (string)PhoneApplicationService.Current.State["TakeSurveyId"];
    }

    ((TakeSurveyViewModel)this.DataContext).Initialize(surveyId);
  }
}

This method checks whether the page is being navigated to from the secondary Tile by checking if the TemplateViewModel is null. If it is, it checks if the QueryString contains a surveyID and retrieves the surveyID from the QueryString if this is the case. Otherwise, it retrieves the surveyID from the application state dictionary. It then initializes the DataContext by calling an overload of the Initialize method that takes the surveyID as a parameter. The outcome is that the specified survey is loaded and navigated to.

Next Topic | Previous Topic | Home

Last built: May 25, 2012