Other articles in the PivotViewer V2 Series:
- Part 1: Intro
- Part 2: Creating a Project
- Part 3: Receiving OData
- Part 4: Trade Cards
- Part 5: Pivot Panel
- Part 6: Links and Interactions
- Part 7: Pivot Properties
- Part 8: Multi-facacited Pivot Properties
- Part 9: Large Data Sets
- Part 10: Teaching Your Users
- Part 11: Exposing Your Own Data
- Part 12: Advanced Sorting
- Part 13: Advanced Trade Cards
- Part 14: Working with Excel
This entry builds upon the previous parts. You can jump right to this point by downloading the following ZIP file, PivotViewerSeries_Part3.zip.
Creating Visuals
So, we have data put into the PivotViewer, but we are missing some exciting visuals. To create all of the visuals you will see here, we just need to make some changes to MainPage.xaml’s PivotViewer control.
Trade Cards
The visuals each data item in a collection is call a “Trade Card”. One of the exciting features for PivotViewer 2.0 is that trade cards can be much more dynamic than the previous CXML method of the past. For example, we can show different trade cards depending on how zoomed in we are. Or we can show more information as needed.
Creating a Trade Card
First we need to create a default trade card for our Netflix data. To do this, we are just going to create a new DataTemplate and attaching it to our PivotViewer control:
- <pivot:PivotViewer ItemsSource="{Binding Titles}">
- <pivot:PivotViewer.ItemTemplates>
- <pivot:PivotViewerItemTemplate>
- <Border BorderBrush="Black" BorderThickness="1">
- <Image Source="{Binding Path=BoxArt.SmallUrl
- , Converter={StaticResource ImageConverter}
- , Mode=OneTime}"
- Width="65" Height="89" />
- </Border>
- </pivot:PivotViewerItemTemplate>
- </pivot:PivotViewer.ItemTemplates>
- </pivot:PivotViewer>
And we will also need to add the ImageConverter that will take our image’s URL string and convert it to a Uri object:
- using System;
- using System.Globalization;
- using System.Windows.Data;
- using System.Windows.Media;
- using System.Windows.Media.Imaging;
-
- namespace PivotViewerSeries.Silverlight
- {
- public class ImageConverter : IValueConverter
- {
- public object Convert(object value
- , Type targetType
- , object parameter
- , CultureInfo culture)
- {
- ImageSource Output = null;
- if (value != null)
- Output = new BitmapImage(new Uri(value.ToString()));
- else
- Output = new BitmapImage();
- return Output;
- }
-
- public object ConvertBack(object value
- , Type targetType
- , object parameter
- , CultureInfo culture)
- {
- throw new NotImplementedException();
- }
- }
- }
And finally, reference that converter in our App.xaml:
- <Application.Resources>
- <vm:ViewModelLocator x:Key="Locator"
- d:IsDataSource="True" />
- <this:ImageConverter x:Key="ImageConverter" />
- </Application.Resources>
Now when we run our application, we will get the following result. Be aware, that depending on your connection, it may take a bit for data to load from Netflix and for the images to download.

Using Multiple Trade Cards
To use different trade cards at different zoom levels, we can add more PivotViewerItemTemplate objects to the ItemTemplates collection, setting the MaxWidth property each time to tell the object how wide a template can go before showing the next larger one.
It is important that the aspect ratio for each trade card must be the same, otherwise you will start to see some weird sizing issues.
First, lets update our small trade card with the MaxWidth:
- <!-- Small Trade Card -->
- <pivot:PivotViewerItemTemplate MaxWidth="100">
- <Image Source="{Binding Path=BoxArt.SmallUrl
- ,Converter={StaticResource ImageConverter}}"
- Width="65" Height="89" />
- </pivot:PivotViewerItemTemplate>
And create a new medium sized trade card that includes the movie title:
- <!-- Medium Trade Card -->
- <pivot:PivotViewerItemTemplate MaxWidth="500">
- <Border BorderBrush="Black" BorderThickness="0">
- <StackPanel Orientation="Vertical">
- <TextBlock Text="{Binding Name}"
- Width="176"
- FontSize="14"
- FontWeight="Bold"
- TextWrapping="Wrap"
- HorizontalAlignment="Center"/>
- <Image Source="{Binding Path=BoxArt.MediumUrl
- ,Converter={StaticResource ImageConverter}}"
- Width="176" Height="240" />
- </StackPanel>
- </Border>
- </pivot:PivotViewerItemTemplate>
Which, when zoomed in enough will look like this:

And finally, lets create a large trade card that can give us some more information:
- <!-- Large Trade Card -->
- <pivot:PivotViewerItemTemplate>
- <Viewbox Width="1200" Height="1636" MinHeight="1636" MinWidth="1200">
- <Grid Width="600" Height="818" >
- <Grid.RowDefinitions>
- <RowDefinition Height="614" />
- <RowDefinition Height="204" />
- </Grid.RowDefinitions>
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="450" />
- <ColumnDefinition Width="150" />
- </Grid.ColumnDefinitions>
- <Image Grid.Row="0"
- Grid.Column="0"
- Source="{Binding Path=BoxArt.LargeUrl
- ,Converter={StaticResource ImageConverter}}"
- Width="450" Height="614" />
- <StackPanel Grid.Row="0"
- Grid.Column="1"
- Orientation="Vertical"
- Margin="2">
- <TextBlock Text="{Binding Rating
- , StringFormat='MPAA Rating: {0}'}" />
- <TextBlock Text="{Binding AverageRating
- , StringFormat='NetFlix Rating: {0} / 5'}" />
- <TextBlock Text="{Binding ReleaseYear
- , StringFormat='Release Year: {0}'}" />
- <TextBlock Text="{Binding Runtime
- , StringFormat='Length: {0} seconds'}" />
- </StackPanel>
- <StackPanel Grid.Row="1"
- Grid.Column="0"
- Grid.ColumnSpan="2"
- Orientation="Vertical"
- Margin="10">
- <TextBlock Text="{Binding Name}"
- FontSize="36"
- FontWeight="Bold"
- TextWrapping="Wrap"/>
- <TextBlock Text="{Binding Synopsis}"
- FontSize="16"
- TextWrapping="Wrap"/>
- </StackPanel>
- </Grid>
- </Viewbox>
- </pivot:PivotViewerItemTemplate>
Which results in something like the following:

If you find your project ‘skipping’ a template, it is likely that your templates are too close in size to each other. For PivotViewer to take the time to optimize and repaint all the cards, it need to make sure it is worth it, and a 50 or 100 pixel change is viewed as not being worth wild.