WEBINAR:
On-Demand
Desktop-as-a-Service Designed for Any Cloud ? Nutanix Frame
Using a Pivot
To add a page with a pivot control, use the Add New Item command and from the available pages select Windows Phone Pivot Page. This will add a new page with the layout root containing a pivot (we'll call this MoviePivotPage.xaml).
[wp7pp_pivottemplate.png]
The XAML code looks like this:
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<!--Pivot Control-->
<controls:Pivot Title="my application">
<!--Pivot item one-->
<controls:PivotItem Header="item1">
<Grid>
</controls:PivotItem>
<!--Pivot item two-->
<controls:PivotItem Header="item2">
<Grid>
</controls:PivotItem>
</controls:Pivot>
</Grid>
As you can see the wizard defines two pivot items (the class that represents a pivot item is simply called PivotItem), with an empty grid as the content. We can either use the grid to add more controls, or replace it with a stack panel or a list (as we'll see in this example) or any other control. The following listing shows how the pivot will look in this example, with various controls used to display movie information in each of the four pivot items (overview, synopsis, cast and poster).
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<!--Pivot Control-->
<controls:Pivot Title="{Binding Path=Title}">
<!--Pivot item one-->
<controls:PivotItem Header="overview">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0"
Margin="5,5,5,5"
Text="Year" />
<TextBlock Grid.Row="0" Grid.Column="1"
Margin="5,5,5,5"
Text="{Binding Path=Year}" />
<TextBlock Grid.Row="1" Grid.Column="0"
Margin="5,5,5,5"
Text="Release date" />
<TextBlock Grid.Row="1" Grid.Column="1"
Margin="5,5,5,5"
Text="{Binding Path=ReleaseDate}" />
<TextBlock Grid.Row="2" Grid.Column="0"
Margin="5,5,5,5"
Text="Rating" />
<TextBlock Grid.Row="2" Grid.Column="1"
Margin="5,5,5,5"
Text="{Binding Path=Rating}" />
<TextBlock Grid.Row="3" Grid.Column="0"
Margin="5,5,5,5"
Text="Runtime" />
<TextBlock Grid.Row="3" Grid.Column="1"
Margin="5,5,5,5"
Text="{Binding Path=Runtime}" />
<TextBlock Grid.Row="4" Grid.Column="0"
Margin="5,5,5,5"
Text="Plot" />
<TextBlock Grid.Row="4" Grid.Column="1"
Margin="5,5,5,5"
TextWrapping="Wrap"
Text="{Binding Path=Plot}" />
<TextBlock Grid.Row="5" Grid.Column="0"
Margin="5,5,5,5"
Text="Genre(s)" />
<ListBox Grid.Row="5" Grid.Column="1"
Margin="5,5,5,5"
ItemsSource="{Binding}"
x:Name="listGenres"/>
<TextBlock Grid.Row="6" Grid.Column="0"
Margin="5,5,5,5"
Text="Staring" />
<ListBox Grid.Row="6" Grid.Column="1"
Margin="5,5,5,5"
ItemsSource="{Binding}"
x:Name="listStars"/>
<TextBlock Grid.Row="7" Grid.Column="0"
Margin="5,5,5,5"
Text="Director(s)" />
<ListBox Grid.Row="7" Grid.Column="1"
Margin="5,5,5,5"
ItemsSource="{Binding}"
x:Name="listDirectors"/>
<TextBlock Grid.Row="8" Grid.Column="0"
Margin="5,5,5,5"
Text="Writer(s)" />
<ListBox Grid.Row="8" Grid.Column="1"
Margin="5,5,5,5"
ItemsSource="{Binding}"
x:Name="listWriters"/>
</Grid>
</controls:PivotItem>
<controls:PivotItem Header="synopsis">
<StackPanel>
<TextBlock Text="Tagline"
Style="{StaticResource PhoneTextTitle2Style}"/>
<TextBlock Text="{Binding Path=Tagline}"
TextWrapping="Wrap"
Margin="10,10,10,10"/>
<TextBlock Text="Storyline"
Style="{StaticResource PhoneTextTitle2Style}"/>
<TextBlock Text="{Binding Path=Storyline}"
TextWrapping="Wrap"
Margin="10,10,10,10"/>
</StackPanel>
</controls:PivotItem>
<!--Pivot item three-->
<controls:PivotItem Header="cast">
<ListBox ItemsSource="{Binding}"
x:Name="listCast"/>
</controls:PivotItem>
<!--Pivot item four-->
<controls:PivotItem Header="poster">
<Image x:Name="imgPoster"/>
</controls:PivotItem>
</controls:Pivot>
</Grid>
First step is to create an IMDb object holding information about the searched movie (parsed from the IMDB HTML results page) and pass it to the pivot page. We do that with the transient dictionary as we've seen in a previous article.
IMDb movie = new IMDb(response);
PhoneApplicationService.Current.State["movie"] = movie;
if (rbtnPivot.IsChecked.HasValue && rbtnPivot.IsChecked.Value)
{
this.NavigationService.Navigate(new Uri("/MoviePivotPage.xaml", UriKind.Relative));
}
Then, on the results page, we override the OnNavigatedTo handler, fetch the movie from the transient cache and set it as data context for the page and controls.
protected override void OnNavigatedTo(NavigationEventArgs e)
{
object obj;
if (PhoneApplicationService.Current.State.TryGetValue("movie", out obj))
{
IMDb movie = (IMDb)obj;
this.DataContext = movie;
this.listGenres.DataContext = movie.Genres;
this.listStars.DataContext = movie.Stars;
this.listDirectors.DataContext = movie.Directors;
this.listWriters.DataContext = movie.Writers;
this.listCast.DataContext = movie.Cast;
this.imgPoster.Source = new BitmapImage(new Uri(movie.Poster, UriKind.Absolute));
}
base.OnNavigatedTo(e);
}
If we now run the application, search for "gladiator" and display the results in the pivot, we'll see the pages filled with information as shown in the following image. You can sweep your finger across the screen (if you're using a real device) or use the mouse to simulate that if you're using the emulator, to navigate through the pivot items.
[wp7pp_pivot_2.jpg]
The Pivot control defines several events:
- LoadingPivotItem: gives you the opportunity to dynamically load or change the content of a pivot item before it is displayed.
- LoadedPivotItem: indicates that an item was completely loaded.
- UnloadingPivotItem: gives you the opportunity to dynamically load, change or remove the content of a pivot item as it is removed.
- UloadedPivotItem: indicates that the pivot item has been completely unloaded from the visual pivot.
- SelectionChanged: indicates that the currently selected item changed.
The following events are fired when we open the pivot page with the "overview" item first displayed, and then we navigate to the "synopsis" item: SelectionChanged ("overview" added) -> LoadingPivotItem ("overview") -> LoadedPivotItem ("overview") -> UnloadingPivotItem ("overview") -> SelectionChanged ("overview" removed, "synopsis" added) -> LoadingPivotItem ("synopsis") -> UnloadedPivotItem ("overview") -> LoadedPivotItem ("synopsis").
Let's see an example for using these events: instead of loading the poster image when we display the page, we'll only load and display it when the user navigates to the "poster" pivot item. This way we won't load unnecessary resources (in case the user never views the poster item).
<controls:Pivot Title="{Binding Path=Title}"
LoadedPivotItem="Pivot_LoadedPivotItem">
Then, the page code will change as shown below. Notice that the image is loaded only the first time the LoadedPivotItem fires for the "poster" item.
public partial class MoviePivotPage : PhoneApplicationPage
{
IMDb m_movie;
public MoviePivotPage()
{
InitializeComponent();
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
object obj;
if (PhoneApplicationService.Current.State.TryGetValue("movie", out obj))
{
m_movie = (IMDb)obj;
this.DataContext = m_movie;
this.listGenres.DataContext = m_movie.Genres;
this.listStars.DataContext = m_movie.Stars;
this.listDirectors.DataContext = m_movie.Directors;
this.listWriters.DataContext = m_movie.Writers;
this.listCast.DataContext = m_movie.Cast;
}
base.OnNavigatedTo(e);
}
private void Pivot_LoadedPivotItem(object sender, PivotItemEventArgs e)
{
string header = e.Item.Header as string;
if (header == "poster")
{
if(imgPoster.Source == null)
imgPoster.Source = new BitmapImage(new Uri(m_movie.Poster, UriKind.Absolute));
}
}
}