×
Namespaces

Variants
Actions

World's Greatest Speeches Application for Windows Phone - How To

From Nokia Developer Wiki
Jump to: navigation, search

This article shows how to create databound application like World's Greatest Speeches for Windows Phone. This article also shows how to create Panorama type application for Windows Phone 7.

WP Metro Icon UI.png
SignpostIcon XAML 40.png
WP Metro Icon WP8.png
SignpostIcon WP7 70px.png
Article Metadata
Code ExampleTested with
Devices(s): Lumia 800, Lumia 710, Lumia 900
Compatibility
Platform(s): Windows Phone 7
Windows Phone 8
Windows Phone 7.5
Article
Created: chintandave_er (08 Jan 2012)
Last edited: pavan.pareta (10 Aug 2013)

Contents

Introduction

In this Article, We will show how to create Windows Phone DataBound Application using List and Navigation Controls. Here we have taken live application World's Greatest Speeches to show you how to create WP DataBound Application. This Application is now available free for download on Windows Phone Marketplace on below link. Windows Phone Marketplace URL

About World's Greatest Speeches Application

World ’s Greatest Speeches app contains a selection of speeches from the world's great speakers. The speeches are accompanied by their picture and autograph (where available). This application is already developed for S40 Devices and Meego devices and available for free on Nokia Store on below links.

We are going to create or port this application on Windows Phone 7.

Video

The media player is loading...

Screenshots

Windows Phone DataBound Application

To Start creating our application we need to first select Windows Phone DataBound Application Project Templates from File >> New >> New Project. There you can select two languages VB or C#. I prefer C#. So I have created my application using C# as code-behind language.

This Project Templates is used to create windows phone application using List and navagation controls. It creates sample code containing ItemView and ModelView files that Stores the data and create kind of MVC (Model-View-Controller) architecture. This Created Sample project also contain List Control with sample data bind in it.

WSGA ss1.png

- After create this project, you can see a folder created in project with name "ViewModel". It contains two classes.

  1. ItemViewModel.cs
  2. MainViewModel.cs

ViewModel - ItemViewModel Class

ItemViewModel Class contains required properties. This class inherit INotifyPropertyChanged interface. This interface notifies clients that a property value has changed. In this ItemViewModel.cs Class, we have created Properties by using get and set methods. Properties is created to use store some value by creating object of that class in C#.

We can create properties like this:

        private string _lineOne;
public string LineOne
{
get
{
return _lineOne;
}
set
{
if (value != _lineOne)
{
_lineOne = value;
NotifyPropertyChanged("LineOne");
}
}
}

We can add more properties as we need by adding code above in ItemViewModel.cs as above. In World's Greatest Speeches application I need several properties. So i have added more properties as shows in below code.

ItemViewModel.cs Class

using System;
using System.ComponentModel;
using System.Diagnostics;
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 WorldsGreatestSpeeches
{
public class ItemViewModel : INotifyPropertyChanged
{
private string _lineOne;
/// <summary>
/// Sample ViewModel property; this property is used in the view to display its value using a Binding.
/// </summary>
/// <returns></returns>
public string LineOne
{
get
{
return _lineOne;
}
set
{
if (value != _lineOne)
{
_lineOne = value;
NotifyPropertyChanged("LineOne");
}
}
}
 
private string _lineTwo;
/// <summary>
/// Sample ViewModel property; this property is used in the view to display its value using a Binding.
/// </summary>
/// <returns></returns>
public string LineTwo
{
get
{
return _lineTwo;
}
set
{
if (value != _lineTwo)
{
_lineTwo = value;
NotifyPropertyChanged("LineTwo");
}
}
}
 
 
private string _lineThree;
/// <summary>
/// Sample ViewModel property; this property is used in the view to display its value using a Binding.
/// </summary>
/// <returns></returns>
public string LineThree
{
get
{
return _lineThree;
}
set
{
if (value != _lineThree)
{
_lineThree = value;
NotifyPropertyChanged("LineThree");
}
}
}
 
private string _line4;
/// <summary>
/// Sample ViewModel property; this property is used in the view to display its value using a Binding.
/// </summary>
/// <returns></returns>
public string Line4
{
get
{
return _line4;
}
set
{
if (value != _line4)
{
_line4 = value;
NotifyPropertyChanged("Line4");
}
}
}
 
 
private string _ShortDes;
/// <summary>
/// Sample ViewModel property; this property is used in the view to display its value using a Binding.
/// </summary>
/// <returns></returns>
public string ShortDes
{
get
{
return _ShortDes;
}
set
{
if (value != _ShortDes)
{
_ShortDes = value;
NotifyPropertyChanged("ShortDes");
}
}
}
 
private string _Sign;
/// <summary>
/// Sample ViewModel property; this property is used in the view to display its value using a Binding.
/// </summary>
/// <returns></returns>
public string Sign
{
get
{
return _Sign;
}
set
{
if (value != _Sign)
{
_Sign = value;
NotifyPropertyChanged("Sign");
}
}
}
 
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}

ViewModel - MainViewModel Class

MainViewModel Class Contain collection for ItemViewModel objects and other methods like to add ItemViewModel to Current Items. Here in this class, we first need to Create ObservableCollection of ItemViewModel Class as shown in below code.

    public MainViewModel()
{
this.Items = new ObservableCollection<ItemViewModel>();
}
 
/// <summary>
/// A collection for ItemViewModel objects.
/// </summary>
public ObservableCollection<ItemViewModel> Items { get; private set; }

Below is the code to load data in Context file. LoadData() method creates and adds a few ItemViewModel objects into the Items collection.

         /// <summary>
///
/// </summary>
public void LoadData()
{
// Sample data; replace with real data
 
this.Items.Add(new ItemViewModel() { LineOne = "Abraham Lincoln", LineTwo = "/WorldsGreatestSpeeches;component/Speechers/Abraham Lincoln.jpg", LineThree = "Born: February 12, 1809", Line4 = "Died: April 15, 1865", ShortDes = "16th President of the United States", Sign = "/WorldsGreatestSpeeches;component/Images/Abraham_Lincoln_Signature.png" });
this.Items.Add(new ItemViewModel() { LineOne = "Albert Einstein", LineTwo = "/WorldsGreatestSpeeches;component/Speechers/Albert-Einstein.jpg", LineThree = "Born: 14 March 1879", Line4 = "Died: 18 April 1955", ShortDes = "German-born Theoretical Physicist", Sign = "/WorldsGreatestSpeeches;component/Images/Albert_Einstein_signature.png" });
this.Items.Add(new ItemViewModel() { LineOne = "Aristotle", LineTwo = "/WorldsGreatestSpeeches;component/Speechers/Aristotle.jpg", LineThree = "Born: 384 BC", Line4 = "Died: 322 BC", ShortDes = "Greek philosopher", Sign = "" });
this.Items.Add(new ItemViewModel() { LineOne = "Audrey Hepburn", LineTwo = "/WorldsGreatestSpeeches;component/Speechers/Audrey.jpg", LineThree = "Born: 4 May 1929", Line4 = "Died: 20 January 1993", ShortDes = "British Actress", Sign = "/WorldsGreatestSpeeches;component/Images/Audrey.jpg" });
this.Items.Add(new ItemViewModel() { LineOne = "Ayn Rand", LineTwo = "/WorldsGreatestSpeeches;component/Speechers/Ayn_Rand.jpg", LineThree = "Born: 2 Feb 1905", Line4 = "Died: 6 March 1982", ShortDes = "Russian-American Philosopher", Sign = "/WorldsGreatestSpeeches;component/Images/Sign_Ayn_Rand.png" });
 
this.Items.Add(new ItemViewModel() { LineOne = "Barak Obama", LineTwo = "/WorldsGreatestSpeeches;component/Speechers/Barack Obama.jpg", LineThree = "Born: 4 August, 1961", Line4 = "", ShortDes = "44th President of the United States", Sign = "/WorldsGreatestSpeeches;component/Images/Barack_Obama_signature.png" });
this.Items.Add(new ItemViewModel() { LineOne = "Benjamin Franklin", LineTwo = "/WorldsGreatestSpeeches;component/Speechers/BenFranklinDuplessis.jpg", LineThree = "Born: January 17, 1706", Line4 = "Died: April 17, 1790", ShortDes = "6th President of the Supreme Executive Council of Pennsylvania", Sign = "/WorldsGreatestSpeeches;component/Images/Benjamin_Franklin_Signature.png" });
this.Items.Add(new ItemViewModel() { LineOne = "Bill Gates", LineTwo = "/WorldsGreatestSpeeches;component/Speechers/Bill_Gates.jpg", LineThree = "Born: October 28, 1955", Line4 = "", ShortDes = "CEO and chairman of Microsoft", Sign = "/WorldsGreatestSpeeches;component/Images/BillGates_Signature.png" });
this.Items.Add(new ItemViewModel() { LineOne = "Bob Marley", LineTwo = "/WorldsGreatestSpeeches;component/Speechers/bob_marley.jpg", LineThree = "Born: 6 Feb 1945", Line4 = "Died: 11 May 1981", ShortDes = "Jamaican Singer, Musician", Sign = "/WorldsGreatestSpeeches;component/Images/bob_marley_signature.png" });
this.Items.Add(new ItemViewModel() { LineOne = "Bruce Lee", LineTwo = "/WorldsGreatestSpeeches;component/Speechers/BruceLeecard.jpg", LineThree = "Born: 27 November 1940", Line4 = "Died: 20 July 1973", ShortDes = "Actor,Martial arts instructor", Sign = "" });
 
}

In our live application, we need to add more records to items so we have added more items in above code. Below is the full MainViewModel.cs class file. There we have added data to items according to our application need.

- In World's Greatest Speech, on Main page (Home page), we have list of the Speakers. So We have Created One ItemViewModel class and MainViewModel class. Here ItemViewModel class holds require properties those we have created in that ItemViewModel class. MainViewModel class uses the ItemViewModel class to access those created properties and to add records in current context by creating LoadData() Method (as seen in below code).

MainViewModel.cs Class

using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
 
 
namespace WorldsGreatestSpeeches
{
public class MainViewModel : INotifyPropertyChanged
{
public MainViewModel()
{
this.Items = new ObservableCollection<ItemViewModel>();
}
 
/// <summary>
/// A collection for ItemViewModel objects.
/// </summary>
public ObservableCollection<ItemViewModel> Items { get; private set; }
 
 
public bool IsDataLoaded
{
get;
private set;
}
 
/// <summary>
/// Creates and adds a few ItemViewModel objects into the Items collection.
/// </summary>
public void LoadData()
{
// Sample data; replace with real data
 
this.Items.Add(new ItemViewModel() { LineOne = "Abraham Lincoln", LineTwo = "/WorldsGreatestSpeeches;component/Speechers/Abraham Lincoln.jpg", LineThree = "Born: February 12, 1809", Line4 = "Died: April 15, 1865", ShortDes = "16th President of the United States", Sign = "/WorldsGreatestSpeeches;component/Images/Abraham_Lincoln_Signature.png" });
this.Items.Add(new ItemViewModel() { LineOne = "Albert Einstein", LineTwo = "/WorldsGreatestSpeeches;component/Speechers/Albert-Einstein.jpg", LineThree = "Born: 14 March 1879", Line4 = "Died: 18 April 1955", ShortDes = "German-born Theoretical Physicist", Sign = "/WorldsGreatestSpeeches;component/Images/Albert_Einstein_signature.png" });
this.Items.Add(new ItemViewModel() { LineOne = "Aristotle", LineTwo = "/WorldsGreatestSpeeches;component/Speechers/Aristotle.jpg", LineThree = "Born: 384 BC", Line4 = "Died: 322 BC", ShortDes = "Greek philosopher", Sign = "" });
this.Items.Add(new ItemViewModel() { LineOne = "Audrey Hepburn", LineTwo = "/WorldsGreatestSpeeches;component/Speechers/Audrey.jpg", LineThree = "Born: 4 May 1929", Line4 = "Died: 20 January 1993", ShortDes = "British Actress", Sign = "/WorldsGreatestSpeeches;component/Images/Audrey.jpg" });
this.Items.Add(new ItemViewModel() { LineOne = "Ayn Rand", LineTwo = "/WorldsGreatestSpeeches;component/Speechers/Ayn_Rand.jpg", LineThree = "Born: 2 Feb 1905", Line4 = "Died: 6 March 1982", ShortDes = "Russian-American Philosopher", Sign = "/WorldsGreatestSpeeches;component/Images/Sign_Ayn_Rand.png" });
 
this.Items.Add(new ItemViewModel() { LineOne = "Barak Obama", LineTwo = "/WorldsGreatestSpeeches;component/Speechers/Barack Obama.jpg", LineThree = "Born: 4 August, 1961", Line4 = "", ShortDes = "44th President of the United States", Sign = "/WorldsGreatestSpeeches;component/Images/Barack_Obama_signature.png" });
this.Items.Add(new ItemViewModel() { LineOne = "Benjamin Franklin", LineTwo = "/WorldsGreatestSpeeches;component/Speechers/BenFranklinDuplessis.jpg", LineThree = "Born: January 17, 1706", Line4 = "Died: April 17, 1790", ShortDes = "6th President of the Supreme Executive Council of Pennsylvania", Sign = "/WorldsGreatestSpeeches;component/Images/Benjamin_Franklin_Signature.png" });
this.Items.Add(new ItemViewModel() { LineOne = "Bill Gates", LineTwo = "/WorldsGreatestSpeeches;component/Speechers/Bill_Gates.jpg", LineThree = "Born: October 28, 1955", Line4 = "", ShortDes = "CEO and chairman of Microsoft", Sign = "/WorldsGreatestSpeeches;component/Images/BillGates_Signature.png" });
this.Items.Add(new ItemViewModel() { LineOne = "Bob Marley", LineTwo = "/WorldsGreatestSpeeches;component/Speechers/bob_marley.jpg", LineThree = "Born: 6 Feb 1945", Line4 = "Died: 11 May 1981", ShortDes = "Jamaican Singer, Musician", Sign = "/WorldsGreatestSpeeches;component/Images/bob_marley_signature.png" });
this.Items.Add(new ItemViewModel() { LineOne = "Bruce Lee", LineTwo = "/WorldsGreatestSpeeches;component/Speechers/BruceLeecard.jpg", LineThree = "Born: 27 November 1940", Line4 = "Died: 20 July 1973", ShortDes = "Actor,Martial arts instructor", Sign = "" });
 
this.IsDataLoaded = true;
}
 
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}

Now We have ItemViewModel.cs Class and MainViewModel.cs Class created.

MohandasGandhiModel.cs (ItemViewModel File)

In World's Greatest Speeches Application, I have created many ItemViewModel classes and MainViewModel classes for each speaker to create related properties and load speeches.

Here is one Item and Main ViewModel class for one Speaker Mohandas Ghandhi.

Here we have created ItemViewModel Class for Speaker Mohandas Gandhi' with Properties Name and Speech as shows in code below.

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.ComponentModel;
 
namespace WorldsGreatestSpeeches
{
public class MohandasGandhiModel : INotifyPropertyChanged
{
private string _name;
/// <summary>
/// Sample ViewModel property; this property is used in the view to display its value using a Binding.
/// </summary>
/// <returns></returns>
public string Name
{
get
{
return _name;
}
set
{
if (value != _name)
{
_name = value;
NotifyPropertyChanged("Name");
}
}
}
 
private string _speech;
/// <summary>
/// Sample ViewModel property; this property is used in the view to display its value using a Binding.
/// </summary>
/// <returns></returns>
public string Speech
{
get
{
return _speech;
}
set
{
if (value != _speech)
{
_speech = value;
NotifyPropertyChanged("Speech");
}
}
}
 
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
 
}
}

MohandasGandhiModelMain.cs (MainViewModel File)

In this Class, We have created collection of particular ItemViewModel Object Classes and added code to Load Speeches. I removed more speeches and make the record very few to make short file.

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.ComponentModel;
using System.Collections.ObjectModel;
 
namespace WorldsGreatestSpeeches
{
public class MohandasGandhiModelMain : INotifyPropertyChanged
{
public MohandasGandhiModelMain()
{
this.Items = new ObservableCollection<MohandasGandhiModel>();
}
 
/// <summary>
/// A collection for ItemViewModel objects.
/// </summary>
public ObservableCollection<MohandasGandhiModel> Items { get; private set; }
 
private string _sampleProperty = "Sample Runtime Property Value";
/// <summary>
/// Sample ViewModel property; this property is used in the view to display its value using a Binding
/// </summary>
/// <returns></returns>
public string SampleProperty
{
get
{
return _sampleProperty;
}
set
{
if (value != _sampleProperty)
{
_sampleProperty = value;
NotifyPropertyChanged("SampleProperty");
}
}
}
 
public bool IsDataLoaded
{
get;
private set;
}
 
/// <summary>
/// Creates and adds a few ItemViewModel objects into the Items collection.
/// </summary>
public void LoadData()
{
// Sample data; replace with real data
 
 
this.Items.Add(new MohandasGandhiModel() { Name="Mohandas Gandhi" ,Speech = "A 'No' uttered from the deepest conviction is better than a 'Yes' merely uttered to please, or worse, to avoid trouble." });
this.Items.Add(new MohandasGandhiModel() { Name="Mohandas Gandhi" ,Speech = "A coward is incapable of exhibiting love; it is the prerogative of the brave." });
this.Items.Add(new MohandasGandhiModel() { Name="Mohandas Gandhi" ,Speech = "A man is but the product of his thoughts what he thinks, he becomes." });
this.Items.Add(new MohandasGandhiModel() { Name="Mohandas Gandhi" ,Speech = "A man who was completely innocent, offered himself as a sacrifice for the good of others, including his enemies, and became the ransom of the world. It was a perfect act." });
this.Items.Add(new MohandasGandhiModel() { Name="Mohandas Gandhi" ,Speech = "A nation's culture resides in the hearts and in the soul of its people." });
this.Items.Add(new MohandasGandhiModel() { Name="Mohandas Gandhi" ,Speech = "A policy is a temporary creed liable to be changed, but while it holds good it has got to be pursued with apostolic zeal." });
this.Items.Add(new MohandasGandhiModel() { Name="Mohandas Gandhi" ,Speech = "A principle is the expression of perfection, and as imperfect beings like us cannot practise perfection, we devise every moment limits of its compromise in practice." });
this.Items.Add(new MohandasGandhiModel() { Name="Mohandas Gandhi" ,Speech = "A religion that takes no account of practical affairs and does not help to solve them is no religion." });
this.Items.Add(new MohandasGandhiModel() { Name="Mohandas Gandhi" ,Speech = "A small body of determined spirits fired by an unquenchable faith in their mission can alter the course of history." });
this.Items.Add(new MohandasGandhiModel() { Name="Mohandas Gandhi" ,Speech = "A vow is a purely religious act which cannot be taken in a fit of passion. It can be taken only with a mind purified and composed and with God as witness." });
this.Items.Add(new MohandasGandhiModel() { Name="Mohandas Gandhi" ,Speech = "A weak man is just by accident. A strong but non-violent man is unjust by accident." });
this.Items.Add(new MohandasGandhiModel() { Name="Mohandas Gandhi" ,Speech = "Action expresses priorities." });
this.Items.Add(new MohandasGandhiModel() { Name="Mohandas Gandhi" ,Speech = "Action is no less necessary than thought to the instinctive tendencies of the human frame." });
this.Items.Add(new MohandasGandhiModel() { Name="Mohandas Gandhi" ,Speech = "All compromise is based on give and take, but there can be no give and take on fundamentals. Any compromise on mere fundamentals is a surrender. For it is all give and no take." });
this.Items.Add(new MohandasGandhiModel() { Name="Mohandas Gandhi" ,Speech = "All the religions of the world, while they may differ in other respects, unitedly proclaim that nothing lives in this world but Truth." });
this.Items.Add(new MohandasGandhiModel() { Name="Mohandas Gandhi" ,Speech = "Always aim at complete harmony of thought and word and deed. Always aim at purifying your thoughts and everything will be well." });
this.Items.Add(new MohandasGandhiModel() { Name="Mohandas Gandhi" ,Speech = "Among the many misdeeds of the British rule in India, history will look upon the act depriving a whole nation of arms as the blackest." });
this.Items.Add(new MohandasGandhiModel() { Name="Mohandas Gandhi" ,Speech = "An error does not become truth by reason of multiplied propagation, nor does truth become error because nobody sees it." });
this.Items.Add(new MohandasGandhiModel() { Name="Mohandas Gandhi" ,Speech = "An eye for an eye only ends up making the whole world blind." });
 
this.IsDataLoaded = true;
}
 
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}


App.xaml

App.xaml file is main setting file for Windows Phone 7 application. This file derived from Application class. or in other words, this file inherits Application class which is a class of System.Windows namespace which initializes a new instance of the System.Windows.Application class.

- App.xaml.cs class contains collection of MainViewModel Object if it is more than one and some Main methods that need to initials everytime when Windows Phone application Start like

  • Application_Launching
Code to execute when the application is launching (eg, from Start). This code will not execute when the application is reactivated
  • Application_Activated
Code to execute when the application is activated (brought to foreground). This code will not execute when the application is first launched
  • Application_Deactivated
Code to execute when the application is deactivated (sent to background). This code will not execute when the application is closing.
  • Application_Closing
Code to execute when the application is closing (eg, user hit Back). This code will not execute when the application is deactivated.
  • RootFrame_NavigationFailed
Code to execute if a navigation fails.
  • Application_UnhandledException
Code to execute on Unhandled Exceptions.
  • InitializePhoneApplication
Initialize Phone Application
  • CompleteInitializePhoneApplication
Call when Initialize Phone application complete.

App.xaml.cs

Here I am showing you the App.xaml.cs file that i have used in my live application World's Greatest Speeches. So you can see i have used related Class there.

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.Navigation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
 
namespace WorldsGreatestSpeeches
{
public partial class App : Application
{
private static MainViewModel viewModel = null;
private static MohandasGandhiModelMain mohandasgandhimodelmain = null;
private static MotherTeresaModelMain motherteresamodelmain = null;
private static AbrahamLincolnModelMain abrahamlincolnmodelmain = null;
private static AlbertEinsteinModelMain alberteinsteinmodelmain = null;
 
/// <summary>
/// A static ViewModel used by the views to bind against.
/// </summary>
/// <returns>The MainViewModel object.</returns>
///
 
public static MainViewModel ViewModel
{
get
{
// Delay creation of the view model until necessary
if (viewModel == null)
viewModel = new MainViewModel();
 
return viewModel;
}
}
public static MohandasGandhiModelMain MohandasGandhiModelMain
{
get
{
// Delay creation of the view model until necessary
if (mohandasgandhimodelmain == null)
mohandasgandhimodelmain = new MohandasGandhiModelMain();
 
return mohandasgandhimodelmain;
}
}
public static MotherTeresaModelMain MainMotherTeresa
{
get
{
// Delay creation of the view model until necessary
if (motherteresamodelmain == null)
motherteresamodelmain = new MotherTeresaModelMain();
 
return motherteresamodelmain;
}
}
public static AbrahamLincolnModelMain AbrahamLincolnModelMain
{
get
{
// Delay creation of the view model until necessary
if (abrahamlincolnmodelmain == null)
abrahamlincolnmodelmain = new AbrahamLincolnModelMain();
 
return abrahamlincolnmodelmain;
}
}
public static AlbertEinsteinModelMain AlbertEinsteinModelMain
{
get
{
// Delay creation of the view model until necessary
if (alberteinsteinmodelmain == null)
alberteinsteinmodelmain = new AlbertEinsteinModelMain();
 
return alberteinsteinmodelmain;
}
}
/// <summary>
/// Provides easy access to the root frame of the Phone Application.
/// </summary>
/// <returns>The root frame of the Phone Application.</returns>
public PhoneApplicationFrame RootFrame { get; private set; }
 
/// <summary>
/// Constructor for the Application object.
/// </summary>
public App()
{
// Global handler for uncaught exceptions.
UnhandledException += Application_UnhandledException;
 
// Standard Silverlight initialization
InitializeComponent();
 
// Phone-specific initialization
InitializePhoneApplication();
 
// Show graphics profiling information while debugging.
if (System.Diagnostics.Debugger.IsAttached)
{
// Display the current frame rate counters.
Application.Current.Host.Settings.EnableFrameRateCounter = true;
 
// Show the areas of the app that are being redrawn in each frame.
//Application.Current.Host.Settings.EnableRedrawRegions = true;
 
// Enable non-production analysis visualization mode,
// which shows areas of a page that are handed off GPU with a colored overlay.
//Application.Current.Host.Settings.EnableCacheVisualization = true;
 
// Disable the application idle detection by setting the UserIdleDetectionMode property of the
// application's PhoneApplicationService object to Disabled.
// Caution:- Use this under debug mode only. Application that disables user idle detection will continue to run
// and consume battery power when the user is not using the phone.
PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;
}
 
}
 
// Code to execute when the application is launching (eg, from Start)
// This code will not execute when the application is reactivated
private void Application_Launching(object sender, LaunchingEventArgs e)
{
}
 
// Code to execute when the application is activated (brought to foreground)
// This code will not execute when the application is first launched
private void Application_Activated(object sender, ActivatedEventArgs e)
{
// Ensure that application state is restored appropriately
if (!App.ViewModel.IsDataLoaded)
{
App.ViewModel.LoadData();
}
}
 
// Code to execute when the application is deactivated (sent to background)
// This code will not execute when the application is closing
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
// Ensure that required application state is persisted here.
}
 
// Code to execute when the application is closing (eg, user hit Back)
// This code will not execute when the application is deactivated
private void Application_Closing(object sender, ClosingEventArgs e)
{
}
 
// Code to execute if a navigation fails
private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
{
if (System.Diagnostics.Debugger.IsAttached)
{
// A navigation has failed; break into the debugger
System.Diagnostics.Debugger.Break();
}
}
 
// Code to execute on Unhandled Exceptions
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
if (System.Diagnostics.Debugger.IsAttached)
{
// An unhandled exception has occurred; break into the debugger
System.Diagnostics.Debugger.Break();
}
}
 
#region Phone application initialization
 
// Avoid double-initialization
private bool phoneApplicationInitialized = false;
 
// Do not add any additional code to this method
private void InitializePhoneApplication()
{
if (phoneApplicationInitialized)
return;
 
// Create the frame but don't set it as RootVisual yet; this allows the splash
// screen to remain active until the application is ready to render.
RootFrame = new PhoneApplicationFrame();
RootFrame.Navigated += CompleteInitializePhoneApplication;
 
// Handle navigation failures
RootFrame.NavigationFailed += RootFrame_NavigationFailed;
 
// Ensure we don't initialize again
phoneApplicationInitialized = true;
}
 
// Do not add any additional code to this method
private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)
{
// Set the root visual to allow the application to render
if (RootVisual != RootFrame)
RootVisual = RootFrame;
 
// Remove this handler since it is no longer needed
RootFrame.Navigated -= CompleteInitializePhoneApplication;
}
 
#endregion
}
}

Till above we just created all classes and methods to load data. But now we are going to create WP pages that will represent our Windows Phone application beautifully.

MainPage.xaml

As Main Page, i.e Home Page, we are here selection Panorama page. In this page, we have used Panorama Control, Grid Control, ListBox Control, Stack Panel Control, Image Control. Here We used ListBox Control to bind the records using classes we created. On ListBox, We added DataTemplate and there we add other control that design the application or databound control. In our case we have added two Textbox Control and Image Control in Stack Panel Control. Here is small part related to Databind control code.

 <Grid x:Name="ContentPanel" Grid.Row="1" Margin="-10,0,-12,0">
<ListBox x:Name="MainListBox" Margin="0,0,-12,0" ItemsSource="{Binding Items}" SelectionChanged="MainListBox_SelectionChanged" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding LineTwo}" Height="150" Width="150" VerticalAlignment="Top" Margin="0,10,0,0" />
<StackPanel Margin="0,0,0,17" Width="432">
<TextBlock Text="{Binding LineOne}" HorizontalAlignment="Left" Width="305" TextWrapping="Wrap" Style="{StaticResource PhoneTextLargeStyle}" Foreground="White"/>
<TextBlock Text="{Binding ShortDes}" HorizontalAlignment="Left" Width="300" TextWrapping="Wrap" Margin="12,-6,0,0" Style="{StaticResource PhoneTextSubtleStyle}" Foreground="DarkGray"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>

- Now to bind the ListBox Control, we add a method on code behind MainPage.xaml.cs file, that calls every time page requested. You can see the MainPage() method that called EventHandler MainPage_Loaded Method Created below it. - In MainPage_Loaded Method, we check whether IsDataLoaded Properties which have Boolean Type is not set to True. If IsDataLoaded is not set to True then we call App.ViewModel.LoadData() Method. And as you can see above in App.xaml file section, this method add Authors/Speakers Items to ListBox Control. And on ListBox Control we used {Binding LineOne} or in general (Binding PropertyName} to bind that particular property to that particular Control.

 public MainPage()
{
InitializeComponent();
// Set the data context of the listbox control to the sample data
DataContext = App.ViewModel;
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}
// Load data for the ViewModel Items
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
if (!App.ViewModel.IsDataLoaded)
{
App.ViewModel.LoadData();
}
 
}
  • Now once user click on the list item we want to forward them to the speeches of that particular author. For that we have created SelectionChanged Event for ListBox control. So When user click on ListBox's any items, First SelectionChanged method call and there we add functionality to get the index of selected item in list and that index we will send it to other page created to show speeches as input.
  • To redirect to other page, we use NavigationService.Navigate method and will pass SelectedIndex number in URI as shown in below code.
// Handle selection changed on ListBox
private void MainListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// If selected index is -1 (no selection) do nothing
if (MainListBox.SelectedIndex == -1)
return;
 
// Navigate to the new page
NavigationService.Navigate(new Uri("/PanoramaPage1.xaml?selectedItem=" + MainListBox.SelectedIndex, UriKind.Relative));
 
// Reset selected index to -1 (no selection)
MainListBox.SelectedIndex = -1;
}
  • We can also give background to the Panoroma page to make it more beautiful and attractive. The size of the background image should be 1024 px x 768 px and we can add apply background image to any Panorama page by using below code.
<controls:Panorama>
<controls:Panorama.Background>
<ImageBrush ImageSource="/WorldsGreatestSpeeches;component/PanoramaBackground---Home.png" />
</controls:Panorama.Background>
<!--Panorama item one-->
<controls:PanoramaItem>
// controls code here.
</controls:PanoramaItem>
</controls:Panorama>

MainPage.xaml (In WGS App)

Here is the full code of MainPage.xaml file that used to create World's Greatest Speeches Application's Home Page.

<phone:PhoneApplicationPage 
x:Class="WorldsGreatestSpeeches.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:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DataContext="{d:DesignData SampleData/MainViewModelSampleData.xaml}"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="800"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="White"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="False">
 
<!--LayoutRoot contains the root grid where all other page content is placed-->
<Grid x:Name="LayoutRoot">
<controls:Panorama>
<controls:Panorama.Background>
<ImageBrush ImageSource="/WorldsGreatestSpeeches;component/PanoramaBackground---Home.png" />
</controls:Panorama.Background>
<!--Panorama item one-->
<controls:PanoramaItem>
<Grid x:Name="main" ShowGridLines="False">
<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="0,0,0,15">
<TextBlock x:Name="ApplicationTitle" Text="World's Greatest" Style="{StaticResource PhoneTextTitle2Style}" FontSize="36" Foreground="White"></TextBlock>
<TextBlock x:Name="PageTitle" Text="Speeches" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}" Foreground="White"></TextBlock>
<!--<Image Height="83" Name="image1" Stretch="Fill" Width="91" Source="/WorldsGreatestSpeeches;component/Speechers/MKGandhi.jpg" Visibility="Visible" AllowDrop="False" DataContext="{Binding}" />-->
</StackPanel>
 
<!--ContentPanel contains ListBox and ListBox ItemTemplate. Place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="-10,0,-12,0">
<ListBox x:Name="MainListBox" Margin="0,0,-12,0" ItemsSource="{Binding Items}" SelectionChanged="MainListBox_SelectionChanged" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding LineTwo}" Height="150" Width="150" VerticalAlignment="Top" Margin="0,10,0,0" />
<StackPanel Margin="0,0,0,17" Width="432">
<TextBlock Text="{Binding LineOne}" HorizontalAlignment="Left" Width="305" TextWrapping="Wrap" Style="{StaticResource PhoneTextLargeStyle}" Foreground="White"/>
<TextBlock Text="{Binding ShortDes}" HorizontalAlignment="Left" Width="300" TextWrapping="Wrap" Margin="12,-6,0,0" Style="{StaticResource PhoneTextSubtleStyle}" Foreground="DarkGray"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Grid>
</controls:PanoramaItem>
 
<!--Panorama item two-->
<controls:PanoramaItem Foreground="White">
<Grid x:Name="mainabout" ShowGridLines="False">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
 
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel1" Grid.Row="0" Margin="0,0,0,15">
<!--<TextBlock x:Name="ApplicationTitle1" Text="About" Style="{StaticResource PhoneTextTitle2Style}" FontSize="36"></TextBlock>-->
<TextBlock x:Name="PageTitle1" Foreground="White" Text="About" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"></TextBlock>
<!--<Image Height="83" Name="image1" Stretch="Fill" Width="91" Source="/WorldsGreatestSpeeches;component/Speechers/MKGandhi.jpg" Visibility="Visible" AllowDrop="False" DataContext="{Binding}" />-->
</StackPanel>
 
<Grid x:Name="ContentPanelabt" Grid.Row="1" Margin="5,0,5,0">
<StackPanel Margin="15,50,0,0" HorizontalAlignment="Stretch">
<TextBlock Name="help" Text="Help" Foreground="White" FontSize="29"/>
<TextBlock Margin="0,5,0,0" HorizontalAlignment="Left" Text="You can read speeches from various famous speakers by clicking on it. The speeches are accompanied by their picture and autograph (where available)." Foreground="White" TextWrapping="Wrap" Style="{StaticResource PhoneTextSubtleStyle}" />
 
<TextBlock Name="name1" Text="About us" Foreground="White" FontSize="29" Margin="0,50,0,0" />
<TextBlock Margin="0,5,0,0" HorizontalAlignment="Left" Text="World's Greatest Speeches Applications is developed by Chintan Dave. You can contact me on chintannapster@live.in. Any Suggestions, Issues, or ideas are welcome. " Foreground="White" TextWrapping="Wrap" Style="{StaticResource PhoneTextSubtleStyle}" />
 
<!--<TextBlock Name="nameCpy" Text="Copyright" Foreground="White" FontSize="29" Margin="0,50,0,0" />-->
<TextBlock Margin="0,200,0,0" HorizontalAlignment="Center" Text="Copyright © 2012 Chintan Dave." Foreground="White" TextWrapping="Wrap" Style="{StaticResource PhoneTextSubtleStyle}" />
</StackPanel>
</Grid>
</Grid>
</controls:PanoramaItem>
</controls:Panorama>
</Grid>
 
<!--Panorama-based applications should not show an ApplicationBar-->
 
</phone:PhoneApplicationPage>

Detail Page (Collection of Speech Page)

We use OnNavigatedTo Method to get Sent Input data from other page. Here in our case, we are sending Id of Selected Item in list from Home page. i.e. Main Page. So we added below sample code to get and use input id in PanoramaPage1.xaml.cs file.

// When page is navigated to set data context to selected item in list
protected override void OnNavigatedTo(NavigationEventArgs e)
{
string selectedIndex = "";
if (NavigationContext.QueryString.TryGetValue("selectedItem", out selectedIndex))
{
int index = int.Parse(selectedIndex);
DataContext = App.ViewModel.Items[index];
 
// sent data is now stored index interger
}
}

- In our application, According to received input id number, We bind the speeches of that Id's Author / Speaker like we bind the list of Authors above. - Here in this Panoroma page, we created to sub pages, 1) Info 2) Speeches. According to input Id, we display Author's Information like Name, Birth Date, Signature etc on Info section and on Speech section we bind Speeches to ListBox Control as we bind Authors in Main Page above. Here is the full code for Panoroma.xaml file design page.

PanoramaPage1.xaml

<phone:PhoneApplicationPage 
x:Class="WorldsGreatestSpeeches.PanoramaPage1"
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:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DataContext="{d:DesignData SampleData/MainViewModelSampleData.xaml}"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="800"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="White"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="False">
 
<!--LayoutRoot contains the root grid where all other page content is placed-->
<Grid x:Name="LayoutRoot">
<controls:Panorama>
 
<controls:Panorama.Background>
<ImageBrush ImageSource="/WorldsGreatestSpeeches;component/PanoramaBackground.png" />
</controls:Panorama.Background>
 
<!--Panorama item one-->
<controls:PanoramaItem Header="info" Foreground="White">
<Grid x:Name="LayoutRoot1" d:DataContext="{Binding Items[0]}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
 
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" d:DataContext="{Binding Items[0]}">
<!--<TextBlock x:Name="PageTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>-->
<TextBlock Foreground="White" x:Name="ListTitle" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}" FontSize="40" />
</StackPanel>
 
<!--ContentPanel contains details text. Place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0" >
 
<StackPanel Orientation="Horizontal">
<Image Source="{Binding LineTwo}" Height="250" Width="150" VerticalAlignment="Top" Margin="0,10,8,0" />
<StackPanel Margin="0,0,0,5" >
<!--<TextBlock Text="{Binding LineOne}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>-->
<TextBlock Foreground="White" x:Name="ContentText" Text="{Binding ShortDes}" HorizontalAlignment="Left" Width="230" TextWrapping="Wrap" Style="{StaticResource PhoneTextNormalStyle}" Margin="5,5,5,15" FontSize="23" />
<TextBlock Foreground="White" x:Name="ContentBorn" Text="{Binding LineThree}" Width="280" TextWrapping="Wrap" Style="{StaticResource PhoneTextNormalStyle}" HorizontalAlignment="Left" Margin="5,5,5,0" />
<TextBlock Foreground="White" x:Name="ContentDied" Text="{Binding Line4}" Width="280" TextWrapping="Wrap" Style="{StaticResource PhoneTextNormalStyle}" HorizontalAlignment="Left" Margin="5,5,5,15" />
<Image Source="{Binding Sign}" Height="100" Width="210" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,10,1,10" />
</StackPanel>
</StackPanel>
 
</Grid>
</Grid>
</controls:PanoramaItem>
 
<!--Panorama item two-->
<controls:PanoramaItem Header="Speeches" Foreground="White">
<Grid x:Name="panelSpeech" Grid.Row="1" Margin="12,0,12,0">
<ListBox x:Name="MainListBox" Margin="0,20,-12,0">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,5">
<TextBlock Foreground="White" x:Name="ContentSpeech" Text="{Binding Speech}" HorizontalAlignment="Left" Width="380" TextWrapping="Wrap" Style="{StaticResource PhoneTextNormalStyle}" Margin="5,5,5,15" FontSize="26" />
<Border BorderThickness="1" BorderBrush="White" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</controls:PanoramaItem>
</controls:Panorama>
 
</Grid>
 
 
</phone:PhoneApplicationPage>

PanoramaPage1.xaml.cs

- Here is the code behind file i.e. C# file for DetailPage for World's Greatest Speeches Application.I made it little small by removing some Authors from code below.

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;
using System.Windows.Navigation;
 
namespace WorldsGreatestSpeeches
{
public partial class PanoramaPage1 : PhoneApplicationPage
{
public PanoramaPage1()
{
InitializeComponent();
}
 
// When page is navigated to set data context to selected item in list
protected override void OnNavigatedTo(NavigationEventArgs e)
{
string selectedIndex = "";
if (NavigationContext.QueryString.TryGetValue("selectedItem", out selectedIndex))
{
int index = int.Parse(selectedIndex);
DataContext = App.ViewModel.Items[index];
 
if (index == 0)// Abraham Lincoln
{
if (!App.AbrahamLincolnModelMain.IsDataLoaded)
{
App.AbrahamLincolnModelMain.LoadData();
}
MainListBox.ItemsSource = App.AbrahamLincolnModelMain.Items;
ListTitle.Text = App.AbrahamLincolnModelMain.Items[0].Name.ToString();
}
else if (index == 1)// Albert Einstein
{
if (!App.AlbertEinsteinModelMain.IsDataLoaded)
{
App.AlbertEinsteinModelMain.LoadData();
}
MainListBox.ItemsSource = App.AlbertEinsteinModelMain.Items;
ListTitle.Text = App.AlbertEinsteinModelMain.Items[0].Name.ToString();
}
else if (index == 2)// Aristotle
{
if (!App.AristotleModelMain.IsDataLoaded)
{
App.AristotleModelMain.LoadData();
}
MainListBox.ItemsSource = App.AristotleModelMain.Items;
ListTitle.Text = App.AristotleModelMain.Items[0].Name.ToString();
}
 
}
}
}
}

Windows Phone MarketPlace URL

This application is available for free on Windows phone Marketplace to download. Here is the URL.

http://windowsphone.com/s?appid=b5b6ad8f-f455-44cd-9670-3cd63c093de7

This page was last modified on 10 August 2013, at 20:54.
167 page views in the last 30 days.