At //build today Microsoft announced the new Universal Apps that will allow you to build desktop, tablet and phone apps using the same code. These are different than PCLs as they allow for platform functionality (I won’t get into differences between PCLs and Shared Projects here). These new apps will be based on the XAML platform that Windows tablet apps are built on. So this means that you can build Windows Phone apps with new XAML elements that are available in Windows [tablet] Apps like the GridView, ListView, Hub and more. This also means that Silverlight Windows Phone controls will not be available. One of these missing controls is the Panorama control. We’ll look at how we can take an existing Panorama app, and convert it to a Hub app. Migrating to the Hub control from the Panorama control is very easy.
To start, I’ll create a new Windows Phone [Silverlight] Panorama app. I’ll call in PanoramaConversion.
Next I’ll add a new project to the solution.
For this project I’ll create a new Windows Phone (not Silverlight) Blank App. I’ll call this one ConvertedPanoramaApp.
Open MainPage.xaml from the PanoramaConversion project. Select all of the xaml for the Panorama control. To make it easy, you can collapse the element, move your mouse to the left and select the entire section. Copy this xaml element and then paste it into the Grid element in the MainPage from the ConvertedPanoramaApp project.
Notice all of the blue squiggly lines? We’ll need to fix these. Most of the errors can be fixed with find/replace. We’ll perform the following find/replace operations
- replace phone:PanoramaItem with HubSection
- replace phone:Panorama with Hub
- replace Title with Header – The Hub control has a Header property while the Panorama control had a Title property.
- replace Orientation="Horizontal" with Width=”Auto” – The HubSection does not have an Orientation property, instead it defines the Width of the control to be 360. Setting the Width to Auto allows it to scroll horizontally.
Because we copied the app as-is. It contains a few LongListSelector controls. This control is not available in Windows Phone XAML apps so we’ll have to replace the use of it with the ListView control. The Panorama App project template has simple uses for the LLS, so it won’t be hard to replace.
- replace phone:LongListSelector with ListView
- replace ListHeaderTemplate with HeaderTemplate
You’ll notice we still have a lot of problems with the xaml.
This is because the PanoramaItem is a ContentControl while the HubSection is just a Control. This means that the PanoramaItem allows for direct content within the element. However, the HubSection does define a ContentProperty attribute. This class attribute defines that something can go within the control element. The HubSection defines that a ControlTemplate can be used as it’s “Content”. So we’ll need to wrap the content of the HubSection with a DataTemplate.
<HubSection Header="third item" Width="Auto">
<DataTemplate>
<!--Double wide Panorama with large image placeholders-->
<Grid>
<StackPanel Margin="0,4,16,0" Orientation="Vertical" VerticalAlignment="Top">
<StackPanel HorizontalAlignment="Left" Orientation="Horizontal">
<Border Background="#FFFFC700" Height="173" Width="173" Margin="12,0,0,0"/>
<Border Background="#FFFFC700" Height="173" Width="173" Margin="12,0,0,0"/>
<Border Background="#FFFFC700" Height="173" Width="173" Margin="12,0,0,0"/>
<Border Background="#FFFFC700" Height="173" Width="173" Margin="12,0,0,0"/>
</StackPanel>
<StackPanel HorizontalAlignment="Left" Orientation="Horizontal" Margin="0,12,0,0">
<Border Background="#FFFFC700" Height="173" Width="173" Margin="12,0,0,0"/>
<Border Background="#FFFFC700" Height="173" Width="173" Margin="12,0,0,0"/>
<Border Background="#FFFFC700" Height="173" Width="173" Margin="12,0,0,0"/>
<Border Background="#FFFFC700" Height="173" Width="173" Margin="12,0,0,0"/>
</StackPanel>
</StackPanel>
</Grid>
</DataTemplate>
</HubSection>
Next we’ll bring the existing background image into the new project. In the Solution Explorer window, drag and drop the PanoramaBackground.png file to the Assets folder in the new project.
Once that is copied over, change the Hub Background ImageBrush source to /Assets/PanoramaBackground.png (remove the /PanoramaConversion;component portion). You’ll notice that now the designer is rendering our Hub control
You’ll notice the text for the HubSection headers is much smaller than it was in the PanoramaItem. You can make the choice to scale this by using the HeaderTemplate of the HubSection.
<HubSection.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" FontSize="40"/>
</DataTemplate>
</HubSection.HeaderTemplate>
Usually best to put this into a resource that can be used across all HubSections. The last thing for our conversion is to remove or replace the use of the Phone [Silverlight] specific resources like PhoneTextExtraLargeStyle and PhoneFontSizeLarge. There are replacements, so we can make the following changes.
- PhoneFontSizeLarge – TextStyleLargeFontSize
- StaticResource PhoneTextSubtleStyle – ThemeResource ListViewItemSubheaderTextBlockStyle
- StaticResource PhoneTextExtraLargeStyle – ThemeResource ListViewItemTextBlockStyle
We’ll still need to bring over the sample data from the original app, but I’ll let you do this .
You should also be aware that the Hub control will occupy the space of the StatusBar by default. You'll want to take this into account and ensure that the content from the StatusBar does not interfere with the content from your app.
You can download a sample project here.