Today we are going to be starting a fun new series that introduces you to the Model-View-ViewModel (MVVM) pattern with Windows Phone 7.  I am going to be using MVVM Light as my framework of choice, since it fits all my requirements and is amazingly easy to use, but if you want to check out another alternative feel free to tune into Bill Moore presenting on Windows Phone 7 and MVVM with Caliburn.Micro as part of our Windows Phone Wednesdays event

 
The first step in this series involves doing two things – getting the latest and greatest copies of the Telerik RadControls for Windows Phone 7 as well as the MVVM Light framework from Galasoft.  Once you have these installed on your system, we want to start up a brand new Windows Phone 7 project and add the following assemblies:

  • GalaSoft.MvvmLight.Extras.WP7
  • GalaSoft.MvvmLight.Wp7
  • Telerik.Windows.Controls.Data
  • Telerik.Windows.Controls.Primitives
  • Telerik.Windows.Core
  • Telerik.Windows.Data

This will help ensure that all of the functionality that we are looking for is available as we work through this example.

Step 1 – The ViewModel

Knowing that we want to utilize the MVVM pattern, we are going to begin with the ViewModel, allowing us to define just what functionality we will want to have available so that our designer (also you) can easily utilize public properties that are available to create a great looking application.  We will create a new class named RadDataBoundListBoxViewModel.cs to serve as our viewmodel, so our first step is to have it inherit from the MVVM Light ViewModelBase (giving us RaisePropertyChanged and a host of other features we can utilize down the road).  We’ll also create a very basic class to use for our data, so before adding any real functionality our viewmodel will look like this:

namespace RadDataBoundListBoxMVVM
{
    public class RadDataBoundListBoxViewModel : ViewModelBase
    {
        public RadDataBoundListBoxViewModel()
        {
        }
     }
   
    public class MyItem
    {
        public int id { get; set; }
        public string CustomerName { get; set; }
    }
}

 

Step 2 – Making the ViewModel Useful

What good is a viewmodel that doesn’t expose some data and functionality that we can use?  I’ll let you ponder that for a moment, then we want to go ahead and add a collection and a single MyItem that can be used for our SelectedItem on RadDataBoundListBox.  These are pretty straightforward, the only thing of note is that we don’t define RaisePropertyChanged – as we mentioned before, we’re utilizing the built-in support from MVVM Light on this, since we can then add other functionality (think messaging) as our application gets more complex.  So we have two properties with backing fields:

private ObservableCollection<MyItem> myItems;
public ObservableCollection<MyItem> MyItems
{
    get
    {
        if (myItems == null)
            myItems = new ObservableCollection<MyItem>();
        return myItems;
    }
    set
    {
        if (myItems != value)
        {
            myItems = value;
            RaisePropertyChanged("MyItem");
        }
    }
}
private MyItem selectedListCustomer;
public MyItem SelectedListCustomer
{
    get
    {
        return selectedListCustomer;
    }
    set
    {
        if (selectedListCustomer != value)
        {
            selectedListCustomer = value;
            RaisePropertyChanged("SelectedListCustomer");
        }
    }
}

 

We also want to ensure that we can have some data available to display.  This will be accomplished by two methods called LoadData and LoadMoreData:

public void LoadData()
{
    for (int i = 0; i < 50; i++)
    {
        MyItem mi = new MyItem();
        mi.id = i;
        mi.CustomerName = "Customer #" + i.ToString();
        MyItems.Add(mi);
    }
}
public void LoadMoreData()
{
    for (int i = 0; i < 10; i++)
    {
        MyItem mi = new MyItem();
        mi.id = i;
        mi.CustomerName = "Customer #" + i.ToString();
        MyItems.Add(mi);
    }
}

 

Realistically you’ll probably be pulling information from isolated storage, a service call, or a Sterling database (or other alternative), but here we want to get the concepts nailed down before bringing in any more levels of complexity.

Step 2.5 – Adding What’s Missing with MVVM Light

We have properties with backing fields as well as methods to generate some data to display – so what do we do next?  Thanks to MVVM Light, we have the ability to utilize a RelayCommand to bind a method from our viewmodel to a button command within our view.  This means that we need to add two RelayCommands to our viewmodel as well as point them at our data loading methods that we have already created:

public RelayCommand LoadDataCommand { get; set; }
public RelayCommand LoadMoreDataCommand { get; set; }
public RadDataBoundListBoxViewModel()
{
    LoadDataCommand = new RelayCommand(LoadData);
    LoadMoreDataCommand = new RelayCommand(LoadMoreData);
}

 

Step 3 – Xaml, the Easy Part


So much time has been spent within our viewmodel by now, let’s put that to use by getting to the fun part of Windows Phone – the Silverlight!  Our Xaml view will actually be relatively simple for this example since we have so much being covered by binding, but let’s be sure to start by adding two namespaces for the RadDataBoundListBox, the MVVM Light commanding, and one to access the viewmodel:

xmlns:telerikPrimitive="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Primitives"
xmlns:commands="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.WP7"
xmlns:local="clr-namespace:RadDataBoundListBoxMVVM"

 

With these in place, we can easily add a reference to our viewmodel as well as set it to the DataContext of the default layout grid:

<phone:PhoneApplicationPage.Resources>
    <local:RadDataBoundListBoxViewModel x:Key="xRDBLViewModel" />
</phone:PhoneApplicationPage.Resources>
    <!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot"
      DataContext="{StaticResource xRDBLViewModel}"
      Background="Transparent">

 

This will give us access to both the public properties as well as the commands on our viewmodel.  Next step is setting up the RadDataBoundListBox, two buttons to hook to our commands for loading data, and last but certainly not least a text block to display the bound SelectedItem:

<Grid x:Name="ContentPanel"
      Grid.Row="1"
      Margin="12,0,12,0">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <Button HorizontalAlignment="Left"
            Content="Load Data"
            commands:ButtonBaseExtensions.Command="{Binding LoadDataCommand}" />
    <Button HorizontalAlignment="Right"
            Content="More Data"
            commands:ButtonBaseExtensions.Command="{Binding LoadMoreDataCommand}" />
    <telerikPrimitive:RadDataBoundListBox x:Name="xRadDataBoundListBox"
                                          Grid.Row="1"
                                          Margin="5"
                                          BorderBrush="Silver"
                                          BorderThickness="2"
                                          DisplayMemberPath="CustomerName"
                                          ItemsSource="{Binding MyItems}"
                                          SelectedItem="{Binding SelectedListCustomer, Mode=TwoWay}"/>
    <TextBlock Grid.Row="2"
               Text="Selected:" />
    <TextBlock Grid.Row="2"
               HorizontalAlignment="Right"
               Text="{Binding SelectedListCustomer.CustomerName}" />
</Grid>

 

As you can see, we don’t have to do much in order to get everything functional – the power of Xaml binding handles most of it for us!  MVVM light commands:ButtonBaseExtensions hook up our buttons to utilize our data loading while RadDataBoundListBox and the lower TextBlock are bound to the MyItems and SelectedListCustomer items, keeping them in sync without writing a line of code to handle selection changed events or the like.  The end result looks something like this:

RadDataBoundListBox MVVM

Easy, right?  Download the full source code for this example right here, and look forward to more posts in this MVVM series as we walk through the RadControls for Windows Phone 7.  Also, don’t forget the Windows Phone Wednesdays series that is coming up to learn about Azure, Rx, Caliburn.Micro, and Push Notifications on the phone, further expanding your abilities as a Windows Phone 7 developer!

Also, added side note, this is a series, so we are going to be building upon this application as we add more of the RadControls, resulting in a full mini samples browser of the RadControls for Windows Phone 7, all done with MVVM!  Rockin!


About the Author

Evan Hutnick

works as a Developer Evangelist for Telerik specializing in Silverlight and WPF in addition to being a Microsoft MVP for Silverlight. After years as a development enthusiast in .Net technologies, he has been able to excel in XAML development helping to provide samples and expertise in these cutting edge technologies. You can find him on Twitter @EvanHutnick.

Comments

Comments are disabled in preview mode.