Metro Controls – Jump Viewer

After an amazing week at //Build, I’ve been busy playing with the new controls, which I have to say are fantastic! Ollie and I know the pain first hand when it comes to building a Silverlight TUI (Touch User Interface) it’s not a great story and IMHO the controls are not ready. I may still post my thoughts on this experience, I’ve been holding back as I really don’t want to be dragged into the Silverlight is DEAD! debacle and this post could be taken in this way, however it will give you context around why we are so pleased that there is a new story and that one is awesome. But while I think about posting my experiences of building TUI on slates running Win 7, I’ve been putting together notes on the controls and thought that these may be beneficial to others so my objectives are to walk through some of the new controls and peel the layers like an onion. So, we can then go deep on certain topics.

So without further ado please say a big HELLO! to the Jump Viewer which is currently my favourite control. The interactions are stunning and performance is awesome! Before I start to dig in we should take a look at the finished control. The first screen shot is of the Jump Viewer when it first loads up in its zoomed in state and the second screen shot is taken when we peform an inwards pinch gesture which zooms out and the semantic zoom kicks in replacing the view with higher level details so that we can easily jump to another position in the Grid.

 

 

Note:- there are some anti-aliasing issues that happen periodically, not sure why this happens but I will update the post when I know more.

 

For more background reading on semantic zoom check out the guidelines for semantic zoom and also the sample in the SDK.

What I really like about the Jump Viewer is that it uses composition, allowing you to simply wrap up other controls that you may have used previously in order to deliver an immersive experience when interacting with the visualised data. In order to build a better understanding of the control we need to look at the Xaml. Lets start by concentrating on the JumpView which is the part of the control that is activated when we zoom out.

I have added my notes into the Xaml and hopefully this is a better way of groking the Xaml rather than snippets and dialogue, this way you can copy and paste the Xaml into your app and retain the notes.



 <!--
The jump view is the visual effect when we use semantic zoom the pinch-in gesture
The grid view items panel is set to a wrapgrid
Which renders a list of category names
-->
<JumpViewer x:Name="jumpViewer"
        Grid.Row="1"
        Margin="120,0,0,0">
        <!--
        The jump viewer jump view
        -->
        <JumpViewer.JumpView>
                <GridView Foreground="White">
                <GridView.ItemTemplate>
                <!--
                Data template used to visualise what we want to display when zoomed out
                In our case we are showing some group text
                -->
                <DataTemplate>
                        <TextBlock Text="{Binding Name}"
                        FontFamily="{StaticResource SemiBoldContentFontFamily}"
                        FontSize="{StaticResource HeaderLargeFontSize}"
                        Foreground="{StaticResource PageForegroundBrush}" />
                </DataTemplate>
                </GridView.ItemTemplate>
                <GridView.ItemsPanel>
                        <ItemsPanelTemplate>
                            <!-- 
                                Positions child elements sequentially from left to right or top to bottom. 
                                When elements extend beyond the container edge, elements are positioned in the next row or column.
                                You can change the Maximum rows or columns to change the visual layout when zoomed out
                            -->
                            <WrapGrid ItemWidth="114"
                                      ItemHeight="114"
                                      MaximumRowsOrColumns="6"
                                      VerticalChildrenAlignment="Center" />
                        </ItemsPanelTemplate>
                </GridView.ItemsPanel>                    
                <!--
                Note when we change the item container style the target type is ListViewItem not GridViewItem
                -->
                <GridView.ItemContainerStyle>
                    <Style TargetType="ListViewItem">
                        <Setter Property="Margin"
                                Value="6" />
                        <Setter Property="Padding"
                                Value="12" />
                        <Setter Property="BorderBrush"
                                Value="{StaticResource PageForegroundBrush}" />
                        <Setter Property="BorderThickness"
                                Value="1" />
                        <Setter Property="HorizontalContentAlignment"
                                Value="Center" />
                        <Setter Property="VerticalContentAlignment"
                                Value="Center" />
                    </Style>
                </GridView.ItemContainerStyle>
                </GridView>
            </JumpViewer.JumpView>

Below is an illustration of the above Xaml and how the composite parts fit together.


 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

What is very cool is the new Wrap Grid which provides the ability to change the layout of Jump View in the code above I do this.

<WrapGrid ItemWidth="114"
    ItemHeight="114"
    MaximumRowsOrColumns="6"
    VerticalChildrenAlignment="Center" />

In order to change the layout of the grid we can simply change the number of Maximum Rows or Columns, for example changing this property to 1 will change the layout to look more like the standard search control in Metro. Therefore, a quick tweak with how many rows or columns you want means that you can change the experience depending on the content being visualised. I will cover off the Wrap Grid in a future post.

Next we need to look at the content part of the Jump Viewer.

<!--
    The content view renders the detailed items
-->
<JumpViewer.ContentView>
    <GridView ItemsSource="{Binding Source={StaticResource cvs2}}"
              IsCrossSlideEnabled="True">
    <!--
        Main content template
    -->
    <GridView.ItemTemplate>
        <--
           Data template used to display the data 
        -->
        <DataTemplate>
            <StackPanel Orientation="Horizontal"
                Margin="12,10,0,0"
                HorizontalAlignment="Left">
                <Image Source="{Binding Image}"
                       Height="60"
                       Width="60"
                       VerticalAlignment="Center"
                       Margin="0,0,10,0" />
                <TextBlock TextWrapping="Wrap"
                           Style="{StaticResource ItemTitleStyle}"
                           Width="240"
                           VerticalAlignment="Center"
                           Text="{Binding Title}"
                           HorizontalAlignment="Left"
                           FontFamily="{StaticResource SemiLightContentFontFamily}" />
             </StackPanel>
        </DataTemplate>
    </GridView.ItemTemplate>
    <!--Group Style this will allow for the grouping visual effects that we want-->
    <GridView.GroupStyle>
        <GroupStyle>
        <!--Group Style Header template defines what controls we use in the header-->
        <GroupStyle.HeaderTemplate>
            <DataTemplate>
                <TextBlock Text='{Binding Name}'
                           Foreground="{StaticResource PageForegroundBrush}"
                           Margin="0,0,36,0"
                           FontSize="{StaticResource HeaderLargeFontSize}"
                           FontFamily="{StaticResource SemiBoldContentFontFamily}" />
            </DataTemplate>
        </GroupStyle.HeaderTemplate>
        <!--Group Style Container Style -->
        <GroupStyle.ContainerStyle>
            <Style TargetType="GroupItem">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="GroupItem">
                    <!--Change the orientation of the panel to change where the Group Header is positioned -->
                        <StackPanel Orientation="Horizontal">
                            <ContentPresenter Content="{TemplateBinding Content}" />
                            <ItemsControl x:Name="ItemsControl"
                                          ItemsSource="{Binding GroupItems}" />
                        </StackPanel>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        </GroupStyle.ContainerStyle>
        <GroupStyle.Panel>
            <ItemsPanelTemplate>
            <!-- 
                Provides a grid-style layout panel where each tile/cell can be variable size based on content.
            -->
            <VariableSizedWrapGrid Orientation="Vertical"
                                   MaximumRowsOrColumns="6" />
            </ItemsPanelTemplate>
        </GroupStyle.Panel>
        </GroupStyle>
    </GridView.GroupStyle>
        <GridView.ItemsPanel>
            <ItemsPanelTemplate>
                <!--VirtualizingStackPanel VirtualizationMode="Recycling" -->
                <StackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </GridView.ItemsPanel>
                    <Button Visibility="Collapsed" />
        </GridView>
    </JumpViewer.ContentView>
</JumpViewer>

 
As you can see the Content section of the Jump Viewer comprises another control, in this case a Grid View, which provides the horizontal scrolling experience. A new feature for Metro is the ability to apply a Group Style on both the List and Grid View controls which provide the ability to group the data if your data model supports it. I will go into more detail about Group Styles in a future post. For now what we should understand is that when providing a Group Style we need to ensure that we provide a data template that will visualise the data in the header template and we can change the orientation of the layout by changing the Stack Panel in the Item Container Style from Vertical to Horizontal.

The Grid View also needs a data template for the items and there is also another new layout control called the Variable Sized Wrap Grid which is being used to layout the items in the Grid View. Once again I am loving this new layout and I will talk in more detail about the control in a future post. The most important thing for now is to understand that like the Wrap Grid, we can change the orientation and the Maximum Rows Or Columns properties which effect the layout of the items in the Grid. Sweet!

You may have also noticed that I have commented out the Virtualizing Stack Panel, I had problems when I used this, not sure why this is and when I find out more details I will update the post.

Enjoy!

Be Sociable, Share!

Tags: , ,

12 Responses to “Metro Controls – Jump Viewer”

  1. [...] Read More… SHARE Categories: Xaml [...]

  2. [...] Metro Controls – Jump Viewer (Rich Griffin) [...]

  3. Any chance you could post a simple sample project with the JumpViewer?

    I’ve been trying to get the JumpViewer functioning in my MetroFlickr project without luck so far.

    Craig
  4. Actually, nevermind…I found a good sample here: http://code.msdn.microsoft.com/windowsapps/GroupedGridView-77c59e8e

    The link in your post goes to a JS sample that didn’t cover what I was after (C#/XAML)

    Craig
  5. Oddly enough, I couldn’t get my JumpViewer to change from the JumpView to my ContentView. Does it really have to be done manually with the ItemClick event ? what’s odd is that I have’nt found any mention of ItemClick in microsoft’s GroupedGridView sample…

    Besides, I am really looking forward to your post about groups and collection views, because I am really not convinced about the way it is done in the sample ( the ItemSource is set in the background to use the collectionViewSource.View.CollectionGroups as a source) From what I’ve tested, I’ve set a binding with a CollecionViewSource in a staticResource as Binding Source, but I could not specify any Path (let’s say View.CollectionGroups to mimic the Sample’s codebehind) because the targeted element could not be found (at least, that’s my guess, since binding errors don’t show up in the Output window, for some reason)

    If you have any thoughts on those feedbacks, I’d be glad to hear them :)

    -Fab

    Fab
  6. Hey Fab,

    Could you share your code ? I can take a look and get back to you. I also need more information around your sceanrio.

    In order to get the most of of the Grouping and the Jump Viewer its all about the structure of your data if this is not in the right shape your going to be getting friction.

    rich
  7. Hey Craig,

    My bad i fubar’d the link sorry about this, interested in hearing about your journey with the jump viewer.

    rich
  8. Hi, rich : where would you like me to drop you the sources ?

    Fab
  9. Allright, got it :

    the idea is to make sure the *Groups* of the ContentView are the *Items* of the JumpView… easy to do if you don’t care about MVVM, but doing it in a clean fashion is an other story.

    My mistake was that I was trying to use the same collectionViewSource for both the ContentView and the JumpView, but doing so will result in having the same items as groups in both views : we don’t want it.

    I’ll dig a little bit on the ValueConverters side for the JumpView, instead of binding directly to a CollectionViewSource, in order to build a collection on the fly with the collectionViewSource’s groups as elements.

    Note : I tried binding to the same StaticResource in oth views and add a path to View.CollectionGroups in the JumpView, in order to bind to a collection of groups, but it was not successful. No idea why.

    Fab
  10. Allright, I just quickly blogged about it :

    If you’re interested to see my feedback, here it is :

    http://www.seesharp.ch/jumping-through-hoops-with-the-jumpviewer/149

    Fab
  11. Fab, nice post dude very interested in looking at your project dropbox sounds like a good place if you are happy to share the link then i can take a look

    Rich

    rich
  12. Hey, thanks :)

    Regarding the project, I just attached it to my blog : it’s even easier that way.

    here it is :

    http://www.seesharp.ch/?attachment_id=156

    Fab

Leave a Reply