Panorama in Windows Phone 7

DZone 's Guide to

Panorama in Windows Phone 7

· Mobile Zone ·
Free Resource

In this article I will be talking about the new Panorama control. Chances are you've already seen it in action in the context of the new application template introduced in the final build of the Windows Phone 7 SDK.

Unlike the Pivot control, Panorama allows the user to slide through content without having to completely hide the previously displayed elements. A Panorama control is also divided in named sections - you could consider it a big page that could not fit on one screen so you can slide through it, viewing different content blocks.

To give you an idea of how the Panorama control behaves, take a look at this video.

In your XAML code section, you need to reference the Microsoft.Phone.Controls library via a namespace reference:

This is also tied to actual library reference in your project, so make sure you add that one as well.

You can now create a Panorama instance. You can do this either in the code-behind or while editing the page XAML. The second method is preferable since you are in direct control of layout and positioning for the new control.

The control is created by adding controls:Panorama tags inside a container (basically any object that has a Content property). Just like this:



A Panorama control has a global header that groups the entire set of objects placed inside it under a single name. This header is defined by the Title property. So, for example, if I would have to group various settings, I could set the title to Settings:

<controls:Panorama Title="Settings">


And here is what I would get:

If you slide the container, you will see that the label moves to the left and to the right, depending on the slide direction, even though there is no content inside the Panorama control. This was not possible with the Pivot control. Here I've noticed an interesting behavior - infinite slide. If there is no content inside the Panorama control, you can scroll to the right to an infinite distance, and then you will have to spend the same amount of time to scroll back. Not really something functional, but it's good to know that it's there.

A Panorama control is defined by a collection of PanoramaItem instances:


Unlike a PivotItem instance, a PanoramaItem automatically sets its height to the maximum available size. However, same as a PivotItem instance, you cannot set the Content property more than once, therefore if you plan on hosting multiple controls inside a single PanoramaItem, make sure you use a common container, like a Grid:

        <Button Height="90" Width="300"></Button>
        <TextBlock Text="Test"></TextBlock>

PanoramaItem can also have a text header defined, that will show the user the category to which the hosted content belongs. It can be set via the Header property and the end-result will look like this:

You can use multiple PanoramaItem instances inside a single Panorama control. Notice one interesting fact - the sliding speed of the global header will depend on the number of panorama items. Therefore, even though the header text is quite short ("Settings"), it will scroll slower as you slide through panorama items if you have lots of them, so that for the last item in the collection you will see the header ending. Less items - faster scrolling speed for the header.

The Panorama control can be used in the same context as the Pivot control, however with one difference - PanoramaItems are visible pretty much instantly when the user slides between content blocks, therefore you have to be aware that the user might be able to view parts of two control sets simultaneously.

In case you are curious about the ways to track down when a specific PanoramaItem is active (visible), you might want to take a look at ManipulationStarted, ManipulationDelta and ManipulationCompleted events - that's when you tie them to a specific item. Otherwise, you might want to settle with the good old SelectionChanged for the main control.


Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}