Creating a snap view with XAML in Windows 8 (WinRT)

If you create a new WinRT solution using the Grid or Split Application Template you'll get all the code you need to create a layout aware page that shows a different view when in snap view. If you start of your project using the blank project template, you need to do a little bit more work to get it working.

First you need to change the page to be a layout aware page. LayoutAwarePage is a class provided by the template and is in the Common folder. (Update: In Visual Studio 2012 RC LayoutAwarePage is no longer in the common folder for a blank page project. You need to copy the file from the Grid or Split Application template. The new version also depends on SuspensionManager also in the common folder of those project templates.)

In BlankPage.xaml.cs change:

public sealed partial class BlankPage : Page

to

public sealed partial class BlankPage : LayoutAwarePage

In BlankPage.xaml you need to change a view things:

The main page tag now needs to be a LayoutAwarePage so change it from this:

<Page
    x:Class="Application1.BlankPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Application1"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

to

<common:LayoutAwarePage
    x:Name="pageRoot"
    x:Class="Application1.BlankPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Application1"
    xmlns:common="using:Application1.Common"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

Your page is now a layout aware page, so all you need to do is add a visual state manager that will control how things look in each different view. You may choose to show or hide different elements based on the view, or just change some sizes. Either way you include all the elements you want in the page set at the size you want them to be in the standard view. You hide them if you only want them to be visible in the snap view. Here is a simple example of a visual state manager:

<VisualStateManager.VisualStateGroups>

 <VisualStateGroup>
  <VisualState x:Name="FullScreenLandscape"/>
  <VisualState x:Name="Filled"/>
  <VisualState x:Name="FullScreenPortrait"/>

  <VisualState x:Name="Snapped">
   <Storyboard>
    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="MyListScroller" Storyboard.TargetProperty="Visibility">
     <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
    </ObjectAnimationUsingKeyFrames>
    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="MyGridScroller" Storyboard.TargetProperty="Visibility">
     <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
    </ObjectAnimationUsingKeyFrames>
   </Storyboard>
  </VisualState>
 </VisualStateGroup>
</VisualStateManager.VisualStateGroups>

In this example I have a list view which is initially hidden for snap view and a grid view for my full screen view which I hide for the snap view.

4 Comments

  • Abdul Rahaman said

    OMG OMG! Thanks a lot Richard. I was trying to make the snap view work on my app for over a week but couldn't do it because it was made from a blank page. Now after making changes, it works! Thanks again! :D

  • Matt said

    I'm using the VB version, Any chance in making a VB version of this? I'm so confused... The <Base> is all I have and I'm getting real stressed over it.. I can't seem to figure it out as I'm like 1 day into programming and I need this information to get to my next task! It would be gratefully appreciated!

    Using Express 2012 Win8

  • Patrick said

    Thanks a lot for the help! It worked like a charm. One issue I encountered that was probably my fault for mucking around with stuff previously was that I had to change

    xmlns:common="using:Application1.Common"
    to
    xmlns:common="using:Application1"

    I thought I'd share in case anyone else has the same issue. But anyways, thanks!

  • Richard said

    @Patrick You shouldn't change the common namespace mapping in your XAML file. You just need to make sure that LayoutAware page is in the common namespace.

Add a Comment