XAML Bindings in Windows Phone 8

I thank my friend Suchit Khanna for co-authoring this article with me

Data is an ubiquitous entity in today’s world of application development, present in some form or the other, and your application should have an intuitive UI that is able to bind to data as well as respond to any form of change in it. Well this what you will learn in this chapter how to bind to data in Windows Phone 7, so without any further delay lets jump onto code.

First let us write a model class that would contain information about a student:


public class Student
 {

public string Name { get; set; }

public int Age { get; set; }

public int StudentId { get; set; }

public string SchoolName { get; set; }

}

So you can see here that class student has simple 4 properties that tell about the name, age, student id and school name of a given student.

Next you need to create a UI for this student class so that these properties can be represented on that UI.

Go to MainPage.xaml and divide the content panel grid into two rows, next add a StackPanel control on the first row of the grid and add ListBox on the second row of the grid, so your xaml code should look like:


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

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

<!--ContentPanel - place additional content here-->
 <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
 <Grid.RowDefinitions>
 <RowDefinition Height="auto"/>
 <RowDefinition />
 </Grid.RowDefinitions>
 <StackPanel Grid.Row="0" DataContext="{Binding ElementName=studentListing, Path=SelectedItem}">

 </StackPanel>
 <ListBox x:Name="studentListing" Grid.Row="1" BorderBrush="WhiteSmoke" BorderThickness="3">

 </ListBox>
 </Grid>
 </Grid>

Do not focus on the DataContext snippet for the time being now, you will come to know about later in chapter.

You need to display the list of students available with you on the UI for which you will make use of ListBox control.

Now comes the interesting part, the student class which you wrote in previous step has many properties and from that in the ListBox control you only want to display the name of the student, so how do you go about implementing this? Well you need to specify the template for the ListBox where you will specify that bind the control in the template which you specified to the name property of the Student:


<ListBox x:Name="studentListing" Grid.Row="1" BorderBrush="WhiteSmoke" BorderThickness="3">
<ListBox.ItemTemplate>
 <DataTemplate>
<TextBlock Text="{Binding Path=Name}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

As mentioned you specified the ItemTemplate for the ListBox to tell how the ListBoxItems should look like, this case we are using TextBlock control to display each of the items from the list and binding the Text property of the control to Name property of the Student.

Path property tells where to find the data in the Binding object (in your case the Binding object is the Student).

So analogy drawn is that List<student> in the C# code is represented with a ListBox control on UI and we are specifying that bind Text property to Name property of student which represents individual items.

Let us add some code behind file, MainPage.xaml.cs where we create a list of students and show it on ListBox:


IEnumerable<Student> RetrieveStudentsList()
 {
 return new List<Student>()
 {
 new Student{Age = 5, Name = "Akash", SchoolName = "ABC Public School", StudentId = 1},
 new Student{Age = 6, Name = "Sachin", SchoolName = "ABC Public School", StudentId = 2},
 new Student{Age = 10, Name = "Javed", SchoolName = "XYZ Public School", StudentId = 3}
 };
 }

The above function returns a simple collection of 3 student details and now you will pass this to the ListBox:


studentListing.ItemsSource = RetrieveStudentsList();

This line sets the data for ListBox and running your application should result as:

image

So far so good, you displayed the list of students, but now we need to show the details of each of these students.

The stack panel control which we added in the previous step will be used now to show the details of the selected student in the ListBox. Your stack panel control should now look like:


<!--ContentPanel - place additional content here-->
 <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
 <Grid.RowDefinitions>
 <RowDefinition Height="auto"/>
 <RowDefinition />
 </Grid.RowDefinitions>
 <StackPanel Grid.Row="0" DataContext="{Binding ElementName=studentListing, Path=SelectedItem}">
 <StackPanel Orientation="Horizontal">
 <TextBlock Text="Name : " />
 <TextBlock Text="{Binding Path=Name}" />
 </StackPanel>
 <StackPanel Orientation="Horizontal">
 <TextBlock Text="Age : " />
 <TextBlock Text="{Binding Path=Age}" />
 </StackPanel>
 <StackPanel Orientation="Horizontal">
 <TextBlock Text="School : "/>
 <TextBlock Text="{Binding Path=SchoolName}" />
 </StackPanel>
 </StackPanel>
 <ListBox x:Name="studentListing" Grid.Row="1" BorderBrush="WhiteSmoke" BorderThickness="3">
 <ListBox.ItemTemplate>
 <DataTemplate>
 <TextBlock Text="{Binding Path=Name}" />
 </DataTemplate>
 </ListBox.ItemTemplate>
 </ListBox>
 </Grid>

You will see that the stack panel control does the job of showing the details of the selected student, if you notice the parent stack panel control does the job of binding to the ListBox control:


<StackPanel Grid.Row="0" DataContext="{Binding ElementName=studentListing, Path=SelectedItem}">

Here in binding we have told that the data source for this stack panel is the list box control, which we specified by telling the element name, studentListing is the x:name of our ListBox control.

But this is a collection which we bound to our stack panel, we need to look for a particular item’s details, which we will show in the stack panel, for that we specify the path to be selected Item proeprty of the list box control:

Path=SelectedItem

Now since the selected item is an instance of Student class we have specified binding to properties of the selected student on the textblocks in the stack panel. Now you can press F5 to run the application to see how it looks like:

image

On selecting items on the ListBox we can see details of the same.

This completes the listing of our student.

Binding Image

Let us add over what we have built so far, you can add images to the students details and bind this on UI.

For this go ahead and add a new property to the Student class that we built:


public ImageSource StudentImage { get; set; }

This property will be used to set the image for student; for the sample sake you can write a private function that would return a BitmapImage every time.


private ImageSource GetImage()
 {
 return new BitmapImage(new Uri("student.png", UriKind.Relative));
 }

Let us refactor the xaml code so far to accommodate the new feature we are building , to the image of selected student.

The xaml code on MainPage.xaml file should look like this now:


<!--ContentPanel - place additional content here-->
 <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
 <Grid.RowDefinitions>
 <RowDefinition Height="auto"/>
 <RowDefinition />
 </Grid.RowDefinitions>
 <Grid Grid.Row="0" DataContext="{Binding ElementName=studentListing, Path=SelectedItem}">
 <Grid.RowDefinitions>
 <RowDefinition />
 <RowDefinition />
 <RowDefinition />
 </Grid.RowDefinitions>
 <Grid.ColumnDefinitions>
 <ColumnDefinition/>
 <ColumnDefinition/>
 </Grid.ColumnDefinitions>
 <StackPanel Orientation="Horizontal" Grid.Row="0">
 <TextBlock Text="Name : " />
 <TextBlock Text="{Binding Path=Name}" />
 </StackPanel>
 <StackPanel Orientation="Horizontal" Grid.Row="1">
 <TextBlock Text="Age : " />
 <TextBlock Text="{Binding Path=Age}" />
 </StackPanel>
 <StackPanel Orientation="Horizontal" Grid.Row="2">
 <TextBlock Text="School : "/>
 <TextBlock Text="{Binding Path=SchoolName}" />
 </StackPanel>
 <Image Grid.RowSpan="3" Height="100" Grid.Column="1" Source="{Binding Path=StudentImage}" />
 </Grid>

The only difference you see this time from previous code being that we have laid out the UI in a nested Grid instead of the Stack Panel and added a new Image control which bound to the new Property you created in the Student class:


<Image Grid.RowSpan="3" Height="100" Grid.Column="1" Source="{Binding Path=StudentImage}" />

Run the application to see the output:

image

You can see that we have achieved binding an image to our application for student details.

XML binding

In this section we will take an example of how to parse an xml and display it on UI, the task is to built an application that would teach a new word every day to the user.

For this you are given an rss feed of yahoo: http://xml.education.yahoo.com/rss/wotd/

You need to parse the rss feed which is an xml file and show the data on UI.

Create new project named ‘WordOfDay’ ; next the go to your xaml page add the following code:


<!--TitlePanel contains the name of the application and page title-->
 <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
 <TextBlock x:Name="ApplicationTitle" Text="Word Of the Day" Style="{StaticResource PhoneTextNormalStyle}"/>
 <TextBlock x:Name="txtWord" Text="{Binding Title}" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle2Style}"/>
 </StackPanel>

<!--ContentPanel - place additional content here-->
 <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
 <Grid.RowDefinitions>
 <RowDefinition Height="Auto" />
 <RowDefinition />
 </Grid.RowDefinitions>
 <StackPanel Orientation="Horizontal">
 <TextBlock Text="Date Published : " />
 <TextBlock x:Name="txtPublishDate" />
 </StackPanel>
 <TextBlock Grid.Row="2" x:Name="txtSummary" />
 </Grid>
 </Grid>

There is nothing much complicated here, the real work happens in the code behind file:

First we need to add reference to the System.ServiceModel.Syndication which should be found at:

C:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Libraries\Client

Now after adding the reference, add following code :


private readonly WebClient _webClient;

// Constructor
 public MainPage()
 {
 InitializeComponent();
 _webClient = new WebClient();
 _webClient.DownloadStringCompleted += OnWebClientDownloadStringCompleted;
 _webClient.DownloadStringAsync(new Uri("http://xml.education.yahoo.com/rss/wotd/"));
 }

private void OnWebClientDownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
 {
 var rssFeed = e.Result;
 ParseFeed(rssFeed);
 }

private void ParseFeed(string _rssFeed)
 {
 if (string.IsNullOrEmpty(_rssFeed))
 MessageBox.Show("Could not retrieve the data...");
 else
 {
 XmlReader reader = XmlReader.Create(new StringReader(_rssFeed));
 SyndicationFeed feed = SyndicationFeed.Load(reader);

var iterator = feed.Items.GetEnumerator();
 SyndicationItem item = null;

if (iterator.MoveNext())
 item = iterator.Current;

if (item != null)
 {
 txtWord.Text = item.Title.Text;
 txtSummary.Text = item.Summary.Text;
 txtPublishDate.Text = item.PublishDate.Date.ToString();
 }
 }
 }

&nbsp;

The WebClient instance helps to download the rss feed from the given uri, the call: DownloadStringAsync(..) is a asynchornous call so we need to subscribe to DownloadStringCompleted event where we read read the result received from the feed.

On the callback function the result is parsed with the help of ParseFeed(…) function which reads the string using XmlReader and the .NET framework for Windows Phone comes with the SyndicationFeed class which helps to read and interpret any rss feed.

Next you iterate over the syndication feed to get individual syndication items and read the title/summary/publish date of each of these syndication items.

Press F5 and you should see the application running:

image

So here we go, we have successfully read a rss feed and displayed it on the UI, thus creating our word of the day application.

In this way you can work with XAML bindings in Windows Phone 8. I hope you find this post useful. Thanks for reading.

About these ads

ASP.Net Web API Service in Windows Phone: Part 4 of Many

Creating First HTTP Service using ASP.NET Web API: Part1 of Many

Consuming ASP.NET Web API Service using HttpClient: Part2 of Many

How to Self-Host ASP.Net Web API: Part 3 of Many

In this post we will consume ASP.Net Web API HTTP Service in Windows Phone Application. If you do not specify header information in HTTP request then by default ASP.Net Web API service returns JSON data. So essentially there are three steps involved in consuming HTTP Service from ASP.Net Web API in Windows Phone Application.

  1. Make a HTTP Request
  2. Read data from HTTP Response
  3. Parse returned JSON data and bind data to data bound control

In this post we are going to consume service created in this POST

I have created a Windows Phone Application by choosing target framework 7.1. We are going to display Bloggers Data returned from ASP.Net Web API service in a ListView. Essentially we are going to consume a JSON Data from a HTTP Service. For that add below references in the project.

image

We are going to de-serialize JSON data using DataContractJsonSerializer class. We need to create a class at client side representing Bloggers entity from the service. Let us create a class called BloggersClient. We will de-serialize JSON data returning from the HTTP service in this object of this class.


namespace WindowsPhoneClient
{
public class BloggersClient
{
public string Id { get; set; }
public string Name { get; set; }
public string AreaOfIntrest { get; set; }

}
}

Once the client class is in placed add following references,

image

We are going to download JSON data from ASP.Net Web API service using WebClient class. Make sure that you are passing URL of your HTTP Service.

image

In the completed event, we will parse returned JSON using DataContractJsonSerializer class. In following code,

  • Creating MemoryStream form returned result
  • Creating object to de-serialize the returned JSON data
  • Reading de-serialized data object in List of BloggersClient
  • Setting List of BloggerClient as ItemSource of ListBox. On the XAML we have put a ListBox with name lstBloggers.

image

Code behind to load data from ASP.Net Web API HTTP Service on page load of the application and s display in ListBox is as following


using System;
using System.Collections.Generic;
using System.Net;
using Microsoft.Phone.Controls;
using System.Runtime.Serialization.Json;
using System.IO;
using System.Text;

namespace WindowsPhoneClient
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
WebClient proxy = new WebClient();
proxy.DownloadStringCompleted +=
new DownloadStringCompletedEventHandler(proxy_DownloadStringCompleted);
proxy.DownloadStringAsync(new Uri("http://localhost:39192/api/Bloggers"));
}

void proxy_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
Stream s = new MemoryStream(Encoding.Unicode.GetBytes(e.Result));
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(List<BloggersClient>));
List<BloggersClient> result = (List<BloggersClient>) ser.ReadObject(s);
lstBloggers.ItemsSource = result;
}
}
}

On the XAML, we have put ListBox control do bind data from HTTP Service in the control.

If you are not aware of Data Binding in ListBox then watch a quick Video here


<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>

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

<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ListBox x:Name="lstBloggers">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Name}" Style="{StaticResource PhoneTextTitle2Style}" />
<TextBlock Text="{Binding AreaOfIntrest}" Style="{StaticResource PhoneTextAccentStyle}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Grid>

Now press F5 to run the application. You should able to get Bloggers detail from ASP.Net Web API service in Windows Phone Application.

image

I hope you find this post useful. Thanks for reading.

As a Developer why should I worry about Hybrid Application Development?

 

As a developer I see a great potential in the direction of mobile and device application development. It is evident that the platforms like IOS, Android and Windows Phone are making themselves better with each passing days such that they can excite more developers and eventually the consumers. A huge marketing perception is consumers and proper marketing make a product successful. May be, but when it comes to mobiles and devices, I don’t buy this argument. When I decide to buy a smart phone or tablet, first and foremost, I evaluate whether useful and popular applications are available in my local market place or not ? Applications are essential for the success of any platform. I believe a smart device with smarter platform is a void combination if there is dearth of applications to use on that. Applications are output of a developer work hence any platform need developers to succeed.


 

As a developer I want to write applications and get connected with user of all types of devices and platforms. At any given day I want to see my applications are running on all platforms and used by users of all types of devices.

 

Let us go bit mathematical here. For instance take an example, I want to run my application on three popular platforms and roughly I may need to learn three different technologies and need three different development environment.


 

 

Learning three different technology is exciting though I am more worried about writing three different sets of code for same business requirement. I am reluctant to put thrice of my work for the same application. After creating application I will have to manage and support three different codes as well. At any given day I do not find creating three different application for same business requirement a wise and smart idea. Having said that there may be some scenario when my application is relying heavily on a particular platform and device capability, in that case I may want to write code specific to platform. However when I see majority of the applications are data driven and just consuming data from remote services. In these types of applications I would consider to write one code running on various platforms.

Let us get more mathematical here, assume we are writing an application and want it to run on three popular platforms and application creation for each platform requires 100 lines of codes. So I have to write 300 lines of codes and later I need to manage and support three different sets of codes.


 

 

I may not want to do it if I am writing an application which is just consuming services and nowhere using device capability extensively.


 

I may consider to write one application and expect it to run on all platforms. This type of application is known as Hybrid Application


 


I want to write code once and expect it to run on all types of devices. And path for me would be creating a Hybrid Application. Now question is what technology, language need to be used to create a Hybrid Application? Hybrid application can be created using web technologies like HTML and JavaScript.

There are many awesome products out there which help to create Hybrid Application. One of the best could be jQuery Mobile and Kendo UI Mobile

So I may summarize Hybrid Application Development in following steps


 

  1. Create application using HTML
  2. Build application using PhoneGap
  3. Deploy it to various platform via respective marketplace

In block diagram, I can summarize hybrid application development as following


 

 

So if I am opting for hybrid application development, I may need to write only 100 lines of codes and my application is running on all the platforms. For the same requirement, if I am going to create native application, I will have to write 300 line of codes and I will have to manage 3 different set of codes.

I will end this post by saying if I am not going to write application that is going to use hardware and device capability heavily then Hybrid Application is my choice. At any given day I would like to write one set of code running on various platforms and being used by consumers from all across.

Any comment would be appreciated.