Quickstart: adding SemanticZoom controls (XAML)

[ This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation ]

Learn how to use the SemanticZoom control to zoom between two views of the same content.

Prerequisites

What is the SemanticZoom control?

The SemanticZoom control enables the user to zoom between two different views of the same content so that they can quickly navigate from one section of a large data set to another. The zoomed-in view is the main view of the content that gives users a detailed look at the items. The zoomed-out view is a high level view of the same content represented in a way that allows users to quickly navigate through it. For example, when viewing an address book, the user could zoom out to navigate to names that start with the letter "W", and zoom in on that letter and see the names associated with it.

To provide this zooming functionality, the SemanticZoom control uses two other controls: one to provide the zoomed-in view and one to provide the zoomed-out view. These controls can be any two controls that implement the ISemanticZoomInformation interface. The Extensible Application Markup Language (XAML) framework provides several controls that implement this interface: ListView, GridView, and Hub. The examples in this quickstart show you how to use SemanticZoom with two GridView controls.

Don't confuse semantic zooming with optical zooming. While they share both the same interaction and basic behavior (displaying more or less detail based on a zoom factor), optical zoom refers to the adjustment of magnification for a content area or object such as a photograph. For info about a control that performs optical zooming, see the ScrollViewer control.

Add the SemanticZoom control

In your markup, create the SemanticZoom control. You'll assign GridView controls to the ZoomedOutView and ZoomedInView properties.

  • In your XAML, add the SemanticZoom control. This example shows the markup before the GridView controls are added.

    <SemanticZoom x:Name="semanticZoom" VerticalAlignment="Bottom">
    
        <SemanticZoom.ZoomedOutView>
            <!-- Put the GridView for the zoomed out view here. -->   
        </SemanticZoom.ZoomedOutView>
    
        <SemanticZoom.ZoomedInView>
            <!-- Put the GridView for the zoomed in view here. -->       
        </SemanticZoom.ZoomedInView>
    
    </SemanticZoom>
    

Define zoomed-in and zoomed-out views

This SemanticZoom control uses two GridView controls: one to supply the zoomed-in view and one for the zoomed-out view.

Note  For the complete code for this example, see the XAML GridView grouping and SemanticZoom sample.

 

  1. In your XAML, define a GridView control for the zoomed-out view. This example shows how to display the group headers in a grid of blue squares.

    <Page.Resources>
        <CollectionViewSource x:Name="cvs2" IsSourceGrouped="true"/>
    </Page.Resources>
    
    ...
    
    <SemanticZoom x:Name="semanticZoom">
        <SemanticZoom.ZoomedOutView>
            <GridView Foreground="White"
                      ScrollViewer.IsHorizontalScrollChainingEnabled="False">
                <GridView.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Group.Key}" 
                       FontFamily="Segoe UI" FontWeight="Light" FontSize="24" />
                    </DataTemplate>
                </GridView.ItemTemplate>
                <GridView.ItemsPanel>
                    <ItemsPanelTemplate>
                        <ItemsWrapGrid ItemWidth="75" ItemHeight="75" MaximumRowsOrColumns="2"/>
                    </ItemsPanelTemplate>
                </GridView.ItemsPanel>
                <GridView.ItemContainerStyle>
                    <Style TargetType="GridViewItem">
                        <Setter Property="Margin" Value="4" />
                        <Setter Property="Padding" Value="10" />
                        <Setter Property="Background" Value="#FF25A1DB" />
                        <Setter Property="BorderThickness" Value="1" />
                        <Setter Property="HorizontalContentAlignment" Value="Left" />
                        <Setter Property="VerticalContentAlignment" Value="Bottom" />
                    </Style>
                </GridView.ItemContainerStyle>
            </GridView>
        </SemanticZoom.ZoomedOutView>
    
        <SemanticZoom.ZoomedInView>
        ...  
        </SemanticZoom.ZoomedInView>
    </SemanticZoom>
    
  2. Define another GridView control for the zoomed-in view. The zoomed-in view should display the complete data collection. This example shows how to display the complete collection in a grid with an image and text.

    <Page.Resources>
        <CollectionViewSource x:Name="cvs2" IsSourceGrouped="true"/>
    </Page.Resources>
    
    ...
    
    <SemanticZoom x:Name="semanticZoom">
        <SemanticZoom.ZoomedOutView>
        ...
        </SemanticZoom.ZoomedOutView>
    
        <SemanticZoom.ZoomedInView>
            <GridView x:Name="ItemsGridView" IsSwipeEnabled="True"
                      ItemsSource="{Binding Source={StaticResource cvs2}}"
                      ScrollViewer.IsHorizontalScrollChainingEnabled="False">
                <GridView.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal" Margin="10,5,0,5" 
                                    HorizontalAlignment="Left" Background="White">
                            <Image Source="{Binding Image}" Height="60" Width="60" 
                                   VerticalAlignment="Center" Margin="0,0,10,0"/>
                            <StackPanel>
                                <TextBlock Text="{Binding Title}" TextWrapping="Wrap" 
                                           Foreground="{StaticResource ApplicationForegroundThemeBrush}" 
                                           Width="200" VerticalAlignment="Center" HorizontalAlignment="Left" 
                                           FontFamily="Segoe UI" FontSize="14.667" FontWeight="Light"/>
                                <TextBlock Text="{Binding Category}" TextWrapping="Wrap"                                                    
                                           Foreground="{StaticResource ApplicationForegroundThemeBrush}" 
                                           Width="200" VerticalAlignment="Center" HorizontalAlignment="Left" 
                                           FontFamily="Segoe UI" FontSize="11" FontWeight="Light"/>
                            </StackPanel>
                        </StackPanel>
                    </DataTemplate>
                </GridView.ItemTemplate>
                <GridView.ItemsPanel>
                    <ItemsPanelTemplate>
                        <ItemsWrapGrid MaximumRowsOrColumns="3"/>
                    </ItemsPanelTemplate>
                </GridView.ItemsPanel>
                <GridView.GroupStyle>
                    <GroupStyle>
                        <GroupStyle.HeaderTemplate>
                            <DataTemplate>
                                <TextBlock Text='{Binding Key}' 
                               Foreground="{StaticResource ApplicationForegroundThemeBrush}" 
                               Margin="5" FontSize="18" FontFamily="Segoe UI" FontWeight="Light" />
                            </DataTemplate>
                        </GroupStyle.HeaderTemplate>
                    </GroupStyle>
                </GridView.GroupStyle>
            </GridView>
        </SemanticZoom.ZoomedInView>
    </SemanticZoom>
    
  3. When you use a GridView in a SemanticZoom control, always set the ScrollViewer.IsHorizontalScrollChainingEnabled attached property to false on the ScrollViewer that's in the GridView's control template, like this: <GridView ScrollViewer.IsHorizontalScrollChainingEnabled="False">.

    When you use a ListView in a SemanticZoom control, always set the ScrollViewer.IsVerticalScrollChainingEnabled attached property to false, like this: <ListView ScrollViewer.IsVerticalScrollChainingEnabled="False">.

Synchronize the views

The zoomed-in view and zoomed-out view should be synchronized, so if a user selects a group in the zoomed-out view, the details of that same group are shown in the zoomed-in view. You can use a CollectionViewSource or add code to synchronize the views.

Any controls that you bind to the same CollectionViewSource will always have the same current item. If both views use the same CollectionViewSource as their data source, the CollectionViewSource will synchronize the views automatically.

Use a CollectionViewSource

  1. Note  For the complete code for this example, including the StoreData class and GetGroupsByLetter method, see the XAML GridView grouping and SemanticZoom sample.

     

    Here, you get a list of data items grouped by the first letter of their title. The grouped items are set as the CollectionViewSource.Source.

    // Create a new instance of the data.
    _storeData = new StoreData();
    
    // Get a list of groups. Each group contains a list of items.
    List<GroupInfoList<object>> dataLetter = _storeData.GetGroupsByLetter();
    
    // Set the CollectionViewSource defined in the XAML page resources
    // to the grouped data.
    cvs2.Source = dataLetter;
    
  2. In your XAML, the CollectionViewSource is bound as the ItemsSource of the zoomed-in view. This view shows the complete collection of grouped items.

    <Page.Resources>
        <CollectionViewSource x:Name="cvs2" IsSourceGrouped="true"/>
    </Page.Resources>
    
    ...
        <SemanticZoom.ZoomedInView>
            <GridView x:Name="ItemsGridView" IsSwipeEnabled="True"
                      ItemsSource="{Binding Source={StaticResource cvs2}}"
                      ScrollViewer.IsHorizontalScrollChainingEnabled="False">
    ...
    
  3. Here, you set the ItemsSource of the zoomed-out view to the CollectionGroups property of the CollectionViewSource.View. This view shows only the groups, but not individual items.

    // Set the items source for the zoomed out view to the group data as well.
    (semanticZoom.ZoomedOutView as ListViewBase).ItemsSource = cvs2.View.CollectionGroups;
    

    Here's where these elements are declared in the XAML.

    <SemanticZoom x:Name="semanticZoom">
        <SemanticZoom.ZoomedOutView>
            <GridView Foreground="White"
                      ScrollViewer.IsHorizontalScrollChainingEnabled="False">
    ...
    

    Because both views use the same CollectionViewSource (cvs2) as their data source, they are always kept synchronized.

Use code

  • If you don't use a CollectionViewSource to synchronize the views, you should handle the ViewChangeStarted event and synchronize the items in the event handler like this.

    <SemanticZoom x:Name="semanticZoom" ViewChangeStarted="SemanticZoom_ViewChangeStarted">
    ...
    
    private void SemanticZoom_ViewChangeStarted(object sender, SemanticZoomViewChangedEventArgs e)
    {
        if (e.IsSourceZoomedInView == false)
        {
            e.DestinationItem.Item = e.SourceItem.Item;
        }
    }
    

Using the SemanticZoom

When you run app, you now see a single grid, and you can now zoom between the two views you defined.

To zoom between the two views:

Input mechanism Zoom out Zoom in
Touch Pinch out Pinch, tap
Keyboard Ctrl + Minus sign, Enter, Space Ctrl + Plus sign, Enter, Space
Mouse Ctrl + Rotate the mouse wheel backward Ctrl + Rotate the mouse wheel forward

 

Samples

To learn more about the SemanticZoom control, download the XAML GridView grouping and SemanticZoom sample.

Summary

You learned how to create a SemanticZoom that uses two GridView controls to create its zoomed-in and zoomed-out views.

SemanticZoom

GridView

ListView

How to group items in a list or grid