Microsoft Gold Certified Partner
 

Dynamic Panorama Control (WP7 basics)

In almost every Windows Phone 7 commercial we can see Panorama control.
*
Panorama (and also Pivot) control is a way of navigating in Windows Phone 7 applications. It allows us to use big, horizontal canvas that extends beyond right and left side of the screen.
Most examples that I found shows how to create “static” panorama control – control with already defined number of “PanoramaItems”.
I think that dynamic panoramas can be used for more flexible applications when user can define on his own, how many “pages” should application display and what content should be displayed.
I’ll quickly show how to create dynamic BBC reader application where user can select list of channels that he finds interesting and define how applications panorama control should look like.
Note: I didn’t spent too much time on polishing this application. Goal of this app is just to show how to create dynamic panorama controls.

1. Main Page XAML:
Here we are simply creating a List of checkboxes and an empty Panorama control.

    <Grid x:Name="LayoutRoot" Background="Transparent"  Margin="0,0,0,0">
        <ListBox Name="channelSelection"  SelectionMode="Multiple"
                 ItemsSource="{Binding ChannelSelection}" Margin="0,0,0,96">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <CheckBox x:Name="McCheckBox"
                      Canvas.Left="10" Canvas.Top="10"
                      Content="{Binding Name}"
                      IsChecked="{Binding Checked, Mode=TwoWay}">
                    </CheckBox>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <Button Name="channelSelected" Content="Save changes"
                Width="230" Margin="125,355,125,0" Height="90" VerticalAlignment="Bottom">
        </Button>

        <!--Panorama control-->
        <controls:Panorama Title="BBC News" Name="panorama" Visibility="Collapsed">
        </controls:Panorama>
    </Grid>

2. Handling Channel selection (Save button click)
After user selects channels, I’m hiding “channel selection”.
For each selected channel I’m adding new custom control to panorama items collection
and displaying it. BBCChannel constructor is taking channel object and panorama index as a parameter – latter one just to load only visible item.

        ///
        /// Handles 'save changes' button click (channel selection)
        ///
        void channelSelected_Click(object sender, RoutedEventArgs e)
        {
            panorama.Visibility = System.Windows.Visibility.Visible;
            channelSelection.Visibility = System.Windows.Visibility.Collapsed;
            channelSelected.Visibility = System.Windows.Visibility.Collapsed;

            var selectedChannels = (channelSelection.ItemsSource as ObservableCollection).Where(chan =&gt; chan.Checked == true).ToList();

            for (var index = 0; index &lt; selectedChannels.Count ;index++ )
            {
                BBCChannel chan = new BBCChannel(selectedChannels[index], index);
                panorama.Items.Add(chan);
            }
        }

3. Handling panorama “Selection Changed” event:
This will force BBCChannel control to load content when user tries to move to the next panorama item control.

            panorama.SelectionChanged += new EventHandler(panorama_SelectionChanged);
        ///
        /// Handles panorama item changed
        ///
        void panorama_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            (e.AddedItems[0] as BBCChannel).LoadComponent();
        }

4. BBCChannel user control XAML

    <Grid>
        <ProgressBar Name="progress" IsIndeterminate="True" Height="40" Style="{StaticResource PerformanceProgressBar}"></ProgressBar>
        <controls:PanoramaItem Name="panoNewsItem" Header="{Binding Name}" >
            <Grid>
                <ListBox ItemsSource="{Binding Items}">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                            <StackPanel Orientation="Horizontal" Margin="0,0,0,17">
                                <Image Height="49" Width="66" Source="{Binding ImageSource}">
                                </Image>
                                <StackPanel Width="311">
                                    <TextBlock Text="{Binding Title}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
                                    <TextBlock Text="{Binding Description}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
                                </StackPanel>
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
            </Grid>
        </controls:PanoramaItem>
    </Grid>

5. Data source contains list of “Channel” objects:

            this.ChannelSelection.Add(new Channel() { Name = "Top Stories", RssURL = "http://feeds.bbci.co.uk/news/rss.xml" });
            this.ChannelSelection.Add(new Channel() { Name = "World", RssURL = "http://feeds.bbci.co.uk/news/world/rss.xml" });
            this.ChannelSelection.Add(new Channel() { Name = "Business", RssURL = "http://feeds.bbci.co.uk/news/business/rss.xml" });
            this.ChannelSelection.Add(new Channel() { Name = "Politics", RssURL = "http://feeds.bbci.co.uk/news/politics/rss.xml" });
            this.ChannelSelection.Add(new Channel() { Name = "Health", RssURL = "http://feeds.bbci.co.uk/news/health/rss.xml" });
            this.ChannelSelection.Add(new Channel() { Name = "Entertainment &amp; Arts", RssURL = "http://feeds.bbci.co.uk/news/entertainment_and_arts/rss.xml" });
            this.ChannelSelection.Add(new Channel() { Name = "Science/Nature", RssURL = "http://feeds.bbci.co.uk/news/science_and_environment/rss.xml" });
            this.ChannelSelection.Add(new Channel() { Name = "Technology", RssURL = "http://feeds.bbci.co.uk/news/technology/rss.xml" });
            this.ChannelSelection.Add(new Channel() { Name = "Education", RssURL = "http://feeds.bbci.co.uk/news/education/rss.xml" });

Each channel object contains list of NewsItem objects; those object are responsible for storing News title, description, image URL and link to main article.

6. Final Result:

Dynamic Panorama (links to youtube)

This is very basic tutorial but I hope it will help someone.

* Image from MSDN Library

 

Tags: , , , ,

9 Responses to “Dynamic Panorama Control (WP7 basics)”

  1. jzon says:

    Hi, can have the source code for this panorama testing. i would like to see how channel object works and store the data. thanks

  2. john says:

    hi, it’s a brilliant example ;)

    do you know any way we can reduce the size of the title?
    I tried with the fontSize property but still the same.

    thanks :)

  3. Kumar says:

    Hi! Thanks for your code. It is very helpful.

    In the BBCChannel UserControl Orientation=”Horizontal” is not working. I tried as shown below:

    It doesn’t expand to the given width, don’t why?

    Thanks http://www.felinesoft.com/blog/wp-includes/images/smilies/icon_smile.gif

  4. jake v says:

    you saved me about a week’s worth of work. but most importantly, you saved me a big headache.

  5. Hemant says:

    Can you share the source code, the link above is broken.

    Thanks

  6. Tiago says:

    The link to the source code doesn’t work. I am trying to follow the tutorial but I can’t get it to work.

  7. The above source code is not working….please share a link.

    I am learning Panorama control and i think i will get help from you and from this article.

  8. TeJ says:

    Hi,

    Your post is very helpful to develop a dynamic panoramic control. Will you please share with me the source code for better understanding.

    Thank You in Advance…. :)

  9. momo says:

    can you share full source code of your project, please?

    Thanks before