How to pin a HubTile to start screen

How to pin a HubTile to start screen

One of the questions on my blog (I love when people ask smart questions and leave nice comments :) ) was how to pin a hubtile to start screen, as a normal live tile. This post will describe the method, continuing on the article about the hubtiles I wrote earlier. I created a few hubtiles in that article and now I want to be able to pin the hubtile by using the context menu on hold event, to resemble the usual procedure for pinning. For the purpose of this article, we will use the ContextMenu that opens on hold with only one MenuItem – “pin to start” which then pins the hubtile as a secondary live tile on start screen.

If you don’t really feel like reading my old article about HubTiles, let me get you up to speed. We used 5 hubtiles defined in XAML using the images that are part of the official hubtile example that comes with the Silverlight toolkit. Every hubtile has a ContextMenu attached to it. The XAML code is:

<Grid>  
  <Grid.RowDefinitions>
      <RowDefinition Height="Auto" />
      <RowDefinition Height="Auto" />
      <RowDefinition Height="Auto" />
  </Grid.RowDefinitions>
  <Grid.ColumnDefinitions>
      <ColumnDefinition Width="Auto"/>
      <ColumnDefinition Width="Auto"/>
  </Grid.ColumnDefinitions>
  <toolkit:HubTile Grid.Row="0"
                      Grid.Column="0"
                      GroupTag="hubs"
                      Source="Images/Shrimp.jpg"
                      Title="Shrimp"
                      Background="Red"
                      Message="I love shrimps"
                      Margin="0,0,10,10"
                      Name="ShrimpTile"
                      Hold="ShrimpTile_Hold">
      <toolkit:ContextMenuService.ContextMenu>
          <toolkit:ContextMenu x:Name="menu">
              <toolkit:MenuItem Header="pin to start" Tap="MenuItem_Tap"/>
          </toolkit:ContextMenu>
      </toolkit:ContextMenuService.ContextMenu>
  </toolkit:HubTile>

  <toolkit:HubTile Grid.Row="0"
                      Grid.Column="1"
                      GroupTag="hubs"
                      Source="Images/Dessert.jpg"
                      Title="Dessert"
                      Background="Blue"
                      Message="I love desserts"
                      Margin="0,0,10,10"
                      Name="DessertTile">
      <toolkit:ContextMenuService.ContextMenu>
          <toolkit:ContextMenu x:Name="menu1">
              <toolkit:MenuItem Header="pin to start" Tap="MenuItem1_Tap" />
          </toolkit:ContextMenu>
      </toolkit:ContextMenuService.ContextMenu>
  </toolkit:HubTile>

  <toolkit:HubTile Grid.Row="1"
                      Grid.Column="0"
                      GroupTag="hubs"
                      Source="Images/Seattle.jpg"
                      Title="Seattle"
                      Message="I'll go to Seattle"
                      Background="Gold"
                      Margin="0,0,10,10"
                      Name="SeattleTile"
                      Tap="SeattleTap">
      <toolkit:ContextMenuService.ContextMenu>
          <toolkit:ContextMenu x:Name="menu2">
              <toolkit:MenuItem Header="pin to start" Tap="MenuItem2_Tap"/>
          </toolkit:ContextMenu>
      </toolkit:ContextMenuService.ContextMenu>
  </toolkit:HubTile>

  <toolkit:HubTile Grid.Row="1"
                      Grid.Column="1"
                      GroupTag="hubs"
                      Source="Images/Venice.jpg"
                      Title="Venice"
                      Background="Green"
                      Message="I'll go to Venice in the meantime"
                      Name="VeniceTile"
                      Margin="0,0,10,10">
      <toolkit:ContextMenuService.ContextMenu>
          <toolkit:ContextMenu x:Name="menu3">
              <toolkit:MenuItem Header="pin to start" Tap="MenuItem3_Tap"/>
          </toolkit:ContextMenu>
      </toolkit:ContextMenuService.ContextMenu>
  </toolkit:HubTile>

  <toolkit:HubTile Grid.Row="2"
                      Grid.Column="0"
                      GroupTag="hubs"
                      Source="Images/Pretzel.jpg"
                      Title="Pretzels"
                      Background="Magenta"
                      Message="Pretzels are good for breakfast"
                      Name="PretzelTile"
                      Margin="0,0,10,10">
      <toolkit:ContextMenuService.ContextMenu>
          <toolkit:ContextMenu x:Name="menu4">
              <toolkit:MenuItem Header="pin to start" Tap="MenuItem4_Tap"/>
          </toolkit:ContextMenu>
      </toolkit:ContextMenuService.ContextMenu>
  </toolkit:HubTile>
</Grid>  

This code is pretty much copy pasted from my old article, except for one important thing – every hubtile now has a ContextMenu, such as this one:

<toolkit:ContextMenuService.ContextMenu>  
      <toolkit:ContextMenu x:Name="menu">
          <toolkit:MenuItem Header="pin to start" Tap="MenuItem_Tap"/>
      </toolkit:ContextMenu>
 </toolkit:ContextMenuService.ContextMenu>

with only one MenuItem that reacts to Tap event with the MenuItem_Tap event handler. Each hubtile has it’s own MenuItem tap event handler, which calls the main function for creating the secondary live tile, called CreateLiveTile.

The code behind for the MainPage.xaml is very simple, and consists of all the MenuItem tap event handlers:

private void MenuItem_Tap(object sender, System.Windows.Input.GestureEventArgs e)  
{
  CreateLiveTile(ShrimpTile);
}

private void MenuItem1_Tap(object sender, System.Windows.Input.GestureEventArgs e)  
{
 CreateLiveTile(DessertTile);
}

private void MenuItem2_Tap(object sender, System.Windows.Input.GestureEventArgs e)  
{
  CreateLiveTile(SeattleTile);
}

private void MenuItem3_Tap(object sender, System.Windows.Input.GestureEventArgs e)  
{
  CreateLiveTile(VeniceTile);
}

private void MenuItem4_Tap(object sender, System.Windows.Input.GestureEventArgs e)  
{
  CreateLiveTile(PretzelTile);
}

It’s clear what all the event handlers are doing – calling the CreateLiveTile method with only one parameter – the reference to the hubtile which should get pinned.

The CreateLiveTile is where all the magic happens. :) Let’s first look at the sample code for creating a secondary live tile at the MSDN documentation. Basically, I first get all the tiles from the Phone and check if there’s already a tile which has the NavigationUri property the same as the one I’m trying to create. Why does the secondary tile need the NavigationUri property at all? It’s because I’m creating those tiles to take me to different parts and functionalities of the app, and it’s what makes secondary tiles different. Since this is just a short article and demo, and not a real Marketplace app, every pinned tile will have NavigationUri taking me to MainPage.xaml, but will have a different passing parameter – it will be the hubtile Title, which ensures that I can pin all the five hubtiles.

So, if a tile with such a NavigationUri doesn’t exist, I create it. In other words, I first create a new StandardTileData object from the hubtile I want to pin:

private void CreateLiveTile(HubTile hubtile)  
{

StandardTileData LiveTile = new StandardTileData  
{
  BackgroundImage = ((System.Windows.Media.Imaging.BitmapImage)hubtile.Source).UriSource,
  Title = hubtile.Title,
  BackTitle = hubtile.Title,
  BackContent = hubtile.Message
};

Then I check to see if the tile already exists. If it doesn’t, I create it, and if it does, I show a MessageBox saying the the tile has already been pinned:

ShellTile Tile = ShellTile.ActiveTiles.FirstOrDefault(x => x.NavigationUri.ToString().Contains("DefaultTitle=" + LiveTile.Title));  
if (Tile == null)  
{
  try
  {
      ShellTile.Create(new Uri("/MainPage.xaml?DefaultTitle=" + LiveTile.Title, UriKind.Relative), LiveTile);
  }
  catch (Exception)
  {
      MessageBox.Show("I prefer not to be pinned");
  }
}
{
else MessageBox.Show("The tile is already pinned");  
}

So this is it – now you know how to pin a hubtile to startscreen using a context menu. The only thing that’s different is that every live tile that you pinned has the background color the same as the accent color of your phone. This is because we didn’t set the Background property of the StandardTileData object. In a hubtile you set the background as a brush by simply naming it, and in a StandardTileData you set the background as a Uri to a image in your project. There are many workarounds to make this transition simple, but it’s beyond the scope of the article. I may describe it in one of my next articles, if someone finds it necessary. :)

If you find the article useful, make sure others hear about it, too. :)

Igor Ralic

igor ralic

View Comments
Microsoft Certified Solutions Developer: Windows Store Apps in C#