Monday, May 27, 2013

WP7 - Panorama Control Data Binding in WP7

Panorama controls are used to slide through a big content without having to completely hide the previous contents, we can consider of sliding through a horizontal page with different contents and blocks. We can use this Panorama control to show rich user interface by dividing the contents to different blocks and assigning to different items horizontally which we can slide through and access the data.

The panorama controls enables you to create the UI of an application on the horizontal canvas which can be flicked to left and right with touch.

In this article i will show you how to dynamically Bind data to Panorama Control.

Step 1
To Develop application for Windows Phone 7 devices, you need to install Windows Phone 7.1 SDK and toolkit. You can download latest SDK for Windows Phone
http://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=27570

SDK 7.1.1 Update
https://dev.windowsphone.com/en-us/downloadsdk

Silverlight for Window Phone Toolkit
http://silverlight.codeplex.com/releases/view/75888

Install SDK and Toolkit on your Machine.

Step 2

Create a Window Phone Application and give the solution name as SolPanoramaControl_WP7.
To start creating a new Windows Phone application, start Microsoft Visual Studio then create a new Project and select Windows Phone Application Template,it is look like this



Click on Image for better View

Step 3
Select the Window Phone Platform,it is look like this



Click on Image for better View

Step 4
Add a Window.Phone.Controls References
To add a reference, right click the References in Solution Explorer and select Add Reference. On this dialog, Select .Net Tab,Select Microsoft.Phone.Controls,Click on Add Button,it is look like this



Click on Image for better View

Step 5
Add a System.Xml.Linq Assemble reference to the project.Right click on the project name in Solution Explorer, select Add Reference and Select System.Xml.Linq  and select OK button,it is look like this



Click on Image for better View

Step 6
Create a New Folder in the Solution and give folder name as Images and add Images in folder ,it is look like this



Click on Image for better View

Step 7
Add XML file in the solution and give the file name as ImageData.xml,it is look like this



Click on Image for better View

Step 8
The XML in the following example defines an XML document with a root node called Images. This root node contains one or more nodes called Image that include elements called ImageName and ImagePath.
<?xml version="1.0" encoding="utf-8" ?>
<Images>

  <Image>
    <ImageName>Choji Akimichi</ImageName>
    <ImagePath>../Images/Choji.png</ImagePath>
  </Image>

  <Image>
    <ImageName>Gaara</ImageName>
    <ImagePath>../Images/Gaara.jpg</ImagePath>
  </Image>

  <Image>
    <ImageName>Jiraiya</ImageName>
    <ImagePath>../Images/Jiraiya.png</ImagePath>
  </Image>

  <Image>
    <ImageName>Kakashi Hatake</ImageName>
    <ImagePath>../Images/Kakashi.jpg</ImagePath>
  </Image>

  <Image>
    <ImageName>Kiba Inuzuka</ImageName>
    <ImagePath>../Images/Kiba.png</ImagePath>
  </Image>

  <Image>
    <ImageName>Killer Bee</ImageName>
    <ImagePath>../Images/KillerBee.jpg</ImagePath>
  </Image>

  <Image>
    <ImageName>Rock Lee</ImageName>
    <ImagePath>../Images/Lee.jpg</ImagePath>
  </Image>

  <Image>
    <ImageName>Might Guy</ImageName>
    <ImagePath>../Images/Might Guy.jpg</ImagePath>
  </Image>

  <Image>
    <ImageName>Naruto Uzumaki</ImageName>
    <ImagePath>../Images/Naruto.png</ImagePath>
  </Image>

  <Image>
    <ImageName>Neji Hyuga</ImageName>
    <ImagePath>../Images/Neji.png</ImagePath>
  </Image>

  <Image>
    <ImageName>Sai</ImageName>
    <ImagePath>../Images/Sai.jpg</ImagePath>
  </Image>

  <Image>
    <ImageName>Sasuke Uchiha</ImageName>
    <ImagePath>../Images/Sasuke.jpeg</ImagePath>
  </Image>

  <Image>
    <ImageName>Shikamaru Nara</ImageName>
    <ImagePath>../Images/Shikamarunara.jpg</ImagePath>
  </Image>

  <Image>
    <ImageName>Shino Aburame</ImageName>
    <ImagePath>../Images/Shino.jpg</ImagePath>
  </Image>

  <Image>
    <ImageName>Itachi Uchiha</ImageName>
    <ImagePath>../Images/UchihaItachi.png</ImagePath>
  </Image>

  <Image>
    <ImageName>Yamato</ImageName>
    <ImagePath>../Images/Yamato.jpg</ImagePath>
  </Image>
 

</Images>

Step 9
Create an ImageEntity Class in the solution,it is look like this
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SolPanoramaControl_WP7
{
    public class ImageEntity
    {
        #region Property
        /// 
        /// Get and Set Image Name
        /// 
        public String ImageName
        {
            get;
            set;
        }

        /// 
        /// Get and Set Image Path
        /// 
        public String ImagePath
        {
            get;
            set;
        }

        #endregion
    }
}

Step 10
Create a ImageView static class in a solution for retrieving data from XML document.it is look like this
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

namespace SolPanoramaControl_WP7
{
    public static class ImageView
    {
        #region Methods

        /// <summary>
        /// Read Data from XML File
        /// </summary>
        /// <returns>List</returns>
        public static List<ImageEntity> GetDataFromXML()
        {
            try
            {
                // Load XML Document  
                XDocument XDoc = XDocument.Load("ImageData.xml");

                // Using Linq
                //Query for retrieving all Images data from XML  
                //var Query =( from Q in XDoc.Descendants("Image")
                //            select new ImageEntity
                //            {
                //                ImageName = Q.Element("ImageName").Value,
                //                ImagePath = Q.Element("ImagePath").Value
                //            }).ToList<ImageEntity>();

               // Using Lambda Expression
                var Query = XDoc.Descendants("Image").Select(LE => new ImageEntity { ImageName = LE.Element("ImageName").Value, ImagePath = LE.Element("ImagePath").Value }).ToList<ImageEntity>();
                
                return Query;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message); 
            }
        }

        #endregion
    }
}

Step 11
Add toolkit reference in XAML,so we can Add Panorama Control in Phone Application Page,it is look like this
xmlns:PhoneControl="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"

Step 12
Now add a Panorama Control on Page,it is look like this
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <PhoneControl:Panorama x:Name="panImages" Grid.Row="0" Grid.Column="0" Title="Naruto Characters"/>
</Grid>



Finally it's look like this
<phone:PhoneApplicationPage 
    x:Class="SolPanoramaControl_WP7.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="PortraitOrLandscape" Orientation="Portrait"
    xmlns:PhoneControl="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"
    shell:SystemTray.IsVisible="True">

Step 13
Create a HeaderTemplate for Panorama Control in phone:PhoneApplicationPage.Resources. This is where we can define header for the given panel,it is look like this
<DataTemplate x:Key="PanHeaderDataTemplate">
   <TextBlock Text="{Binding ImageName}" FontFamily="Comic Sans MS" FontSize="48" FontStyle="Italic"></TextBlock>
  </DataTemplate>

Step 14
Create a ItemTemplate for panorama Control in phone:PhoneApplicationPage.Resources. This is where we can defined content for the panel,it is look like this
<DataTemplate x:Key="PanItemDataTemplate">
   <Image Source="{Binding ImagePath}" Stretch="Uniform"/>
  </DataTemplate>


Finally HeaderTemplate and ItemTemplate look like this
<phone:PhoneApplicationPage.Resources>
  <DataTemplate x:Key="PanHeaderDataTemplate">
   <TextBlock Text="{Binding ImageName}" FontFamily="Comic Sans MS" FontSize="48" FontStyle="Italic"></TextBlock>
  </DataTemplate>
  <DataTemplate x:Key="PanItemDataTemplate">
   <Image Source="{Binding ImagePath}" Stretch="Uniform"/>
  </DataTemplate>
 </phone:PhoneApplicationPage.Resources>


Step 15
Apply HeaderTemplate  and ItemTemplate on Panorama Control,it is look like this
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <PhoneControl:Panorama x:Name="panImages" Grid.Row="0" Grid.Column="0"  Title="Naruto Characters" ItemsSource="{Binding}" HeaderTemplate="{StaticResource PanHeaderDataTemplate}" ItemTemplate="{StaticResource PanItemDataTemplate}"/>
        </Grid>

Full XAML Code
<phone:PhoneApplicationPage 
    x:Class="SolPanoramaControl_WP7.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="PortraitOrLandscape" Orientation="Portrait"
    xmlns:PhoneControl="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"
    shell:SystemTray.IsVisible="True">
 <phone:PhoneApplicationPage.Resources>
  <DataTemplate x:Key="PanHeaderDataTemplate">
   <TextBlock Text="{Binding ImageName}" FontFamily="Comic Sans MS" FontSize="48" FontStyle="Italic"></TextBlock>
  </DataTemplate>
  <DataTemplate x:Key="PanItemDataTemplate">
   <Image Source="{Binding ImagePath}" Stretch="Uniform"/>
  </DataTemplate>
 </phone:PhoneApplicationPage.Resources>

    <!--LayoutRoot is the root grid where all page content is placed-->
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!--TitlePanel contains the name of the application and page title-->
        <!--<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
            <TextBlock x:Name="PageTitle" Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
        </StackPanel>-->

        <!--ContentPanel - place additional content here-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <PhoneControl:Panorama x:Name="panImages" Grid.Row="0" Grid.Column="0"  Title="Naruto Characters" ItemsSource="{Binding}" HeaderTemplate="{StaticResource PanHeaderDataTemplate}" ItemTemplate="{StaticResource PanItemDataTemplate}"/>
        </Grid>
    </Grid>
 
    <!--Sample code showing usage of ApplicationBar-->
    <!--<phone:PhoneApplicationPage.ApplicationBar>
        <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
            <shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="Button 1"/>
            <shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" Text="Button 2"/>
            <shell:ApplicationBar.MenuItems>
                <shell:ApplicationBarMenuItem Text="MenuItem 1"/>
                <shell:ApplicationBarMenuItem Text="MenuItem 2"/>
            </shell:ApplicationBar.MenuItems>
        </shell:ApplicationBar>
    </phone:PhoneApplicationPage.ApplicationBar>-->

</phone:PhoneApplicationPage>

Step 16
Now Bind the data in Panorama Control in Code Behind,it is look like this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;

namespace SolPanoramaControl_WP7
{
    public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainPage()
        {
            InitializeComponent();

            // Call Bind Images Function on Phone Application Loaded Event
            // this is Lambda Expression Event handler
            this.Loaded += (s, e) =>
            {
                try
                {
                    // Call Bind Image Function
                    BindImages();

                    // Set Default Panoram Item.
                    panImages.DefaultItem = panImages.Items[3];
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message); 
                }
            };

            
        }

        #region Methods

        /// <summary>
        /// Bind Image to Panaroma Control
        /// </summary>
        private void BindImages()
        {
            try
            {
                // Store Data in List Object
                List<ImageEntity> ListImageEntityObj = ImageView.GetDataFromXML();

                // Check List Object is Null or Not
                if (ListImageEntityObj != null)
                {
                    // Check List Object Count  
                    if (ListImageEntityObj.Count > 0)
                    {
                        // Bind Data in Panorama Control. 
                        panImages.DataContext = ListImageEntityObj;
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message); 
            }
        }

        #endregion
    }
}

Run the Project.

Output





Flick Images to Left and Right.

Download
Download Source Code

2 comments: