Design  a simple Windows Phone 7 app
Learn how to build a typical  List/Detail application for Windows Phone 7.
The article presents simple  customer list editor making use of various data editors 
- all built with the  help of MobileLight Toolkit from Resco.
Introduction
Windows Phone 7 (WP7) programming combines  several technologies:
- .NET (WP7 uses a subset of the full .NET class  library)
- C# (Other languages not available yet)
- Silverlight for WP7. (A simplification of the  desktop SVL, which is in turn a simplification of WPF.)
Mastering these technologies for a programmer  coming from (say) Windows Mobile programming is a real problem.
This article shows how to build typical  List/Detail application for Windows Phone 7 using MobileLight Toolkit from Resco.
Prerequisites
The target audience is a C# .NET programmer with  a reading knowledge of Silverlight. At the very minimum, the reader should  understand basic Silverlight controls and layout.
 You need to have installed Windows Phone  Developer Tools. (Requires Vista or W7, 2 GB RAM, DirectX 10+)
The installation includes
- Visual Studio 2010 Express for WP,
- The emulator (real phone device is not needed).
Further, you should install Resco MobileLight  Toolkit from http://www.resco.net/developer/mobilelighttoolkit.
 The Toolkit contains a set of useful controls  that simplify Windows Phone 7 programming. Attached SampleApplication provides  a template that can be used to build a broad range of typical business-class  applications without delving into advanced Silverlight topics.
 Although SampleApplication operates with more  difficult concepts 
- binding, styling and templating - all of this can be  understood from the comments.
Application  Preview
![]()
The above screenshots demonstrate the application functionality:
- Main screen displays customer list.
- Selected customer is displayed differently, as it  shows buttons offering call, e-mail and edit actions.
- At the bottom there is [+] button for creation  of a new customer.
- Customer form contains various editors of  customer properties and buttons for save/delete.
Special editors - combo box and datetime picker are shown in  the screenshots below.
![Resco_wp7_2.png]()
![]()
The rest of this  document describes the source code for this application. We recommend that you  install Resco MobileLight Toolkit and open the SampleApplication project.
Application description
The app serves as an  editor of a customer list.
It displays list of all  customers and lets you add/delete/edit individual customers.
 The code consists of:
- Data:
- Customer.cs  contains class Customer and related classes.
- Customer  is a simple data class with a set of public properties. It implements  INotifyPropertyChanged interface so that the UI controls can react to data  changes.
- Class  Customers provides single application-wide customer list. It is also  responsible for the data loading and storing.
- Customers.xml  is a sample customer list in xml format used for the app initialization.
- Images
- Three classes - App, MainPage, DetailsPage, i.e.  a pretty standard structure of a WP7 application (1 application object + 2  pages). 
- Note  also that each class is actually represented by 2 files - one for GUI (xaml  file) and one for the respective code (xaml.cs file).
App class
The code for App.xaml,  App.xaml.cs was generated by Visual Studio. The only thing added is the line
 Customers.Save();
 in  Application_Deactivated/Application_Closing handlers. (In other words we tell  the class Customers that it's time to close)
That's it. Well, you may ask how the app actually  starts. This is done behind the scenes in the file WMAppManifest.xml. This file  is organized by Microsoft Visual Studio and contains a few standard things  (background, app title) and the start page 
- MainPage in our case.
MainPage class
Apart from some  initialization/termination stuff, it's here where the programming of WP7 apps  starts.
MainPage.xaml defines the UI - the header, bottom bar  (with [New] button) and the most important part 
- the AdvancedList control.
MainPage.xaml.cs contains:
- Standard constructor generated by Microsoft Visual  Studio. (InitializeComponent() is a command to read xaml file at runtime.)
- OnNavigatedTo handler. WP7 apps consist of pages  and this handler is called by the framework when the page becomes active. 
 In our case we do a single thing - set up the DataContext, which is a single  instance of the Customers class. DataContext is then inherited by the page  controls. In this case it is the list that uses inherited DataContext to show  Customers.Items collection.
- The rest of the file contains event handlers.  The handlers that initiate email or phone call are straightforward (see the  code), while the navigation is described elsewhere.
How the navigation works
WP7 apps have pretty  standard structure as they always consist of these components:
- Application object takes cares about the app  life cycle - launching/termination, activation/deactivation.
- Pages which are basically forms. (Objects  derived from PhoneApplicationPage class.)
- Navigation between the pages.
The navigation concept  is simple:
- System navigates to the first page. (Defined in  WMAppManifest.xml)
- The application can navigate to another page  using NavigationService.Navigate() calls.
- The user presses the back key or start button.  (To return to previous page or to exit the application.)
Every page  (PhoneApplicationPage derived class) has two navigation related callbacks:
- OnNavigatedTo - called when the page is  activated.
- OnNavigatedFrom - called when the page is  deactivated.
The very last thing to  mention is the parameters used in these methods.  In this respect two things are important:
- We navigate to xaml files. As long as we talk  about the xaml files within our application, the file names used are simply  full paths with respect to the project folder.
Hence we could navigate to say  "/SubFolder/MyFile.xaml"
- We need to pass some parameters. Microsoft  decided to take over Uri technology used by web browsers.
Uri has usually the form <xaml_path>[?<query>], where
query:=  key1=value1&key2=value2&...                  //  or key1=value1;key2=value2;...
 In our case the navigation conversation looks like  this:
 MainPage issues the commands:
Navigate(  "/DetailsPage.xaml?selectedItem=12" )           //  Open the item #12
Navigate(  "/DetailsPage.xaml?newItem=true" )              //  Create new item\
DetailsPage reacts in  OnNavigatedTo():
 System passes the query is passed through the page  property NavigationContext. Its member QueryString contains key/value  dictionary of the parameters passed. (This saves you from parsing rather  complex query format.)
 In our case we simply analyze single key/value pair,  which is either [selectedItem,12] or [newItem,true].
How the AdvancedList works
Most of the list  programming is done in the Xaml file. Here is the code scheme:
// MainPage.xaml
<r:AdvancedList  x:Name="MainListBox" ItemsSource="{Binding Items}" ...    NormalTemplate="normal"  SelectedTemplate="selected">
<r:AdvancedList.DataTemplates>
<DataTemplate  x:Name="normal"> ... </DataTemplate>
<DataTemplate  x:Name="selected"> ... </DataTemplate>
</r:AdvancedList.DataTemplates>
</r:AdvancedList>
// MainPage.xaml.cs
public  partial class MainPage : PhoneApplicationPage {
protected override void  OnNavigatedTo(NavigationEventArgs e) {
//...
if (DataContext  == null)
DataContext  = Customers.Instance;
}
private void  btnCall_Click(object sender, RoutedEventArgs e) {
//...
var customer =  Customers.Instance.Items[MainListBox.SelectedIndex];
}
}
 Let's analyze the code:
- The  name property of the AdvancedList Xml element defines the instance
 AdvancedList MainListBox ;
 This object is then used in btnCall_Click handler to get selected customer.
- The  DataContext is set in the .cs file to Customers.Instance. 
 If you now realize that ItemsSource for AdvancedList is bound to the  DataContext property Items, it becomes clear that the list displays  Customers.Items.
 Moreover, it is an ObservableCollection, i.e. the binding will be  "live". What it means is that if the rest of the application  adds/deletes/changes customers, the list will react automatically.
 (Note that there are other possibilities to supply ListBox items, but the  described one represents the mainstream use.)
- The last question is how the list items are  displayed. This is defined by the DataTemplate and will be discussed later. For  the time being note that there are two templates - one for selected and another  one for the unselected item.
DataTemplate
The template is used to  display list items, which (in our case) means Customer objects.
 Here is the template for unselected item:
<DataTemplate  x:Name="normal">
<Grid>
// Define grid 2x2
<Grid.RowDefinitions>  <RowDefinition/>  <RowDefinition/>  </Grid.RowDefinitions>
<Grid.ColumnDefinitions>  <ColumnDefinition/>  <ColumnDefinition/>  </Grid.ColumnDefinitions>// First grid row shows the value  Customer.Name
<TextBlock  Grid.ColumnSpan="2" Text="{Binding Name}" 
Style="{StaticResource PhoneTextExtraLargeStyle}"/>// 2nd row displays Customer properties  EMailAddress1 and Telephone1
<TextBlock Grid.Row="1"  Grid.Column="0" Text="{Binding EMailAddress1}" 
Style="{StaticResource PhoneTextSubtleStyle}"/>
<TextBlock Grid.Row="1"  Grid.Column="1" Text="{Binding Telephone1}" 
Style="{StaticResource PhoneTextSubtleStyle}"/>
</Grid>
</DataTemplate>
 Note also that we do not  specify text properties (font, height etc.) directly, but rely instead on  predefined WP7 styles. The advantage is that the application will behave  consistently with the phone theme selected by the user.
 The template for selected item looks similarly 
- it  displays the same items as above and adds 3 buttons - [call], [email] and  [edit]. These buttons are processed in the .cs file by handlers such as  btnCall_Click.
 If you looked into the AdvancedList source code, you  would find that the treatment of dynamic templates is the primary added functionality  of this class. In other words, AdvancedList adds TemplateSelector 
- a feature  present in WPF, but omitted in Silverlight.
How to implement dynamic template
SampleApplication relies on AdvancedList feature that  allows using different templates for selected/unselected items. The former one  contains buttons, while the latter shows only Customer properties.
 The logical question is if we could do it by using a  single dynamic template that would show/hide buttons depending on the  selection. In other words we need a way to bind button visibility to the  IsSelected property.
 Unfortunately Silverlight (unlike WPF) can't bind to  ListBoxItem. (IsSelected is a property of ListBoxItem!)
 However, AdvancedList has a solution:
 Customer object has suitable property that by chance  uses the same name 
- IsSelected. If you set AdvancedList ItemIsSelectedPath  property to "IsSelected", then the list selection will be bound to  Customer.IsSelected property.
 
 Now we can make the dynamic template:
<r:AdvancedList ItemsSource="{Binding  Items}"  ...  ItemIsSelectedPath="IsSelected">
<r:AdvancedList.Resources> 
<r:BooleanToVisibilityConverter  x:Key="MyConverter"/> 
</r:AdvancedList.Resources> 
...
<DataTemplate>
<Button ... Visibility="{Binding  IsSelected, Converter={StaticResource MyConverter}}"/>
...
</DataTemplate>
</r:AdvancedList>
The binding relies on a  converter. This is because there is a type conversion between IsSelected and  Visibility properties.
Remark:
You can similarly bind  ListBoxItem.IsEnabled property to suitable Customer property.
How DetailView works
DetailsPage serves as a viewer/editor of a Customer  object.
We already know that this form is launched through  navigation. If you look into OnNavigatedTo() code, you will see that its purpose  is to set the DataContext to suitable Customer object (m_customer).
 There's not much else what the .cs file takes care of  
- it just performs the final action, i.e. saves or discards the changes.
 Most of the work is done in the Xaml file, but even  that one is conceptually simple:
- It's just definitions of individual controls  that are properly bound to the DataContext (i.e. Customer object) properties.
- On top of that we have also the title and the  ApplicationBar with two buttons - [Save] and [Delete].
The most important part of the code is the DetailView  element containing a list of various DetailViewItems.
Number of items is  unlimited; the DetailView will scroll if necessary.
 Typical item definition looks as follows:
<r:DetailItemTextBox  Label="Name" DataMember="Name" />
 As you probably guessed,  it is a (labeled) text box with that edits the property Customer.Name.
The text box takes the  whole screen width with the label displayed right above it. (This all can be overridden.)
There's just one more  complex item - the combo box:
<r:DetailItemComboBox  Label="Company Size" DataMember="Size"
ItemsSource="{Binding  Source={StaticResource CustomerSizesKey}}" 
ValueMemberPath="Id"   DisplayMemberPath="Label"/>
 The first two attributes  (Label, DataMember) are standard, i.e. combo box edits the property
 int  Customer.Size;
 Remaining attributes  define the content of the list shown when the combo box is opened:
- ItemsSource supplies the item list. In this case  it is the CustomerSizes object defined through static resources, i.e. a list of  CustomerSize objects. Look to the xaml code for the implementation details.
- DisplayMemberPath attribute tells the list to  display the item property CustomerSize.Label.
- ValueMemberPath attribute tells the list to  return the item property CustomerSize.Id.
- DetailItemComboBox binds the returned value to  the Customer.Size property.
As you'll become  familiar with WP7 programming, you will discover other ways how to set up the  DetailView.
See for example  DetailView.xaml comments that discuss other ways how to setup the combo box. 
Note also that you are  not limited to placing DetailViewItem's into the DetailView.
You can use any other  control as well - just take care about proper binding.
What happens to data
Customers.xml contains the default data that is used  when the app is launched for the first time.
 Once you edit the data,  it gets saved into WP7 isolated storage. Unfortunately, it means the data cannot be used by  any other application.
 If you - as a programmer - want to see raw saved  data, do the trick described in the source code of the Customers.Instance()  method.
 The format of the saved data relies on the old good  XmlSerializer. It covers most common scenarios, although one could expect  problems with more complex types as Silverlight does not support custom  serializing (ISerializable interface, Serializable attribute).
 As an alternative you could use  DataContractSerializer (DCS) that is natively used by Silverlight messaging.
 Although DCS is newer,  it is not clearly superior to XmlSerializer. (DCS is slightly faster, but  produces larger payload.) 
 
 Our recommendation is to start with XmlSerializer and  switch to DCS only if the former does not support all data formats.
 As of now, the only meaningful way of data sharing on  WP7 presents the web services. However, this topic goes well beyond the purpose  of the current document and won't be discussed here.
What's Next
Resco is a company with a long tradition of mobile  programming covering both end-user applications and developer tools. The Toolkit  
- as it is published now - is just the first version. In the near future  existing controls will be enhanced and new ones added. We also plan to publish  a series of tutorials that should help to jump-start Windows Phone 7  programming.
 Any feedback is welcome - either here or directly at Resco  forums.