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:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
<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:
|
1 2 3 4 5 |
<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:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
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:
|
1 2 3 4 5 6 7 8 9 10 |
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:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
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. :)



Great article! Good job.
thanks!
Great article! Good job.
thanks!
Thanks for the great article. I couldn’t get the image to be displayed in the Tile using your sample code. I had to write the image to the isostore:/Shared/ShellContent/tile and read it from there. I hope there is a better way to do this.
Hi
Thanks for reading!
I can hardly tell what went wrong and why can’t you read the image like this. If the image has been properly set on the hubtile inside the app, it should work… It worked for me.
I can find the old code and give it a try again to see if I can detect the possible issue.
Thanks for the great article. I couldn’t get the image to be displayed in the Tile using your sample code. I had to write the image to the isostore:/Shared/ShellContent/tile and read it from there. I hope there is a better way to do this.
Hi
Thanks for reading!
I can hardly tell what went wrong and why can’t you read the image like this. If the image has been properly set on the hubtile inside the app, it should work… It worked for me.
I can find the old code and give it a try again to see if I can detect the possible issue.
Sorry for the late reply. I found the issue why I couldn’t get the images displayed using your code. I had the Build Action on the images set to Resource. Changed the build action to content and worked like a charm. Thanks again.
Sorry for the late reply. I found the issue why I couldn’t get the images displayed using your code. I had the Build Action on the images set to Resource. Changed the build action to content and worked like a charm. Thanks again.
Also is there a way to change the font size of the BackTile content?
Glad to hear you got it working with setting the build action to Content.
Now, I’m not sure about the font size. Perhaps there’s some sort of a property. If not, you will have to edit the styling yourself… I’ll look into it!
Also is there a way to change the font size of the BackTile content?
Glad to hear you got it working with setting the build action to Content.
Now, I’m not sure about the font size. Perhaps there’s some sort of a property. If not, you will have to edit the styling yourself… I’ll look into it!
Is there a way to pin a large tile?
like the calender type..could be usefull to make a clock app like HTC have for WP8
Is there a way to pin a large tile?
like the calender type..could be usefull to make a clock app like HTC have for WP8