Frame: Avigating Etween Ages
Frame: Avigating Etween Ages
As explained in the previous part, navigations on Windows Phone use the same navigation introduced in
Silverlight 3. There are two important elements in the application level which are Frame and Page, and one
important element in device level.
FRAME
Frame is integrated with the whole layout of a Windows Phone application, and only one frame can be used
throughout the application. Several characteristics related to frame are the properties that can be used (full
screen, orientation), the ability to expose page areas in it and provide a location for system tray and
application bar. System tray is an area in which system status, such as battery, signal, etc. are displayed.
Application bar, on the other hand, provides space for frequently used tasks.
PAGE
A page fills the whole content of a frame. Main characteristics of a page are title and the ability to show
application bar specifically on certain pages.
BACK BUTTON
One important element that has become a standard in every Windows Phone device is a “Back” button. This
button is used to move one page backwards. With this button present, developers are advised not to add
any back button in their applications, unless absolutely necessary. By default the back button will also close
any pop-up menu displayed and bring users back to the previous screen.
1. Use the project we have created in the previous exercise. Add a page; in Solution Explorer, select
Add > New Item.
2. Select Windows Phone Portrait Page and rename the file as you like, in this example
SecondPage.xaml, then select Add.
3. Change the page title into “Page 2” from the XAML code
14
4. On MainPage.xaml.cs, change the codes in the Button’s click event handler into the following:
Navigate is a static function from NavigationService which is used to navigate to desired pages using
target URI as the parameter.
5. Press F5 and see the result. Click on the Button to go forward to the next page.
15
6. We can use the Back button to return to the previous page. Additionally, if we want to go one page
backwards using custom button, we can do so by typing the following code into an event handler
In the next part, we will see how to do a parameter passing while navigating between pages.
3. On the second page, we will try to retrieve the sent string and show it on the page title. Type the
following code to do so:
PageTitle.Text = msg;
}
16
4. Press F5 and see the result. Type any string into TextBox then press Button. The title on the second
page will change according to the input text.
17
PIVOT AND PANORAMA
Navigation is an aspect that can be found very open for exploration, especially to build a better user
experience; and Microsoft seems to be concerned about the topic. In the latest release, developers have the
advantage with two complete look and feel experiences available, along with the built-in controls and
navigations. Let us get to know Pivot and Panorama.
P ANORAMA
Panorama is designed to fit into the device’s main screen limitations. The panorama application
offers a unique way to show controls, data, and services on a horizontal canvas which size extends
beyond the device’s display. The dynamic view uses layer animations that give fun parallax effects.
Panorama can be used for application with non task-oriented page browsing and hub with a lot of
information.
Panorama view supports touch interaction for its navigations. We don’t need to re-implement. Among the
supported interactions are:
18
Several guidelines to develop application using Panorama:
· Make sure to limit the number of sections used to a maximum of 4 sections. If the contents are too
tight or a lot of the application’s sections use hosted controls, then use less than 4 sections.
· Hide the parts where data is nonexistent.
· Sections can be extended beyond the display width by using Horizontal property.
· Use suitable background color or a wide picture background all through the Panorama control.
· The recommended size is 2000px (width) x 800px (height)
· Avoid drop-shadow effects.
· Make sure that title does not depend on the background.
· Avoid animations on Panorama titles.
Now let’s practice making an application using Panorama view on Windows Phone.
Note:
If you want to continue from the previous exercises, right click on the project and select Add
Windows Phone Panorama Page. Or if you want to add Panorama control on existing page, drag and
drop from the toolbox to your page.
19
2. We will only use the template that is generated automatically while creating the application. Press
F5 and see the results. Do a flick to slide to next section.
3. Now let’s review the codes to understand application structures of a Panorama view.
<!--Panorama control-->
<controls:Panorama Title="my application">
<controls:Panorama.Background>
<ImageBrush ImageSource="PanoramaBackground.png"/>
</controls:Panorama.Background>
20
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Width="432">
<TextBlock Text="{Binding LineOne}"
TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<TextBlock Text="{Binding LineTwo}"
TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource
PhoneTextSubtleStyle}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</controls:PanoramaItem>
.....
<!--Panorama item two-->
<!--Use 'Orientation="Horizontal"' to enable a panel that lays out
horizontally-->
</controls:Panorama>
4. Add another PanoramaItem. We do the following in XAML code, adding the panorama item count on
the application to 3 items.
</controls:PanoramaItem>
Don’t forget to add this reference:
xmlns:sys="clr-namespace:System;assembly=mscorlib"
21
5. Press F5 and see the result. Adding items on Panorama is an easy matter because the project
template has already given the big picture as how to use the control.
P IVOT
Pivot is designed to show a number of data and enable selections, and view items based on a certain
category. Pivot is used to manage application views that have several layouts or pages with built-in
navigations that support, such as:
22
Some best practices that can be put into account in developing application using Pivot controls are:
Note:
To continue from the previous exercise, right click on the project and select Add Windows Phone
Pivot Page. Or if you want to add Pivot control on existing page, drag and drop from the toolbox to
your page.
23
2. We will only use the template that is generated automatically while creating the application. Press
F5 and see the results.
3. Now let’s review the code in the main page. This is what it looks like:
<!--Pivot Control-->
<controls:Pivot Title="MY APPLICATION">
<!--Pivot item one-->
<controls:PivotItem Header="first">
24
<!--Double line list with text wrapping-->
<ListBox x:Name="FirstListBox" Margin="0,0,-12,0"
ItemsSource="{Binding Items}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Width="432">
<TextBlock Text="{Binding LineOne}"
TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<TextBlock Text="{Binding LineTwo}"
TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource
PhoneTextSubtleStyle}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</controls:PivotItem>
...
<!--Pivot item two-->
....
</controls:Pivot>
</Grid>
Examine that it is basically similar to Panorama View’s schematics. In Pivot control there is one main
container which includes several PivotItem. PivotItem can be used as containers equal to other
containers such as grid or canvas in which we can place other controls.
4. To add a new item, here is the example:
<controls:PivotItem Header="third">>
<Grid>
<ListBox FontSize="{StaticResource PhoneFontSizeLarge}">
<sys:String>This</sys:String>
<sys:String>item</sys:String>
<sys:String>has</sys:String>
<sys:String>a</sys:String>
<sys:String>short</sys:String>
<sys:String>list</sys:String>
<sys:String>of</sys:String>
<sys:String>strings</sys:String>
<sys:String>that</sys:String>
<sys:String>you</sys:String>
<sys:String>can</sys:String>
<sys:String>scroll</sys:String>
<sys:String>up</sys:String>
<sys:String>and</sys:String>
<sys:String>down</sys:String>
<sys:String>and</sys:String>
<sys:String>back</sys:String>
<sys:String>again.</sys:String>
</ListBox>
</Grid>
</controls:PivotItem>
25
Don’t forget to add the following reference in the class declaration:
xmlns:sys="clr-namespace:System;assembly=mscorlib"
In this part, we will learn how to handle switching between page orientations based on the device's position.
There are two types of page orientation: portrait or landscape. Let us follow the steps below:
1. Create a new project or use any previously created project. Insert a new page; on Solution
Explorer select Add, then New Item.
2. Select Windows Phone Portrait Page and rename the file to your liking, in this example,
Orientation.xaml, then select Add.
26
3. Insert a video file into your project and set its Build Action property as “Resource”.
4. Add a MediaElement control and place it inside content grid. Then set the source property to
refer to the previously added video file.
<phone:PhoneApplicationPage
x:Class="BukuWinPhone7.Orientation"
...... >
<!--LayoutRoot contains the root grid where all other page content is
placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
</phone:PhoneApplicationPage>
27
5. In order to make the page support both portrait and landscape orientation, insert the following
code into the page's PhoneApplicationPage definition.
<phone:PhoneApplicationPage
x:Class="BukuWinPhone7.Orientation"
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"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="PortraitOrLandscape" Orientation="Portrait"
mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
shell:SystemTray.IsVisible="True">
6. Now set Orientation.xaml as the application's initial page by changing the property of
WMAppManifest manifest file.
</Capabilities>
<Tasks>
<DefaultTask Name ="_default" NavigationPage="Orientation.xaml"/>
</Tasks>
<Tokens>
7. Then on the Orientation.xaml page source code, add an event handler to handle the page's
orientation switch. Type in the code below:
public Orientation()
{
InitializeComponent();
28
this.OrientationChanged += new
EventHandler<OrientationChangedEventArgs>(Orientation_OrientationChanged);
}
}
}
8. Press F5 and change the emulator's orientation by pressing the orientation button on the top
right corner of the emulator. When the orientation changes to landscape, the video will be
shown in full screen mode and the page title will disappear.
The handling of page orientation alteration can increase the Window Phone application's user
experience. It is of course your option to develop an application that can adapt to the way users hold
their devices.
29
APPLICATION BAR
Application bar is a control system that can be used to build a toolbar on a Windows Phone application.
Application bar can be considered as the main option to develop a fast and consistent navigation. There are
two types of application bar that we can use, icon button based and text menu based. Both types can also be
combined. Icon bars are usually used for main, frequently used activities. Application bar can be defined for
the whole application (global) or only on certain pages (local).
According to best practices written in MSDN, there are a couple things to be considered:
· If a task can be represented clearly using an icon, then use icon button. Otherwise, use text
menu.
· Use application bar to make sure system menus are consistent with the user experience in
every applications on the device.
· The recommended opacity are 0 (not shown, content page fills the display screen), 0.5, and
1 (shows on the screen).
If you want an application with many different pages (XAML files) that has only one application bar for all or
most pages, then global application bar is the perfect choice. To add a global application bar, what we have
to do is add the application bar's definition in App.xaml. Don't forget to add a unique key in resource
application bar so that it can be used in other XAML files.
1. You can continue from the previous projects or make a new one. In this example I will use a
previously made project.
2. Open the App.xaml file, add the following code:
<Application
x:Class="BukuWinPhone7.App"
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">
30
<!--Application Resources-->
<Application.Resources>
<shell:ApplicationBar x:Name="globalApplicationBar"
x:Key="globalApplicationBar" Opacity="0.7">
<shell:ApplicationBar.MenuItems>
<shell:ApplicationBarMenuItem Text="Home" />
<shell:ApplicationBarMenuItem Text="Help" />
<shell:ApplicationBarMenuItem Text="About" />
</shell:ApplicationBar.MenuItems>
</shell:ApplicationBar>
</Application.Resources>
In the above example, we will add three menus on the application bar. Next, the pages
which will use the application bar can refer to the previously defined key.
3. Open the pages to which the application bar will be added, and type the code below on each
page:
<phone:PhoneApplicationPage
x:Class="BukuWinPhone7.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"
.....
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
shell:SystemTray.IsVisible="True"
ApplicationBar="{StaticResource globalApplicationBar}">
31
For the pages in the application (in this example, MainPage.xaml and SecondPage.xaml) to which
the application bar's definition has been added, a menu list will be visible on the bottom of the main
screen. The next section will explain the use of application bar in only one certain page.
Creating a local application bar can be done in two ways: using codes or XAML. Make sure that the
XAML page doesn't already have a global application bar declaration. In this example we will use
MainPage.xaml file again.
1. Open your XAML page and add the code below under the root container:
<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar x:Name="globalApplicationBar"
x:Key="globalApplicationBar" Opacity="0.7">
<shell:ApplicationBar.MenuItems>
<shell:ApplicationBarMenuItem Text="Home" />
<shell:ApplicationBarMenuItem Text="Profile" />
<shell:ApplicationBarMenuItem Text="Help" />
<shell:ApplicationBarMenuItem Text="About" />
</shell:ApplicationBar.MenuItems>
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>
2. Press F5 for results. In this example, you can see the difference between the application bar in
MainPage.xaml and the one in SecondPage.xaml.
3. We used menu item in the previous example, now let's try using icon for our application bar. We
should prepare the required icons before starting. Icons can be downloaded from Microsoft
Download Center.
32
4. Add a couple of icons into the project. Right click on the project, select Add Existing Item. Set
Build Action property of the images to content.
<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar x:Name="globalApplicationBar"
IsMenuEnabled="True" Opacity="0.7">
<shell:ApplicationBarIconButton Text="Add"
IconUri="appbar.add.rest.png"/>
<shell:ApplicationBarIconButton Text="Message"
IconUri="appbar.feature.email.rest.png"/>
<shell:ApplicationBarIconButton Text="Delete"
IconUri="appbar.delete.rest.png"/>
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>
33
6. Press F5 and see the results. Now the application bar consisting of three buttons is ready to use.
In this section we will see how application bar can be created programmatically with codes instead of XAML
file declaration. Follow the steps below:
1. Make sure that the page doesn't already have either global or local application bar defined.
2. Add a reference to the following dll
using Microsoft.Phone.Shell;
public MainPage()
{
InitializeComponent();
ApplicationBar appBar = new ApplicationBar();
appBar.IsMenuEnabled = true;
appBar.Buttons.Add(new ApplicationBarIconButton(){ Text="Add", IconUri=new
Uri("appbar.add.rest.png",UriKind.Relative)});
appBar.Buttons.Add(new ApplicationBarIconButton() { Text = "Message",
IconUri = new Uri("appbar.feature.email.rest.png", UriKind.Relative) });
appBar.Buttons.Add(new ApplicationBarIconButton() { Text = "Delete",
IconUri = new Uri("appbar.delete.rest.png", UriKind.Relative) });
this.ApplicationBar = appBar;
34
4. Press F5 for results.
To implement functionality into application bar items, we need to assign a click event for each item
(regardless icon based or menu based). This can be done by using XAML or code. We can add a click event on
XAML by declaring a function inside the item’s property.
For the exercise we’ve done in creating icon bar, we only have to add the following declaration:
<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar x:Name="globalApplicationBar" IsMenuEnabled="True"
Opacity="0.7">
<shell:ApplicationBarIconButton Text="Add"
Click="ApplicationBarIconButton_Click" IconUri="appbar.add.rest.png"/>
<shell:ApplicationBarIconButton Text="Message"
IconUri="appbar.feature.email.rest.png"/>
<shell:ApplicationBarIconButton Text="Delete"
IconUri="appbar.delete.rest.png"/>
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>
35
Or if you want it done programmatically, here is the code:
...
InitializeComponent();
ApplicationBar appBar = new ApplicationBar();
appBar.IsMenuEnabled = true;
appBar.Buttons.Add(appIcon);
appBar.Buttons.Add(new ApplicationBarIconButton() { Text = "Message",
IconUri = new Uri("appbar.feature.email.rest.png", UriKind.Relative) });
appBar.Buttons.Add(new ApplicationBarIconButton() { Text = "Delete",
IconUri = new Uri("appbar.delete.rest.png", UriKind.Relative) });
this.ApplicationBar = appBar;
....
After the declaration, add the desired functionality inside the method (in this example it’s
ApplicationBarIconButton_Click). To give an illustration, the following code will show a message
box on button clicked.
Press F5 for results. When icon button on application bar is pressed, a message box will appear with
the icon text as its content.
36
37
WEB SERVICE CONSUMPTION
Web service has become a standard when it comes to using a predefined web function in our application. In
this section we will learn how to consume web service on Windows Phone. Web services consumable by
Windows Phone can be in the form of SOAP (built in WCF or other technologies), plain HTTP, or REST.
Explanations regarding the said terms will not be discussed here; if you are not familiar with the terms you
can look it up in your preferred search engine.
Windows Phone applications can access these web services either directly or through a proxy class that is
automatically generated from metadata attached to a service. A service can be in a form of user defined
service that you place in your server, or a third party server, for example Facebook, Twitter, and other
services. Silverlight can work with many different data format, such as XML, JSON, RSS, or ATOM, and data
access can be done under numerous scenarios, such as serialization, LINQ to XML, LINQ to JSON, or
syndication. It has unlimited combinations, and can be implemented based on your need.
C REATING W EB S ERVICES
1. Run a Visual Studio program that support Web Application project creation (in this case I use Visual
Studio 2010 Web Developer Express), then create a new Web ASP.NET Web Application project.
38
2. On the Solution Explorer window, add a web service file by right clicking on Project, then select Add >
Add New Item.
39
4. We will only use the automatically generated function, which is a web service method that returns a
“Hello World” string. Further explanations regarding web service will not be discussed, and we will focus
to the Windows Phone access aspect.
5. Right click on the web service file and select View in Browser to test the function.
40
6. Your sample web service is ready for consumption. Do not turn off your browser.
1. Open your Windows Phone project. On the Solution Explorer windows, right click on References,
then select Add Service Reference.
41
2. Copy and paste the access address for the web service that we created. This address can be
retrieved from the URL address on the browser. Click Go.
3. If the web service is found and accessible, a list of services and available operations will be
displayed. Give a namespace per your need then click OK.
42
4. If the addition is successful, on the Solution Explorer window we can see a configuration file and
a reference file for the web service we created.
C ONSUMING W EB S ERVICE
To consume a web service, we will create a new page so that the MainPage.xaml will not be overcrowded.
1. Right click on the project, Add New Item and select Windows Phone Portrait Page. Rename the file
as you wish, in this example WebService.xaml, then click Add.
43
2. Insert a Button and a TextBox. The scenario is that when the button is pressed, we will call for a web
service via an auto-generated proxy class.
3. Double-click on the button to add event handler. Type in the following code:
First we initialize proxy from the service. Define handler when request is done, then call the function
that will be used. On the above example, when the web service request is done, the content of the
TextBox will become “HelloWorld”.
44
4. Now set Orientation.xaml as the initial page for the application by changing the property on
WMAppManifest manifest file.
</Capabilities>
<Tasks>
<DefaultTask Name ="_default" NavigationPage="WebService.xaml"/>
</Tasks>
<Tokens>
Note:
Don’t forget to set this page as the first page your application goes to if you continue from the
previous project. Learn how to do so here.
45
USING STANDARD HTTP REQUEST
In this section we will see how to consume a service in form of plain HTTP or RESTful. Silverlight and
Windows Phone SDK have a System.Net standard package to send request through ftp and http. The
scenario used in this case is to consume a real live service, which is service from a website that provides
weather information.
This below is the URL for the service with <city_name> as input parameter.
http://www.google.com/ig/api?weather=jakarta
1. If you are still using the project from the previous section, let’s add a little modification on the
WebService.xaml file. If you are new to this, then create a new file by following these steps.
2. Insert the code below into the button’s event handler
46
wc.DownloadStringCompleted += new
DownloadStringCompletedEventHandler(wc_DownloadStringCompleted);
}
There are two things done here. First, create a request by entering a URL address in WebClient class.
Request will later be done asynchronously so that it will not disturb the application’s responsiveness.
The second part is what to do after the request is done. In the above example, the result retrieved
from the request is written into a TextBlock.
3. Press F5 and see the results. Press button to call the service.
Download speed will be very dependent to your PC connection. The same thing applies in the real device.
You can see that the service data can be retrieved successfully. Data can then be processed further before
being displayed to users.
47
WORKING WITH DATA
Windows Phone which uses Silverlight as a development platform surely inherits the beauty of interacting
with data using DataBinding. Binding data to UI Control means that any alteration we do in UI will cause a
change in the data bound to it and vice versa. DataBinding makes it easier for us to display data by trimming
down handling on code-behind, thus making the code much simpler.
One scenario commonly used is working with a ListBox to show a number of data. The part highlighted in
yellow in the box below shows XAML code that declares the binding of a ListBox to a collection named
“items”.
The part highlighted in green shows that the text value of TextBlock will refer to the property LineOne,
regardless of its value, from the “Items” collection. To learn about it further, we will take a look at a standard
template Windows Phone Tools has provided, Windows Phone Databound Application, which provides a
comprehensible general illustration of databinding usage to display data collection.
1. Create a new Windows Phone Databound Application project. Right click on the solution on
Solution Explorer window, select Add New Project and choose Windows Phone Databound
Application.
48
2. Several files will be automatically created, and we will review them one by one.
Item Description
SampleData/MainViewModelSample This file consists of sample data which will be the input
Data.xaml data during design process
ItemViewModel.cs This file declares the view model for each item on the list
MainViewModel.cs This file declares the main view for the application’s main
page
App.xaml The main file, consists of resources usable throughout the
application and events to handle application states
DetailsPage.xaml This file displays detailed data for every item on the list
MainPage.xaml This file displays list from data collections using ListBox
control
49
The main page already has a layout containing item design one, design two, and so on. The data is
retrieved from SampleData and displayed on design time with data context declaration on the page.
<phone:PhoneApplicationPage
x:Class="WindowsPhoneDataBoundApplication1.MainPage"
......
d:DataContext="{d:DesignData SampleData/MainViewModelSampleData.xaml}"
.....>
....
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
The class includes declarations for properties to be displayed, on the example above consists of 3
properties: a string, PropertyChanged property, and event handler. The last item is used to give
notification when your data is changed.
50
5. Now open MainViewModel.cs file and observe the contents
public MainViewModel()
{
this.Items = new ObservableCollection<ItemViewModel>();
}
/// <summary>
/// A collection for ItemViewModel objects.
/// </summary>
public ObservableCollection<ItemViewModel> Items { get; private set; }
We can see a declaration of a collection called Items, which consists of ItemVIewModel. This
collection will later be bound with ListBox UI Control. Next we have Load data mechanism, in this
part data is inserted into items. In reality, data source can be a service or a database.
// Constructor
public MainPage()
{
InitializeComponent();
// Set the data context of the ListBox control to the sample data
DataContext = App.ViewModel;
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}
51
if (MainListBox.SelectedIndex == -1)
return;
The part highlighted in yellow is how you can set MainPage’s DataContext with App.ViewModel that
refers to an instance of MainViewModel in App.xaml.cs file. With that declaration, MainViewModel
automatically becomes the data source on MainPage.xaml page. There is also a navigation
mechanism in Section Changed event handler from ListBox. It means that if one item in the ListBox is
clicked, it will navigate to DetailPage and display details of the clicked item. This navigation has been
discussed in Navigations on Windows Phone, along with passing parameters to target page. Now
open MainPage.xaml file and observe the code in ListBox.
Notice that data source of ListBox, the ItemsSource property is Items, an ItemViewModel collection,
and because data context is set to ViewModel then data will automatically be retrieved from
ViewModel. Also notice that inside the ListBox, two TextBlocks are placed each of their values, in
that order, bound to LineOne and LineTwo property of ItemViewModel in ViewModel collection.
Therefore the values are automatically assigned to suitable data.
52
7. Now press F5 and see how the application works.
We can see that emulator displays several data runtime one, two, and so on. When we click an item we will
be directed to the details of the data. This scenario is also known as Master/Detail scenario and can be
applied further to make menu list, display dynamic data, et cetera. With databinding, working with data is
made easier, and the code is cleaner. Furthermore Windows Phone Databound Application implements the
use of MVVM (Model-View-ViewMode) Design Pattern which actuality derives from DataBinding practice.
For applications related to data and MVVM view, maybe you should know that the concept will not be
discussed further here. Search engines should be your good friend :)
53
USING I SOLATED STORAGE
Isolated storage is a local storage that can be used for Windows Phone application data storage needs.
When an application is running, it works with a number of data, some of which is temporary and only
required for certain sessions, therefore storing them will not be necessary. This is where isolated storage
comes in handy.
The whole IO operation has to use IsolatedStorage and for security reasons applications cannot access
operating system storage and other application’s space. The figure below shows the storage structure in
Windows Phone applications.
There are two parts of storage, which are standard file folder and a particular folder to store application
settings.
We should put into account that storage space in mobile devices is very limited. However Windows Phone
does not give quota to applications in order to provide high flexibility for developers. Nevertheless, as a
developer we should consider the space storage usage responsibly. Every temporary file should immediately
be deleted, and users should be given the liberty to delete what they store. It would be better to give
transparency to users, letting them know how much space is used in the mobile device. We can also consider
the option of storing in cloud storage, whether it’s in our own application server or in a third party server.
Make sure applications on device are thin, making them comfortable to use. Would users use applications
that take up a lot of space in their mobile device? That’s how smart phones lose their smartness :)
1. Right click on Project, Add New Item and select Windows Phone Portrait Page. Rename the file
as you like, in this example it’s called IsolatedStorage.xaml, then choose Add.
54
2. Insert a button and a TextBox. Click event button will later be set so that it will store the string
inside the TextBox into isolated storage.
3. Next, insert a TextBlock and a button. By clicking the second button, we will call any string stored
in isolated storage.
55
4. Now double click on the first button to handle storing data into isolated storage. Add these
namespaces:
using System.IO;
using System.IO.IsolatedStorage;
5. Next, double click on the second button to handle loading data from isolatedstorage. Type in the
code below:
56
{
IsolatedStorageFile isf =
IsolatedStorageFile.GetUserStoreForApplication();
StreamReader sr = null;
try
{
sr = new StreamReader(new
IsolatedStorageFileStream("Data\\myfile.text",FileMode.Open,isf));
textBlock1.Text = sr.ReadLine();
sr.Close();
}
catch (Exception ex)
{
MessageBox.Show("error");
}
}
57
1. There is no need for a new page, let's just continue from IsolatedStorage.xaml for this purpose.
On the first button's event handler, change the code into the following:
The code above is pretty straightforward: we call for an instance of ApplicationSetting, insert a value
and a key then store it.
2. On the second button's event handler, change the code into the following:
try
{
settings.TryGetValue("duration", out value);
MessageBox.Show(value.ToString());
}
catch
{
MessageBox.Show("error");
}
The code above will call an instance of ApplicationSetting, try to fetch the value of duration, and
display it with a MessageBox.
58
Press the first button to store the application's setting. Nothing seems to happen, but do believe
that the setting has been saved. To prove this, press the second button. A MessageBox will appear,
showing the value stored in the application's setting.
59
SOFT IINPUT PANEL LAYOUT
On Windows Phone devices, with the absence of physical keyboard, you probably would have guessed that
we have to interact with the device using on-screen keyboard. SIP or Soft Input Panel is the name given for
Windows Phone's on-screen keyboard. One of the common scenarios in which SIP will appear is when we
interact with a TextBox.
A standard SIP layout is QWERTY panel with alphabets as the main display. To view the numbers, we press
the digit button on the lower left corner of the keyboard. But there may be certain scenarios in which you'd
want the SIP to only display numbers when users use it to input a value. This can also be a mechanism to
prevent invalid user inputs.
Such configuration can be easily done using LayoutOptions property for SIP. The supported layouts are:
Default, Text, Digits, Web, and Email Address. Each of the layouts has its own unique characteristic. Text for
example, has a similar layout to the default layout but with the addition of autocorrect and text suggestion
features.
1. If you continue from the previously made project, then add a page to learn about SIP Layout.
Otherwise, create a new project for this purpose. Having been doing exercises up to this page, it
should be fairly easy to do. The following example uses a previously existing project. Right click
60
on the project, Add New Item, select Windows Phone Portrait Page and rename the file, in this
example SIPLayout.xaml then select Add.
For this example, if the first button is pressed, it will show the Text layout, while pressing the second
button will show the Email layout.
3. Double click on the first button and type in the following code:
61
private void button1_Click(object sender, RoutedEventArgs e)
{
textBox1.InputScope = new InputScope()
{
Names = { new InputScopeName() { NameValue = InputScopeNameValue.Text }
}
};
}
4. Double click on the second button and type in the following code:
Click on the TextBox first to see the Default layout. Then click on the first button then click on the
TextBox again. Now your keyboard shows the Text layout. When you type in 'Fr' for example, several
word suggestions that you can pick from will appear. Now click on the second button and click the
TextBox again. Although there aren’t any significant differences, now on the bottom part of the
62
keyboard you can see two additional characters, which are @ and .com that we often use to input
email addresses.
6. Other than using code, keyboard layout can also be configured directly with XAML in TextBox
control. Observe the following code:
7. Press F5 for results. Click on the TextBox and now the SIP layout will display the number panels
as its main display.
Using SIP Layout we can freely configure keyboard display. This should be used to our advantage. A
better implementation of this feature will give the application a more professional feel to it, don't
you think?
63
GETTING TO KNOW WEB BROWSER
Say you want a scenario in which you need to display a webpage but you don't want to use your device's
built-in browser. Web Browser control is an option for this. WebBrowser control is a control that can be used
to display contents in the form of a web page, whether it is a locally stored file or dynamically generated
from a code.
1. If you continue from the previously made project, then add a page to learn about WebBrowser.
Otherwise, create a new project for this purpose. Having been doing exercises up to this page, it
should be fairly easy to do. The following example uses a previously existing project. Right click
on the project, Add New Item, select Windows Phone Portrait Page and rename the file, in this
example WebBrowser.xaml then select Add.
2. Change the page title into WebBrowser, add a TextBox, a button, and WebBrowser from the
toolbox like the figure below.
64
3. Double click on the button and type in the following code:
To retrieve the web content, call for Navigate method with a URI as input parameter. For starting
point, change the TextBox value into a web address.
65
4. Press F5 for results. This of course is very dependent to your connection speed.
5. Now let's try to dynamically display web content from a code. Type in the code below in GO!
Button's event handler.
webBrowser1.NavigateToString(html);
In this case, use NavigateToString method with an HTML string as input parameter. This string
will be rendered by WebBrowser and be displayed just like any webpage.
66
A file containing HTML declaration can of course be made and stored in local storage. We have
learned about using IsolatedStorage in this part.
67
GLOBALIZATION & LOCALIZATION
Speaking of applications, especially mobile applications, as a developer you surely are not aiming to make an
application just for yourself. You build the application so that it is usable for as many people as possible,
maybe even for users from different countries.
Globalization is used in order to accommodate different cultures, so that applications can be distributed
more broadly. Users often expect to easily adapt to applications they use daily. Examples on the matter are
the language used by labels and information in the application, time format, currency, or calendar format.
If you are experienced in using culture code in other .NET applications, then doing this shouldn't be any
different in Windows Phone. Setting is done by declaring the culture type targeted to certain users in the
format of 2 lower case letters, representing the language used, and 2 upper case letters, representing the
name of the country, in double quotes.
Localization, on the other hand, is used so that applications can adapt into certain culture. Besides
formatting, it also deals with text translations and other configurations. To do this, we need a separated
resource for the supported cultures, then the applications’ code only have to refer to that certain resource.
Note that separating resource from the code makes a cleaner and more maintainable application.
GLOBALIZATION
1. If you continue from the previously made project, then add a page to learn about Globalization.
Otherwise, create a new project for this purpose. Having been doing exercises up to this page, it
should be fairly easy to do. The following example uses a previously existing project. Right click
on the project, Add New Item, select Windows Phone Portrait Page and rename the file, in this
example Globalization.xaml then select Add.
68
2. Insert a TextBlock and two buttons like the figure below:
69
Int32 currency = 12500;
textBlock1.Text += Environment.NewLine + currency.ToString("C");
Don't forget to add the following namespaces so that Visual Studio recognizes CultureInfo and
Thread classes.
using System.Globalization;
using System.Threading;
Double click on the second button and add the following code:
Press the first button, then the second button, and see the difference. What we just did was
displaying the name of the currently used culture and displaying date and currency in a format
suitable to the culture. See the formatting differences between United States and Indonesia.
70
LOCALIZATION
A compiled Windows Phone application will include a number of standard resource and assembly files added
for each localized languages. The language used by Windows Phone UI depends on the culture setting of the
device. Take for example an application that has resources in English and Indonesian. If the device's culture
setting is en-US, then the application will display the English resource. During compilation, Visual Studio will
generate a standard culture used in main assembly and automatically generate a different assembly for
other language resource that the developer created.
1. If you continue from the previously made project, then add a page to learn about Localization.
Otherwise, create a new project for this purpose. Having been doing exercises up to this page, it
should be fairly easy to do. The following example uses a previously existing project. Right click
on the project, Add New Item, select Windows Phone Portrait Page and rename the file, in this
example Localization.xaml then select Add.
2. On Solution Explorer window, right click on project, then select Add > New Item. On the dialog
box, select Resource File, and rename it accordingly, for example AppResources.resx. This is the
file that will store a different language for the application.
71
3. List all the strings in the application and add them inside the resource file. Each string consists of
name, value, and optional comment. The name should be descriptive and unique. Values are in
the form of string and will be displayed to users. For example the file is AppResources.resx, and
this file will contain default values of the application.
Add a resource file for each language your application supports. The example below is resource
file for Indonesian.
72
Each resource should obey the following name convention:
4. Define standard culture which the application supports. Do this by right clicking on project name
and select Properties. On Application tab, click the Assembly Information button. On Neutral
Language, select default culture. This choice will identify the language used as standard
language.
73
5. Close the project and open (<projectname>.csproj) file using a text editor. Find
<SupportedCultures> tag and add cultures that are supported by the application. Separate each
language using a semicolon. It is not necessary to add default UI, this means that if the
application supports English, United States with Indonesian, Indonesia as an alternative, the tag
will look like this:
<SupportedCultures>id-ID; SupportedCultures>
6. Close the text editor and reopen the project using Visual Studio. Add a class into which we will
add a property that refers to the previously made resource.
74
Type in the following code:
7. Open App.xaml file and add a reference to the resources file that we've made
<Application
x:Class="BukuWinPhone7.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
.....
xmlns:local="clr-namespace:BukuWinPhone7"
>
<!--Application Resources-->
<Application.Resources>
<local:LocalizedStrings x:Key="LocalizedStrings"></local:LocalizedStrings>
...
75
</Application.Resources>
8. Open Localization.xaml file and insert several TextBox like the figure below:
9. Now we will call resource to fill the value of page title, name, and address. What we will do is
basically using databinding on Silverlight so that the code can be clean. Observe how to do it in
XAML file:
76
</Grid>
</Grid>
The parts highlighted in yellow are ways to call resources we previously created. Property path contains
the name of a string that is automatically bound to a suitable value, while source defines where the
resource data comes from. On the above example it is named LocalizedStrings which refers to
ApplicationResources in App.xaml file
11. Stop the debugging process and add the following code into App.xaml.cs.
77
As expected, the application can adapt with the selected culture and automatically load the resource
we've created. Using localization we can create an application that can adapt to its users. We also
have the advantage of having a cleaner, more maintainable code thus making it easier to develop
further.
78
LOCATION BASED SYSTEM
Location based system has become a certain trend in 2010. We can see services such as Gowalla,
Foursquare, and even Facebook offering location features in their applications. The ability to retrieve
locations gives developers an opportunity to give a unique user experience.
Any Windows Phone device manufacturer are obliged to include in the device a sensor that can fetch the
device's location at a given time. Furthermore the location service from Microsoft enables us to develop
location-aware applications on Windows Phone. This service can fetch location data from GPS, Wi-Fi, or
cellular towers. All three data source can be retrieved using managed code.
There are several things to take into account in using location sensors on the device. The first one is
movement threshold. This is set in meters and we need to consider its effect to battery consumption and
noise handling of movement changes due to GPS sensor. Sensor accuracy can also be managed depending
on the needs of the application. Using higher accuracy will surely give a better result, but it will also cause a
battery drain. Meanwhile battery consumption is highly critical in mobile application. Reckless handling
regarding this matter will cause a bad user experience. This is how smart phones become dumb.
To study the ways of using location features on Windows Phone, observe the steps below:
1. If you continue from the previously made project, then add a page to learn about Location.
Otherwise, create a new project for this purpose. Having been doing exercises up to this page, it
should be fairly easy to do. The following example uses a previously existing project. Right click
on the project, Add New Item, select Windows Phone Portrait Page and rename the file, in this
example Location.xaml then select Add
79
3. To use GPS, we need to add a reference to System.Device. To do this, right click on References
and select Add Reference.
4. Now we will add a reference and an instance of GeoCoordinateWatcher class which we will use
to retrieve position from the device's GPS.
using System.Device.Location;
namespace BukuWinPhone7
{
80
public partial class Location : PhoneApplicationPage
{
GeoCoordinateWatcher watcher;
public Localization()
{
InitializeComponent();
}
}
}
5. Use the Start function in the GeoCoordinateWatcher class instance to retrieve data from
location service. In this example, data will be fetched when the button is pressed. Add an event
handler on the button.
Remember that we need to implement an event handler for status change (whether or not the
location service is available) and position change. Start function will call for service asynchronously
so users can still use the application.
6. For status change handler, notice that this event handler will be called by a different thread from
the active page. For this reason, we need to utilize Dispatcher to invoke functions in the page's
thread.
81
void watcher_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e)
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
MyStatusChanged(e));
}
void MyStatusChanged(GeoPositionStatusChangedEventArgs e)
{
switch (e.Status)
{
case GeoPositionStatus.NoData :
MessageBox.Show("No Data Available");
break;
case GeoPositionStatus.Ready :
//donothing
break;
case GeoPositionStatus.Disabled:
MessageBox.Show("Location service is disabled");
break;
}
}
7. As the location service is active and receives data, it will invoke PositionChanged event,
therefore the handling of position change can be done according to an application logic that we
want. The same thing applies for status change event; we need to use Dispatcher to call the
handler.
void MyPosititonChanged(GeoPositionChangedEventArgs<GeoCoordinate> e)
{
textBlock1.Text = e.Position.Location.Latitude.ToString("0.000") + " " +
e.Position.Location.Longitude.ToString("0.000");
}
8. Press F5 and observe the result. Press the button to see how the application works. Of course,
since we are using an emulator, the data service will not be available, but the code will work on
a real device.
82
83
GETTING TO KNOW A CCELEROMETER
Accelerometer is a component to measure acceleration in such a way that it can detect changes in the
device's position and the magnitude of the change. Microsoft requires every Windows Phone manufacturer
to put this sensor in every device that supports Windows Phone. This way, a change in the device's physical
position can be used as an alternative for users to interact with a Windows Phone application.
This component gives as a new user experience in interacting with the device's movement. This can be used
not only for standard applications but especially for games also.
It's pretty simple to use; there are two basic functions, Start and Stop, and an event to handle, which is
ReadingChanged. Accelerometer detects a change in the x, y, and z dimensions. Using the value it detects,
we can write certain code that reacts depending on the change.
The device's axis does not change on orientation change. The Y axis is always from the top to the
bottom of the device, perpendicular to the three hardware buttons, the X axis is always from one
side of the device to another, parallel to the three hardware button, while the Z axis is a virtual axis
that goes through the device, assuming we are holding the device and looking at it. The value we can
get ranges from -1 to 1.
84
For reading schema, take a look at these illustrations of result values from the accelerometer:
Upright : 0 -1 0
85
Rotated counterclockwise : -1 0 0
Rotated clockwise : 1 0 0
Lying flat : 0 0 -1
86
Now we will learn how to retrieve data from the sensor.
1. If you continue from the previously made project, then add a page to learn about
Accelerometer. Otherwise, create a new project for this purpose. Having been doing exercises
up to this page, it should be fairly easy to do. The following example uses a previously existing
project. Right click on the project, Add New Item, select Windows Phone Portrait Page and
rename the file, in this example Accelerometer.xaml then select Add.
87
4. Add the following code:
using Microsoft.Devices.Sensors;
namespace BukuWinPhone7
{
public partial class Accelerometer : PhoneApplicationPage
{
Accelerometer accelerometer;
public Accelerometer()
{
InitializeComponent();
}
}
}
Don't forget to add assembly usage reference. On the next part the Accelerometer object id defined
for us to use later.
88
accelerometer = new Accelerometer();
accelerometer.ReadingChanged += new
EventHandler<AccelerometerReadingEventArgs>(accelerometer_ReadingChanged);
accelerometer.Start();
}
}
After instantiating accelerometer, add a handler to handle data change from the sensor.
6. Because data changes are sent constantly and this may happen during thread runtime, in
fetching data we need to use Dispatcher to invoke data change event handler.
void MyReadingChanged(AccelerometerReadingEventArgs e)
{
textBlock1.Text = String.Format("{0} {1} {2}", e.X.ToString(),
e.Y.ToString(), e.Z.ToString());
}
Fill this part with the logic for the application you're developing.
89
Accelerometer shows the values 0 0 -1, which means the emulator is in lying flat position. Since the
emulator doesn't have built in support for accelerometer, we cannot test this function using emulator.
There are several things to remember. Getting the exact value of 1.0 is however very unlikely to ever
happen because gravity does not work that way. It may astound you how standing on top of a mountain
or shaking your hand too much can add pressure on the device.
Accelerometer has its own fault tolerance, so maybe you would want to experiment on the total value of
the fault.
Imagine that you will receive a lot of new data changes, precisely 50 times per second. This means that
the amount of data we will receive is humongous. Retrieved data is very likely to be unstable due to the
nature of accelerometer sensor itself. Even when the device is lying on a table, any variation may occur.
This means that any application that uses accelerometer needs a reading mechanism, whether it's
calibration or smoothing for any data received from the component.
90
BING MAPS CONTROL FOR WINDOWS PHONE
Bing™ Maps Silverlight ® Control for Windows® Phone combines the powers of Silverlight and Bing Maps to
support applications. Developers can now use Bing Maps Silverlight Control, which includes location and
search services. For those of you who are quite familiar with using this control in standard Silverlight
applications, you surely won't see any difficulties to use the control in your Windows Phone applications.
To be able to use this service, you have to register in order to get a key to use control, SOAP Services, REST,
and Bing Spatial Data Services. Without a valid key we will not be able to fetch data via web.
91
USING BING MAPS CONTROL
1. If you continue from the previously made project, then add a page to learn about Bing Maps.
Otherwise, create a new project for this purpose. Having been doing exercises up to this page, it
should be fairly easy to do. The following example uses a previously existing project. Right click on
the project, Add New Item, select Windows Phone Portrait Page and rename the file, in this
example BingMaps.xaml then select Add.
On the center of the control you will see a warning: “Invalid Credentials. Sign up for a developer
account”. This indicates that you haven't inserted your key, which will allow you to use Bing
maps services.
93
6. Now we add a simple functionality that will automatically add a marker, or more generally
known as pushpin, whenever we click on an area on the map. Add an event handler to handle
click event on the map.
7. Press F5 and see the result. Click anywhere to add a marker on the map.
94
Pretty simple, isn't it? The addition of map control on Windows Phone gives developers more
freedom to enrich user experiences, especially on using maps and other Bing Maps services. The
topic about Bing Maps Control Silverlight itself has a very wide scope which will not be discussed
further here. If you are interested, you can see references on MSDN site or interactive SDK for
Silverlight.
95
PART III
PRACTICE
#1 - UNIT CONVERTER
This Unit Converter application we are making is an application to convert values from one measurement
unit to another, for example from meter to feet, or from mile to kilometer. Conceptually, we will use several
aspect we discussed on the LEARN part, which are using SIP Layout (Digit), IsolatedStorage to store settings,
Globalization and Localization, and Pivot as main layout.
3. Configure the MainPage.xaml file: name the application, name the PivotItem header, and delete
the mark-up from PivotItem content. Now your code should look like this:
</controls:PivotItem>
97
</controls:PivotItem>
</controls:Pivot>
</Grid>
4. Insert two TextBoxes and two PickerBoxes. Textbox will contain the measurement value input
while list picker will provide the measurement units. Add these items into a PivotItem named
convert.
<controls:PivotItem Header="convert">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<TextBlock Margin="10" Style="{StaticResource
PhoneTextTitle2Style}" Text="From"></TextBlock>
<TextBox Height="72" HorizontalAlignment="Left"
Margin="0,0,0,0" Name="unitone" Text="0" Width="213" Canvas.Left="0" Canvas.Top="0">
</TextBox>
</StackPanel>
<my:ListPicker Margin="103,10,10,10" FontSize="30" Height="50"
HorizontalAlignment="Left" Name="measurementunitone" Width="100" Padding="5,0,0,0"/>
</StackPanel>
</controls:PivotItem>
98
Note:
We intentionally don't use ComboBox for unit selection. Although ComboBox is not available in
the toolbox, we can actually insert it using XAML code. However, based on Windows Phone UI
Guidelines, this control is not a part of Windows Phone UX platform for its natural characteristic
that requires mouse/stylus precision. Hence the use of list picker. This control is implemented by
Alex Yakhnin here according to the list picker style available in the emulator's setting.
99
5. Open MainPage.xaml.cs file end add the following code to insert items to list picker:
// Constructor
public MainPage()
{
InitializeComponent();
// Set the data context of the ListBox control to the sample data
DataContext = App.ViewModel;
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}
100
6. Press F5 and check whether or not the application layout has met our expectations.
CONVERTING
1. To do a conversion we need a converter table. This table stores scales for each units. There are
many ways to implement this, but to keep it simple, in this example unit converters will be listed
in a dictionary.
//from cm
ConverterList.Add("cm-inch", 0.39);
ConverterList.Add("cm-feet", 0.03);
ConverterList.Add("cm-mile", 0.0000062);
//to inch
101
ConverterList.Add("feet-inch", 11.8872);
ConverterList.Add("mile-inch", 62764.26);
ConverterList.Add("inch-inch", 1.0);
//from inch
ConverterList.Add("inch-feet", 0.0762);
ConverterList.Add("inch-mile", 0.00001578);
//to feet
ConverterList.Add("mile-feet", 4828.02);
ConverterList.Add("feet-feet", 1.0);
//from feet
ConverterList.Add("feet-mile", 0.0002);
//from mile
ConverterList.Add("mile-mile", 1.0);
3. Double click on the first TextBox to add an event handler. This event handler processes the input
on the TextBox and displays the result in the second TextBox.
4. Add an input scope and limit the valid input to numbers only. Do this for both TextBoxes.
102
<InputScope>
<InputScopeName
NameValue="Digits"></InputScopeName>
</InputScope>
</TextBox.InputScope>
</TextBox>
5. To give a better user experience, add an update function when measurements are changed
during runtime. Double click on the list picker and add the following code:
103
ADDING CULTURE LIST
User preference is provided ultimately to adjust to language or culture selection that users want for the
application. This will affect the application's presentation and surely the more adjustable it is to users'
expectations, the better.
1. Let's prepare culture selections for users to select from. Insert a list picker on the second
PivotItem.
104
2. We are going to add culture list for the application. In this example we will only handle two
cultures (you can later add more, according to your application's needs), which are US and
Indonesia.
105