A gentle introduction to the semantic zoom pivot viewer in LightSwitch.

Introduction

Silverlight 5 has an amazing control called the PivotViewer which has semantic zoom capabilities. What is semantic zoom? Well, stop reading and open following link:

http://www.bluesware.ch/parlament/ .

Play with is and if you like this, continue reading and be confident that you can leverage all this in LightSwitch as well, without having to buy expensive 3rd party extensions or controls. Furthermore the fact that the control is part of the silverlight framework is a garantee for high quality !

Let’s get started with a basic example.

We’ll build an example to visualize a fictious movie database. I have no real movie database at my disposal. So we’ll make sure we can easily construct some random test data. The idea is that you have the pivotviewer up and running in less than 3 minutes. I’m using visual studio 2012.

Let’s start with a very basic movie table containing only following fields:

 

Next, generate  a simple ListDetail screen for the movie entity type and attach a button to the screen and call it “AddTestData”.

With this button we will… create test data:

 

public partial class MoviesListDetail
    {
        partial void AddTestData_Execute()
        {
            Int32 startNumber = 1;

            var lastMovieRecord = this.DataWorkspace.ApplicationData.Movies.OrderByDescending(m => m.Id).FirstOrDefault();
            if (lastMovieRecord != null)
            {
                startNumber = lastMovieRecord.Id + 1;
            }

            Random random = new Random();
            for (int i = startNumber; i <= startNumber + 100; i++)
            {
                Movie newMovie = this.Movies.AddNew();

                var mod = i % 6;

                switch (mod)
                {
                    case 0:
                        newMovie.Category = "Thriller";
                        break;
                    case 1:
                        newMovie.Category = "Comedy";
                        break;
                    case 2:
                        newMovie.Category = "Adult";
                        break;
                    case 3:
                        newMovie.Category = "Sience Fiction";
                        break;
                    case 4:
                        newMovie.Category = "Documentary";
                        break;
                    case 5:
                        newMovie.Category = "Adult";
                        break;
                }

                newMovie.ReleaseDate = DateTime.Now.AddDays(-1 * random.Next(3000));
                newMovie.MovieName = "Movie " + i.ToString();
            }
            this.Save();
        }

As you can see, you can call this method consecutively (each time more test data are added).

Add the pivot viewer silverlight control

First add a new silverlight class library in which we will add a new silverlight user control which we will  call “MoviePivotControl”.

Add a reference to the System.Windows.Controls.Pivot.dll.

This is the xaml for the control:

<UserControl x:Class="SilverlightPivot.MoviePivotControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:pivot="clr-namespace:System.Windows.Controls.Pivot;assembly=System.Windows.Controls.Pivot"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <pivot:PivotViewer x:Name="pViewer"  ItemsSource="{Binding Screen.Movies}">
            <pivot:PivotViewer.PivotProperties>
                <pivot:PivotViewerStringProperty
            Id="MovieName"
            Options="CanSearchText"
            Binding="{Binding MovieName}"/>

                <pivot:PivotViewerDateTimeProperty
            Id="ReleaseDate"
            Options="CanFilter"
            Binding="{Binding ReleaseDate}"/>
                <pivot:PivotViewerStringProperty
            Id="Category"
            Options="CanFilter"
            Binding="{Binding Category}"/>
                <pivot:PivotViewerNumericProperty
            Id="Value"
            Options="None"
            Binding="{Binding Value}"/>
            </pivot:PivotViewer.PivotProperties>
            <pivot:PivotViewer.ItemTemplates>
                <pivot:PivotViewerItemTemplate>
                    <Border Width="300" Height="300" Background="Red" >
                        <StackPanel Orientation="Vertical">
                            <TextBlock Text="{Binding MovieName}" 
                            FontSize="30"
                            FontWeight="Bold"
                            Foreground="White"
                            HorizontalAlignment="Center" 
                            VerticalAlignment="Center" />
                            <TextBlock Text="{Binding Category}" 
                            FontSize="30"
                            FontWeight="Bold"
                            Foreground="White"
                            HorizontalAlignment="Center" 
                            VerticalAlignment="Center" />
                        </StackPanel>
                    </Border>
                </pivot:PivotViewerItemTemplate>
            </pivot:PivotViewer.ItemTemplates>
        </pivot:PivotViewer>
    </Grid>
</UserControl>

 

There is no specific code in the associated code file.

Consume the PivotViewer in your LightSwitch project.

We are almost finished. Start from a “New Data Screen” and do not attach it to any screen data. Now simply add the custom control to this screen:

Make sure to click in properties Change… and select the MoviePivotControl. Disable paging on the Movies query and change in the properties of the custom control also the label position to “None”.

Start using the pivot viewer.

F5 you LightSwitch project and first generate some test data in the Movie ListDetail screen. Go then to the pivot screen and you should see this:

 

You can click on a card which will visualize the movie details:

 

Of course the real fun is the filtering and searching:

You can search on the movie name. The following example shows all movies with “3” in the name:

You can filter as well on the Release date, but also on the category. In order to see the category filters, first click on the ReleaseDate header which will unhide the Category filter:

 

 

 

 

 

 

 

 

The following reveals the real intelligence of the PivotViewer control: first make a filtering on the ReleaseDate for a year where there are less than 4 movies. Now, go to the Category filter. You will see that only the categories can be selected applicable to what’s relevant given your selection on release date:

 

 

 

 

 

 

 

 

 

Conclusion

I limited deliberately this demo to a very basic example. Trust me, the real fun comes in later posts I’m planning to do on this subject:

  • We’ll introduce colored cards (e.g. every movie category is represented by a specific color,
  • we’ll make the cards really responsive to semantic zoom (meaning that a card’s morphology changes when you zoom !),
  • we can introduce adorners,