SemanticZoom Control in Windows Store Apps

Introduction

Today I am going to explian how to use the SemanticZoom control in Windows Store apps. How this control works is that, as one GridView shows items by their first letter, when we switch it, all the letters are placed in another GridView. For designing the SemanticZoom control we can use either a ListView or a GridView. If we use a ListView then set its property as:

<ListView ScrollViewer.IsVerticleScrollChainingEnabled="False">

If a GridView is used then sets GridView property as:

<GridView ScrollViewer.IsHorizontalScrollChainingEnabled="False">

In this article I use a GridView.

To see how its works let's use the following steps.

Step 1

Open Visual Studio 2012 and click on File -> New -> Project. A window is shown; in it select Windows Store inside Visual C# from the left side pane and BlankPage from the center pane, then give the name of your application and click ok.

Step 2

Add a class by right-clicking on the project in the Solution Explorer and click Add->Class. A window is opened. In this give the name of your class and and click ok. I give ItemSource.cs as a name of the class.

Step 3

Now add some parameters in this class as:

public class ItemSource

{

    public string Title { get; set; }

    public string Image { get; set; }

    public string Category { get; set; }

    public string Description { get; set; }

}

Step 4

Assign the values of these parameters as:

public class StoreData

{

     public StoreData()

      {

            ItemSource item;

            item = new ItemSource()

            { Title = "C#",Image = "Books/c-sharp.jpg",Category = "Books",Description = "Multi Paradigm Programming Language" };

            collection.Add(item);

            item = new ItemSource() { Title = "DotNet Framework", Image = "Books/Dotnet_framework.jpg", Category = "Books", Description = "This Book defines Dotnet Framework" };

            collection.Add(item);

            item = new ItemSource() { Title = "Dell-Laptop", Image = "Laptops/Laptop1.jpg", Category = "Laptop", Description = "Windows 7 enabled" };

            collection.Add(item);

            item = new ItemSource() { Title = "Comopaq Laptop", Image = "Laptops/Laptop2.jpg", Category = "Laptop", Description = "Windows Vista Enabled" };

            collection.Add(item);

            item = new ItemSource() { Title = "Nokia 5555", Image = "Mobile/Mobile1.jpg", Category = "Mobile", Description = "Cheapest Mobile Set" };

            collection.Add(item);

            item = new ItemSource() { Title = "Nokia 7677", Image = "Mobile/Mobile2.jpg", Category = "Mobile", Description = "Mostly Used Nokia set" };

            collection.Add(item);

            item = new ItemSource() { Title = "DotNet", Image = "Books/net.jpg", Category = "Books", Description = "Very Useful for all beggineer" };

            collection.Add(item);

            item = new ItemSource() { Title = "Dotnet Technology", Image = "Books/net_technology.jpg", Category = "Books", Description = "Technology related to dotnet" };

            collection.Add(item);

            item = new ItemSource() { Title = "Dell", Image = "Laptops/Laptop3.jpg", Category = "Laptop", Description = "Best Operating System" };

            collection.Add(item);

            item = new ItemSource() { Title = "Compaq-HP", Image = "Laptops/Laptop4.jpg", Category = "Laptop", Description = "Most Used and very popular" };

            collection.Add(item);

            item = new ItemSource() { Title = "WPF", Image = "Books/wpf.jpg", Category = "Books", Description = "WPF Designing" };

            collection.Add(item);

      }

     private ItemCollection collection = new ItemCollection();

}

Step 5

Create a class for the ItemCollection as:

namespace SemanticZoom_Example

{

    class ItemCollection: IEnumerable<Object>

    {

        private System.Collections.ObjectModel.ObservableCollection<ItemSource> itemCollection = new System.Collections.ObjectModel.ObservableCollection<ItemSource>();

        public IEnumerator<Object> GetEnumerator()

        {

            return itemCollection.GetEnumerator();

        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()

        {

            return GetEnumerator();

        }

        public void Add(ItemSource item)

        {

            itemCollection.Add(item);

        }

    }  

} 


In this a namespace System.Collections.ObjectModel.ObservableCollection is used which is used for representing a dynamic data collection that provides notification when the items are added, removed or when the whole list is refreshed.

Step 6

Write a LINQ query for dividing all the items (with text as well as images) by their first letter of the title, as:
 

internal List<GroupInfoList<object>> GetGroupsByLetters()

{

     List<GroupInfoList<object>> groups = new List<GroupInfoList<object>>();

     var query = from item in collection

                 orderby ((ItemSource)item).Title

                 group item by ((ItemSource)item).Title[0] into g

                 select new { GroupName = g.Key, Items = g };

     foreach (var g in query)

     {

          GroupInfoList<object> info = new GroupInfoList<object>();

          info.Key = g.GroupName;

          foreach (var item in g.Items)

          {

              info.Add(item);

          }

          groups.Add(info);

     }

     return groups;
}

Step 7

The definition of GroupListInfo is as:
 

public class GroupInfoList<T> : List<object>

{

    public object Key { get; set; }

    public new IEnumerator<object> GetEnumerator()

    {

         return (System.Collections.Generic.IEnumerator<object>)base.GetEnumerator();

    }
}



Step 8

The structure of SemanticZoom control is as:
 

<SemanticZoom>

       <SemanticZoom.ZoomedOutView>

                <!--Code For Semantic  Zoomed Outview-->

       </SemanticZoom.ZoomedOutView>

       <SemanticZoom.ZoomedInView>

                <!--Code For Semantic  Zoomed Inview-->

       </SemanticZoom.ZoomedInView>

</SemanticZoom>


Hear Zoomed-Out control shows how to display the group header in a grid. You can also see my article to see the details that how we design the GridView Grouped Header and Zoomed-In shows how to display the collection of all the complete data items.As I use GridView for creating the SemanticZoom control so I set GridView ScrollViewer property to false as,

<GridView ScrollViewer.IsHorizontalScrollChainingEnabled="False">

Step 9

Now write the code in MainPage.xaml file as:
 

<Page

    x:Class="SemanticZoom_Example.BlankPage2"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:local="using:SemanticZoom_Example"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    mc:Ignorable="d">

    <Page.Resources>

        <CollectionViewSource x:Name="cvs2" IsSourceGrouped="true" />

    </Page.Resources>

    <Grid x:Name="ContentPanel" VerticalAlignment="Top" HorizontalAlignment="Left">

        <SemanticZoom x:Name="semanticZoom" VerticalAlignment="Bottom">

            <SemanticZoom.ZoomedOutView>

                <GridView ScrollViewer.IsHorizontalScrollChainingEnabled="False">

                    <GridView.ItemTemplate>

                        <DataTemplate>

                            <TextBlock

                                Text="{Binding Group.Key}"

                                FontFamily="Segoe UI Light"

                                FontSize="24"/>

                        </DataTemplate>

                    </GridView.ItemTemplate>

                    <GridView.ItemsPanel>

                        <ItemsPanelTemplate>

                            <WrapGrid ItemWidth="75" ItemHeight="75" MaximumRowsOrColumns="1" VerticalChildrenAlignment="Center" />

                        </ItemsPanelTemplate>

                    </GridView.ItemsPanel>

                    <GridView.ItemContainerStyle>

                        <Style TargetType="GridViewItem">

                            <Setter Property="Margin" Value="4" />

                            <Setter Property="Padding" Value="10" />

                            <Setter Property="BorderBrush" Value="Gray" />

                            <Setter Property="BorderThickness" Value="1" />

                            <Setter Property="HorizontalContentAlignment" Value="Center" />

                            <Setter Property="VerticalContentAlignment" Value="Center" />

                        </Style>

                    </GridView.ItemContainerStyle>

                </GridView>

            </SemanticZoom.ZoomedOutView>

            <SemanticZoom.ZoomedInView>               

                <GridView ItemsSource="{Binding Source={StaticResource cvs2}}" IsSwipeEnabled="True" ScrollViewer.IsHorizontalScrollChainingEnabled="False">

                    <GridView.ItemTemplate>

                        <DataTemplate>

                            <StackPanel Orientation="Horizontal" Margin="10,10,0,0" HorizontalAlignment="Left" Background="{StaticResource ApplicationPageBackgroundThemeBrush}">

                                <Image Source="{Binding Image}" Height="60" Width="60" VerticalAlignment="Center" Margin="0,0,10,0"/>

                                <TextBlock TextWrapping="Wrap" Foreground="{StaticResource ApplicationForegroundThemeBrush}" Width="200" VerticalAlignment="Center" Text="{Binding Title}" HorizontalAlignment="Left" FontFamily="Segoe UI" />

                            </StackPanel>

                        </DataTemplate>

                    </GridView.ItemTemplate>

                    <GridView.GroupStyle>

                        <GroupStyle>

                            <GroupStyle.HeaderTemplate>

                                <DataTemplate>

                                    <TextBlock Text='{Binding Key}' Foreground="{StaticResource ApplicationForegroundThemeBrush}" Margin="5" FontSize="18" FontFamily="Segoe UI Light" />

                                </DataTemplate>

                            </GroupStyle.HeaderTemplate>

                            <GroupStyle.ContainerStyle>

                                <Style TargetType="GroupItem">

                                    <Setter Property="Template">

                                        <Setter.Value>

                                            <ControlTemplate TargetType="GroupItem">

                                                <StackPanel Orientation="Vertical">

                                                    <ContentPresenter Content="{TemplateBinding Content}" />

                                                    <ItemsControl x:Name="ItemsControl" ItemsSource="{Binding GroupItems}" />

                                                </StackPanel>

                                            </ControlTemplate>

                                        </Setter.Value>

                                    </Setter>

                                </Style>

                            </GroupStyle.ContainerStyle>

                            <GroupStyle.Panel>

                                <ItemsPanelTemplate>

                                    <VariableSizedWrapGrid Orientation="Vertical" MaximumRowsOrColumns="3" />

                                </ItemsPanelTemplate>

                            </GroupStyle.Panel>

                        </GroupStyle>

                    </GridView.GroupStyle>

                    <GridView.ItemsPanel>

                        <ItemsPanelTemplate>

                            <WrapGrid Orientation="Vertical" MaximumRowsOrColumns="1" />

                        </ItemsPanelTemplate>

                    </GridView.ItemsPanel>

                    <Button Visibility="Collapsed"/>

                </GridView>

            </SemanticZoom.ZoomedInView>

        </SemanticZoom>

    </Grid>

</Page>

Step 10

Write code for MainPage.xaml.cs file as:

namespace SemanticZoom_Example

{   

    public sealed partial class BlankPage2 : Page

    {

        StoreData storeData;

        public BlankPage2()

        {

            this.InitializeComponent();         

            storeData = new StoreData();

            List<GroupInfoList<object>> dataLetter = storeData.GetGroupsByLetters();

            cvs2.Source = dataLetter;

            (semanticZoom.ZoomedOutView as ListViewBase).ItemsSource = cvs2.View.CollectionGroups;

        }       

    }

}

Step 11

Run the application and you see the output as:

Semantic-Zoom-In-Windows-Store-Apps.jpg

When I click on the button the screen will look like:

Semantic-Zoom-Switch-In-Windows-Store-Apps.jpg

Summary

In this article I explained how to create the SemanticZoom control in Windows Store apps.


Similar Articles