Over a million developers have joined DZone.

Quick look inside a List Application for Windows Phone 7

· Mobile Zone

A list application is in no way different from the standard Silverlight application for Windows Phone 7, the only difference being that a list application by default has a menu-like list present and it implements the MVVM design pattern from the very beginning.

Getting Started

First of all, launch Visual Studio 2010 and select New Project. From the C# category, select Silverlight for Windows Phone and there – Windows Phone List Application.

Once you click OK, a basic template will be built and you will see the development environment set up and ready.

The default project contains a lot of sample data that is not needed in this case. I am going to remove  unnecessary data in order to have a simple list layout and nothing more.

First of all, remove the SampleData folder from the solution.

Now, in the main page (MainPage.xaml) as well as in the details page (DetailsPage.xaml), remove the reference to the DataContext that points to sample data.

In the ViewModels folder, open MainViewModel.cs and remove all items in the Items ObservableCollection but one of them (left for experimental purposes).

Build and run the application. The Windows Phone 7 emulator should start and this is what you should see (main menu and opened item):

Looks pretty plain and simple, but it works. Let’s look into the details of this application now.

Digging deeper – how it works?

If you look at the default template for the main page, you can see that the main grid is structured in three separate parts.

A.    The row definitions:

This part basically defines that the grid will have two rows, one of which is set to have a height that will be automatically calculated based on the content structure while the second row will take up the rest of the space.

B.    The application & page title:

As you can see, this specific StackPanel occupies the first row and it contains two unbound TextBlock elements that describe the current page and application by displaying their titles. You can freely modify the values for the Text properties here.

C.    The list:

This is the fundamental part of the main page. The list is bound to the Items ObservableCollection, that you’ve modified in the MainViewModel.cs file. Each item listed there will also be a member of the list on the main page.

Each ListBox item is in fact represented by a data template, defined by a StackPanel instance, with an image and two TextBlock elements (used for the name and description), each of them being bound to a property of the ItemViewModel instance in the Items ObservableCollection.

And this is pretty much it about the main page structure. Let’s look at what’s available in the details page.

Its structure is pretty much the same as the one for the main page, the only difference being the binding. The DataContext for the main grid is set to Items[0], that being the currently selected item for the page in the ItemViewModel collection in the MainViewModel instance. The page title TextBlock element is bound to LineOne, which is a property inside the ItemViewModel instance, that is returned by the DataContext.

The last grid is used to display descriptive information and the TextBlock element is also bound to a property inside the ItemViewModel instance returned by the element bound as the DataContext for the grid.

A view from the inside

I mentioned binding quite a few times here, so let’s take a look at what an instance of ItemViewModel looks like. To do this, open the ItemViewModel.cs file inside the ViewModels folder. Here is the class structure:

public class ItemViewModel : INotifyPropertyChanged
{
private string lineOne;
public string LineOne
{
get
{
return lineOne;
}
set
{
if (value != lineOne)
{
lineOne = value;
NotifyPropertyChanged("LineOne");
}
}
}

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

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

public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}

Basically, there are three string properties and an event that is triggered on property change. Every item that is displayed on the home page is defined by an instance of ItemViewModel.

The main view model (can be viewed in MainViewModel.cs) takes advantage of the existing ItemViewModel to include separate instances of it in an ObservableCollection, but at the same time its structure is the same:

    public class MainViewModel : INotifyPropertyChanged
{
public MainViewModel()
{
// Insert code required on object creation below this point
Items = new ObservableCollection<ItemViewModel>() {
new ItemViewModel() { LineOne = "runtime one", LineTwo = "Maecenas praesent accumsan bibendum", LineThree = "Facilisi faucibus habitant inceptos interdum lobortis nascetur pharetra placerat pulvinar sagittis senectus sociosqu"}
};
}

public ObservableCollection<ItemViewModel> Items { get; private set; }

public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}

When the application is launched, a new MainViewModel instance is initialized as soon as it’s called. After that, the same instance is used, unless you modify the property.

// Static view model
private static MainViewModel viewModel = null;
public static MainViewModel ViewModel
{
get
{
// Delay creation of the view model until necessary
if (viewModel == null)
viewModel = new MainViewModel();

return viewModel;
}
}

In fact, we can see that it is first called inside the main page, when it is loaded:

// When page is navigated to, set data context
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);

// Set the data context of the listbox control to the sample data
if (DataContext == null)
DataContext = App.ViewModel;
}

Therefore, an instance of MainViewModel is automatically created on application launch.

So let’s take a look at how these components interact.

The application has a static instance of MainViewModel that is null by default. When the main page loads, it sets its DataContext to App.ViewModel. The way the property is structured, when it is first requested, it is automatically instantiated. Therefore, we have a static instance of MainViewModel that at the same time includes a collection of ItemViewModel objects that are defined inside the MainViewModel class. When the details page is loaded, it requests the needed instance of ItemViewModel and displays the properties assigned to it that are bound to specific controls.

Every time the user goes back to the main page via theBack button, a new instance of that page is used. Same applies to the details page.

A thing to avoid

One of the things to avoid when working with an application structured the way a list application is would be passing UI objects to the view directly. Not only does this breaks the MVVM separation rules, but also might cause binding problems. As James Ashley pointed out in this thread, it would be much easier to pass a DataTemplate to an existing property rather than pass a UIElement instance.

Where can I use a list application?

Anywhere where you need multiple options and/or information displayed in various ways. This can include various social network clients, applications that store specific data and later on need to display it (with multiple instances of various data, of course), Silverlight games and whatnot.

Topics:

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}