Free Trial

Safari Books Online is a digital library providing on-demand subscription access to thousands of learning resources.

Share this Page URL
Help

Chapter 10. Pivot and Panorama > Using the Panorama Control

Feedback: 0 Comments on this Section

Using the Panorama Control

Using the Panorama Control Working with the Panorama control is much like working with the Pivot. You can create a Panorama in the same way as a Pivot, either by using the built-in project or application template, or by manually adding the Panorama XAML to an existing page. The XAML for a Panorama usually looks something like this: <controls:Panorama Title="an application">

    <controls:PanoramaItem Header="item1">
        <!-- Place content here. -->
    </controls:PanoramaItem>

    <controls:PanoramaItem Header="item2">
        <!-- Place content here. -->
    </controls:PanoramaItem>

</controls:Panorama> The PanoramaItem controls host the panoramic content, and these represent the sections displayed within the control. Panorama Anatomy The Panorama is comprised of three different layers: • Background layer • Title layer • Items layer Each layer is contained within a Grid control that serves as the layout root for the Panorama control (see Figure 10.8). Figure 10.8. The Panorama control anatomy Background Layer The background represents the bottom layer of the Panorama, with sections sitting above. The background layer is represented by a PanningBackgroundLayer within the Panorama class. This layer is set with the Background property on the Panorama control. You can set the background of the Panorama to an image using an ImageBrush. Alternatively, a color or gradient can be used by assigning the Background property to a SolidColorBrush or GradientBrush. Note You should not set a Panorama control’s Background to null. If it is set to null, gesture response is unreliable. The Background is set to Transparent by default in the default template. The background is stretched vertically to fill the height of the Panorama. The ImageBrush retains the width of the ImageSource, while the GradientBrush is stretched to fill the width of the items. Note The default template for the Panorama uses bitmap caching for the Panorama’s Background property. Clipping occurs for UI elements with bitmap caching enabled if they exceed 2000 by 2000 pixels. Therefore, restrict the size of your background image to less than this size. Bitmap caching helps to improve performance by storing visual elements as bitmaps after the first time they are rendered. Once an element has been cached as a bitmap, it no longer needs to be included as part of the render phase when the UI refreshes. This means less processing needs to be done, as just the cached bitmap is rendered. Cached bitmaps can take advantage of hardware acceleration using the phone’s GPU, which has the potential of yielding significant performance improvements in some situations. Tip Avoid positioning the background according to the content position. The Panorama title moves at a different rate than its section titles, as the user moves across the Panorama. Title Layer The title layer is represented by a PanningTitleLayer within the Panorama class. This layer presents the title of the app and is assigned using the Panorama.Title property. The Panorama Title can be specified as text; however, there is also a TitleTemplate property, which allows you to completely customize the appearance of the Title. The vertical height of this layer remains constant and is unaffected by oversized content or the absence of content. The layer does not wrap back on itself but rather animates back to the starting position when you pan past the final section. Best Practice Avoid animating the Panorama title or dynamically changing its size after it has loaded. Doing so can interfere with the Panorama’s built-in animations. Items Layer The items layer is represented by a PanningLayer within the Panorama class. This layer contains the content of the PanoramaItem controls. A pan gesture causes this layer to move at the same rate. Therefore, the content beneath the finger at the beginning of the pan gesture remains beneath the finger until the finger leaves the display. PanoramaItem Control Each PanoramaItem control represents individual sections of content. The PanoramaItem is itself comprised of two parts: a header part and a content part. Each part is contained within a Grid that serves as the layout root for the PanoramaItem control. The contents of a PanoramaItem can either be specified in XAML, or added programmatically using its Content property. The headers of all PanoramaItems can be uniformly customized by using the Panorama’s HeaderTemplate property. This works in the same manner as the example for the Pivot in the previous section. You can hide a PanoramaItem by setting its Visibility property to Collapsed. This can be useful when you need to conceal an item before it has loaded some other resource. Tip As mentioned earlier in the chapter, when a Panorama loads, all Panorama items undergo a render pass. Thus, a Panorama with too many items may take a long time to load. Alternatively, to improve performance, where reducing the number of items is not an option, consider delay loading controls and content. Unlike the Pivot, however, the Panorama does not have load events (such as the LoadingPivotItem event), which further underscores the differences between the purpose and nature of the two controls. If you find that the Panorama’s performance is not up to scratch, then it may indicate that your content is not suited to the Panorama and that a different control or approach is needed. PanoramaItem Orientation The Orientation property of the PanoramaItem affects how content is snapped into place during a pan gesture. The default value of the Orientation property is Vertical. By setting the property to Horizontal, the user is able to pan around the content without snapping a PanoramaItem into place. A horizontal orientation also allows for the content to be placed off the screen instead of being clipped. This reinforces the panoramic nature of the control. Sample Panorama Application The sample for this section makes use of the WCF Bookshop Service, which was detailed in Chapter 3, “Application Execution Model.” This service is used to retrieve a list of products and present them within a Panorama. The code is located in the files PanoramaView.xaml, PanoramaView.xaml.cs, and PanoramaViewModel.cs in the downloadable sample code. The viewmodel, for this example, exposes a collection of Product objects, which are retrieved from the Bookshop Service when the viewmodel is instantiated, and a single featured product, which is simply the first member of the collection (see Listing 10.8). Listing 10.8. PanoramaViewModel Class public class PanoramaViewModel : ViewModelBase
{
    public PanoramaViewModel()
    {
        BookshopServiceClient client = new BookshopServiceClient();
        client.GetProductsCompleted
            += (sender, args) =>
                {
                    if (args.Error != null)
                    {
                        throw args.Error;
                    }

                    Products = args.Result;
                    FeaturedProduct = args.Result.FirstOrDefault();
                };
        client.GetProductsAsync();
    }

    ObservableCollection<Product> products;

    public ObservableCollection<Product> Products
    {
        get
        {
            return products;
        }
        private set
        {
            Assign("Products", ref products, value);
        }
    }

    Product featuredProduct;

    public Product FeaturedProduct
    {
        get
        {
            return featuredProduct;
        }
        private set
        {
            Assign("FeaturedProduct", ref featuredProduct, value);
        }
    }
} The PanoramaView code-beside is used to instantiate an instance of the PanoramaViewModel, which is assigned to PanoramaView’s DataContext (see Listing 10.9). Listing 10.9. PanoramaView Class public partial class PanoramaView : PhoneApplicationPage
{
    public PanoramaView()
    {
        InitializeComponent();
        DataContext = new PanoramaViewModel();
    }
} The view contains two PanoramaItems. The first displays the list of products and is titled Best Picks. A Silverlight Toolkit WrapPanel control is used to display the Product images thumbs (see Listing 10.10). For more information on the WrapPanel control, see Chapter 9, “Silverlight Toolkit Controls.” The second PanoramaItem presents the details of the featured product; a larger image is displayed for the product, and a HyperlinkButton allows you to open the built-in web browser application. Listing 10.10. PanoramaView.xaml (excerpt) <Grid x:Name="LayoutRoot" Background="Transparent">
    <controls:Panorama x:Name="Panorama"
        Title="Bookshop">
        <controls:Panorama.Background>
            <ImageBrush ImageSource="../../../Images/PanoramaBackground.png"/>
        </controls:Panorama.Background>

        <controls:PanoramaItem Header="Best Picks">
            <ListBox ItemsSource="{Binding Products}">
                <ListBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <toolkit:WrapPanel x:Name="wrapPanel"  />
                    </ItemsPanelTemplate>
                </ListBox.ItemsPanel>
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <Image Source="{Binding SmallImageUri}"
                               MaxWidth="150" MaxHeight="150"
                               Margin="10" />
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </controls:PanoramaItem>

        <controls:PanoramaItem Header="Featured"
                    DataContext="{Binding FeaturedProduct}">
            <StackPanel>
                <TextBlock Text="{Binding Product.Title}"
                TextWrapping="Wrap"
                Style="{StaticResource PhoneTextTitle2Style}"/>
                <StackPanel Orientation="Horizontal">
                    <Image Source="{Binding LargeImageUri}"
                           MaxWidth="250" MaxHeight="250"
                           Margin="10,10,0,10"/>
                    <StackPanel>
                        <TextBlock Text="{Binding Author}"
                        TextWrapping="Wrap"
                        Style="{StaticResource PhoneTextTitle3Style}"/>
                        <TextBlock Text="{Binding Price,
                        Converter={StaticResource StringFormatConverter},
                        ConverterParameter=\{0:C\}}"
                        Style="{StaticResource PhoneTextTitle3Style}"/>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="ISBN"
                            Style="{StaticResource PhoneTextTitle3Style}"/>
                            <TextBlock Text="{Binding Isbn13}"
                            TextWrapping="Wrap"
                            Style="{StaticResource PhoneTextNormalStyle}"/>
                        </StackPanel>

                        <HyperlinkButton
                            NavigateUri="{Binding ExternalUrl}"
                            TargetName="_blank"
                            Content="External Page"
                            Margin="0,10,0,0"
                            HorizontalAlignment="Left" />
                    </StackPanel>
                </StackPanel>
            </StackPanel>
        </controls:PanoramaItem>

    </controls:Panorama>
</Grid> Figure 10.9 shows the Panorama presenting the first PanoramaItem. Notice that the second PanoramaItem is partially displayed. This helps to improve the user’s awareness of neighboring content. Figure 10.9. The first PanoramaItem presents a list of Products in a WrapPanel. Figure 10.10 shows the second PanoramaItem selected. Here the title and background have been scrolled horizontally. Figure 10.10. The second PanoramaItem presents the featured product.

You are currently reading a free preview of this book.

                                                                                                         

Sign up for a
Safari Library subscription
to access Rough Cuts.

  

Subscribe Now