As readers of this magazine, you are all experts at certain facets of software development, be it for the desktop, the web, SQL Server and now mobile platforms. Mobile programming was a fairly arcane development arena up until the recent announcement of Windows Phone 7 (WP7). Prior to WP7, you had to become intimately familiar with the myriad platforms and form factors available and write your programs to each of those phones. With the advent of WP7, Microsoft is now controlling the hardware capabilities of the phone making it much easier to develop for these platforms. You can now also leverage existing skills in Silverlight and XNA to write your apps. But the question always remains: how do I get started and what is the best way to write for the new WP7? In a previous article, CODE Magazine Jan/Feb 2011, I showed you what to do to get started; now I want to show you the best way to apply what you have learned in that article. I will use Silverlight, the Model-View-ViewModel (MVVM) pattern, and Silverlight Unit testing to build a sample app.

Silverlight

Silverlight is a great programming environment and is well-suited for mobile development because it is lightweight and self-contained. It has its own CLR and all functionality is, by default, contained in a single .xap file. You can transfer this .xap file anywhere that has the silverlight runtime and you can execute the code contained in it.

There are a few basic tenets to Silverlight programming that you need to be aware of. Silverlight leverages layout containers to position its control content. In the Silverlight world, you want controls to flow into the space given them rather than using the absolute positioning paradigm familiar to web/win forms programmers. Silverlight has five layout controls, but in normal use, you’ll probably only use two: the grid and the stack panel.

The grid is analogous to the HTML Table as it can contain columns and rows for precise control over content placement. The stack panel allows you to stack controls either horizontally or vertically. You can also nest grids within grids and stackpanels. You can create a precise hierarchy of layout containers to completely constrain your page layout to your satisfaction.

Listing 1 shows a fairly complex layout with nested grids and stackpanels to layout the controls in an even flowing manner. It shows the use of a data template for the listbox. Figure 1 shows the results of the layout on the phone screen.

Figure 1: The View.

One of the most powerful features of Silverlight is its capability to bind to almost any kind of data. The binding engine allows you to specify the datacontext of a page or control and then looks to that context for the name you’ve declared in the binding. If it finds it, it displays the value; if not, it simply ignores it - there is no error generated. You can bind to data from the DataContext or to values of other controls in the page (Element-To-Element binding).

Imagine a page with about 30 checkboxes (I actually had to write something close to this) of options that allow the user to include or exclude specific data from a report. In WinForms, you would have to write tons of code to check the state of all checkboxes, and then have a number of methods where you would enable/disable the checkbox on a given condition. Some of these routines could be hundreds of lines of code. With Silverlight, you bind the value of each checkbox to the content of a related item, greatly reducing the amount of maintenance code.

In the following snippet, the Visibility of the TextBox is tied to the CheckBox’s IsChecked property through element-to-element binding.

<CheckBox
  x:Name="chkAddCategoryType"
  Grid.Row="0"
  Content="Add new category type"
  HorizontalAlignment="Left"
  VerticalAlignment="Center" />
    
<TextBlock
  Text="Category type"
  Grid.Row="1"
  Grid.Column="0"
  VerticalAlignment="Bottom"
  Visibility="{Binding
     ElementName=chkAddCategoryType,
     Path=IsChecked,
     Converter={StaticResource
        BooleanToVisibilityConverter}” />

In addition to powerful binding constructs, Silverlight also includes a rich data-templating capability. With data-templating, you can change the look and feel of any data presentation simply by altering the template. The following code snippets demonstrate the difference in the XAML between the two ComboBox controls used to generate the comboboxes displayed in Figure 2.

Figure 2: A standard and a data-templated ComboBox.

In addition to powerful binding constructs, Silverlight also includes a rich data-templating capability.

The first snippet shows two ways to create the combobox without using data templates: one with the ComboBoxItems manually declared and the other with the ItemsSource set to a List<T>.

<ComboBox
  HorizontalAlignment="Left"
  VerticalAlignment="Top"
  Margin="15"
  Width="90" >
  <ComboBoxItem Content="Asus" IsSelected="True"/>
  <ComboBoxItem Content="Dell" />
  <ComboBoxItem Content="HP" />
  <ComboBoxItem Content="Lenovo" />
</ComboBox>
    
<ComboBox
  ItemsSource="{Binding ContentList}"
  DisplayMemberPath="ManName"
  Margin="15"
  HorizontalAlignment="Left"
  VerticalAlignment="Top"
  Width="90" />

This snippet demonstrates the use of data templating to produce a rich display layout in the ComboBoxItem. Notice that the ComboBox ItemsSource is bound to a List<T>:

<UserControl.Resources>
 <pv:ComboBoxItemImagePathConverter
    x:Key="ComboBoxItemImagePathConverter" />
    
  <DataTemplate x:Key="ComboBoxItemTemplate">
    <Border
     BorderBrush="Blue"
     BorderThickness="0,0,0,1">
        
     <Grid>
      <Grid.RowDefinitions>
       <RowDefinition Height="Auto" />
       <RowDefinition Height="Auto" />
      </Grid.RowDefinitions>
    
      <Grid.ColumnDefinitions>
       <ColumnDefinition Width=".25*" />
       <ColumnDefinition Width=".75*" />
      </Grid.ColumnDefinitions>
    
      <Image
       Grid.Row="0"
       Grid.RowSpan="2"
       HorizontalAlignment="Left"
       Height="40"
       Width="40"
       Margin="0,0,15,0"
       Stretch="Uniform"
       Source="{Binding
               Converter={StaticResource
            ComboBoxItemImagePathConverter}}"
      />
    
      <TextBlock
       Text="{Binding ManName}"
       FontSize="12"
       FontWeight="Bold"
       Foreground="Blue"
       Grid.Row="0"
       Grid.Column="1" />
    
      <TextBlock
       Text="{Binding ManHome}"
       FontSize="10"
       Grid.Row="1"
       Grid.Column="1" />
     </Grid>
    </Border>
  </DataTemplate>
</UserControl.Resources>
  
<Grid x:Name="LayoutRoot" Background="White">
  <ComboBox
   ItemsSource="{Binding ContentList}"
   ItemTemplate="{StaticResource
                        ComboBoxItemTemplate}"
   Margin="15"
   HorizontalAlignment="Left"
   VerticalAlignment="Top"
   Width="250" />
</Grid>

The key part of the above code is the addition of the ItemTemplate attribute and assigning the data template we created in the UserResource section to it. The converter specified simply takes a string location to the graphic image and converts it to a format consumable by the user control. Type and value converters are another powerful feature of Silverlight.

/// <summary>
/// Convert string to image path...
/// </summary>
public class ComboBoxItemImagePathConverter :
                              IValueConverter
{
  public object Convert(
object value, Type targetType,
object parameter, CultureInfo culture)
  {
    var path = "/PhillyDotNet;Component/Media/";
    var item = (ComputerManufacturers) value;
             
if (item != null)
      {
        switch (item.ManName)
        {
          case "Asus":
          {
             path += "AsusLogo.jpg";
             break;
           }
           case "Dell":
           {
             path += "DellLogo.png";
             break;
           }
           case "HP":
           {
             path += "HPLogo.png";
             break;
           }
           case "Lenovo":
           {
             path += "LenovoLogo.jpg";
             break;
           }
        }
      }
    
      return path;
    }
    
    public object ConvertBack(
            object value, Type targetType,
            object parameter, CultureInfo culture)
    {
            return null;
    }
}

Silverlight has more flexible functionality that makes it a great programmer’s language and you can learn more about it at: www.silverlight.net

Metro

Metro is the new UI look and feel from Microsoft. It embodies a crisp definition of text against a background of opposite coloring, rendering a document, page or screen that is much easier to read. It stems from the signage used in train stations, airports, street signs, etc., across the world. These signs provide information to the user in a concise, clear, easy to read format. Metro’s goal is to leverage that clarity for the phone. You should develop your applications taking advantage of the pre-defined metro themes and styling. You can find excellent guildelines in the Microsoft UI Design and Interaction Guide for Windows Phone 2.0. This 69-page document lists current best practices and development guildines for WP7. You can download it from:

http://download.microsoft.com/download/D/8/6/D869941E-455D-4882-A6B8-0DBCAA6AF2D4/UI%20Design%20and%20Interaction%20Guide%20for%20Windows%20Phone%207%20Series.pdf

Jeff Wilcox, a Senior Software Development Engineer at Microsoft, member of the Silverlight team and author of the popular 4th & Mayor application for WP7, has a great blog and has authored a number of resources for the WP7 developer. You can find his post concerning Metro guildlines, which provides specific insights for the serious devleoper, at: http://www.jeff.wilcox.name/2011/03/metro-design-guide-v1/.

Professional WP7 Development

In my opinion, any professional who desires to design and code for WP7 must follow a few common standards that have become best practices in other endeavors and are now extending to the phone. If you are going to develop for WP7, you need to understand:

  • MVVM
  • Unit testing
  • Phone best practices and concepts

Model-View-ViewModel (MVVM)

Developing user interfaces in today’s world of whirlwind change is not an easy task. An ongoing spate of research tells us that this is the proper technique to use to create effective user interaction. What are we to believe? A number of dedicated WPF/Silverlight developers have put forth much effort to determine the most effective way to present the UI in XAML-based solutions. Recent experience points to one emerging best practice.

Standard Silverlight development is done using a User Control (.xaml) and a code-behind file (.cs). The user creates their XAML page and then adds methods and funcitons to the code behind to accomplish their intentions. Using this default methodology to code your application results in a fully functioning application; however, there are also a few problems with this approach. The main problem is that you cannot unit test the application code. Other problems include a lack of loose coupling in the application as well as the fact that multiple developers cannot modify the given page at the same time leading to bottlenecks in development.

The Model-View-ViewModel (MVVM - pronounced move-em) pattern, which has recently emerged as a best practice, addresses most of these problems for Silverlight/WP7 developers. MVVM is a design pattern that had its beginnings at Microsoft and is a modification of Martin Fowler’s MVP design pattern. The major difference between MVP and MVVM is that in MVVM, the ViewModel doesn’t need a reference to the view. MVVM segments the program architecture into UI (View), Data (Model) and the interface code (ViewModel). Figure 3 shows the relationships between elements of the MVVM pattern.

Figure 3: The MVVM design pattern.
The Model-View-ViewModel (MVVM - pronounced move-em) pattern, which has recently emerged as a best practice, addresses most of these problems for Silverlight/WP7 developers.

MVVM, however, also has drawbacks:

  • Lack of standardization and guidance
  • It may be overkill for simple UI programming
  • If not managed well, there is a tendency for duplicated code

In my opinion, the positive aspects of MVVM outweigh the negative, if managed well, and careful consideration is given to construction of the various tiers.

Model

The model is the static data repository. It can be anything from simple POCO (Plain old CLR objects) classes, complex data structures from the Entity Framework, or data being returned from web services. Some people think of the model as the data access layer. The model knows nothing about the other parts of the application; it simply exists to serve data to the application ViewModel when requested.

View

The View is the main .xaml file which contains your page layout and child controls to display data and allow the user to perform actions on that data such as add, edit and save. The View knows nothing about the other portions of the application; however, it has a non-explicit relationship to the ViewModel because the ViewModel is instantiated in the View and receives binding update requests from the ViewModel. The View can also initiate communication with the ViewModel through the Commanding interface. The View exists simply to receive data through binding and display it. It could be navigation page, a report, or a chart. The visualization of the data doesn’t matter - it simply displays it.

ViewModel

The ViewModel is the bridge between the Model and the View. It contains the code which interfaces with the model and manipulates the properties in itself to which the View is bound. The ViewModel is the only part of the MVVM pattern that can communicate to the other parts. The ViewModel can request data from the Model and can notify the View to perform UI-related activities that should not be part of the View model. This communication with the View is normally done through some sort of messaging/event subsystem.

Key Concepts

MVVM operates by a set of key concepts:

  • Binding - Any property/attribute on the View that changes is bound to an analogous property in the ViewModel, using Two-Way binding mode.
  • Commanding - Any object that inherits from button contains a command attribute that should be bound to a command property in the ViewModel.
  • INotifyPropertyChanged - Raising this event is the magic that causes the View to update when a property in the ViewModel changes.
  • InterViewModel and ViewModel-View communications are done through either events or a messaging system.

Creating the ViewModelBase

If you are not using an MVVM framework, you have a little bit of work to do to set up the required pieces for easy use. As mentioned in the key concepts, binding depends on properties in the ViewModel that raise INotifyPropertyChanged to update the View. Most MVVM users develop a base class to centralize the requisite functionality for MVVM. The following snippet shows the beginning of a simple base class to implement INotifyPropertyChanged.

using System.Windows;
using System.Windows.Input;
using System.ComponentModel;
    
namespace Xamlware.ViewModels
{
  public class ViewModelBase :
                   INotifyPropertyChanged
  {
    public event PropertyChangedEventHandler
                   PropertyChanged;
    
    /// <summary>
    /// On property changed event handler
    /// </summary>
    /// <param name="name">Property name</param>
    protected virtual void
             OnPropertyChanged(string name)
    {
      if (this.PropertyChanged != null)
      {
        this.PropertyChanged(this,
             new PropertyChangedEventArgs(name));
      }
    }
  }
}

In order to implement commanding, we will rely on the ICommand interface and add that to our ViewModelBase. ICommand implements three methods:

  • Execute - The code to execute when the command button is clicked.
  • CanExecute - This method returns a Boolean signifying whether the execute command can actually process the request. Any kind of logic can be placed here that returns a Boolean value.
  • CanExecuteChanged - This event is raised whenever the value returns from the CanExecute method changes.

NOTE: There is a known bug in Silverlight that prevents the CanExecute from firing more than once. The workaround for this is to use a property like IsEnabled for each command button and in its Setter, raise the CanExecuteChanged event, which causes a requery of the CanExecute.

public class DelegateCommand : ICommand
 {
    private Action<object> _execute;
    private Func<object, bool> _canExecute;
    public DelegateCommand(Action<object> execute,
                Func<object, bool> canExecute)
    {
      _execute = execute;
      _canExecute = canExecute;
    }
    
    public bool CanExecute(object parameter)
    {
      if (_canExecute != null)
      {
        return _canExecute(parameter);
      }
      return true;
    }
    
    public event EventHandler CanExecuteChanged;
    public void Execute(object parameter)
    {
      if (_execute != null)
      {
        _execute(parameter);
      }
    }
 }

The last concept we must add to our base class is our interprocess messaging system. In our ViewModelBase, we’ll raise an event to broadcast our intent. Other components of the MVVM system can register and listen for this broadcast. This snippet shows the addition of the event for communication.

public event EventHandler<NotifyEventArgs> Notify;
    
public void OnNotify(string notification,
                     object data)
{
if (this.Notify != null)
   {
      this.Notify(this, new NotifyEventArgs
                  {
                     Notification = notification,
                     Data = data });
                   }
    }
}
    
public class NotifyEventArgs : EventArgs
{
public string Notification { get; set; }
   public object Data { get; set; }
}

Creating an MVVM Project

If you are using your custom ViewModelBase, then you are set to implement your MVVM solution. You will begin by creating a new project in Visual Studio, utilizing the Windows Phone application template (Figure 4).

Figure 4: Creating the new WP7 application.

When you create your MVVM project, the first step is normally to add three new folders to your project (Figure 5), Views, ViewModels and Models.

Figure 5: Our project ready for MVVM.
Figure 6: The main screen layout.

In our sample program, we’ll implement the three parts of MVVM.

Defining a Model

Listing 4 shows a simple POCO class definition for the category model. Listing 5 shows the definition for the Expense Model. Both models contain a number of classes and methods to build each data collection. If we needed additional methods to add functionality or manipulate our collection, those methods would be added here in the model as public methods and would be called from the ViewModel. Remember, our model exists solely to serve up data when requested by the ViewModel.

Creating the Views

In the MainPage.xaml, we’ve added a number of buttons and setup navigation to other application pages. Listing 1 shows our MainPage Xaml setup and Listing 2 shows the code behind and navigation.

Add a new user control to the Views folder and name it ExpenseView. It will follow the definition shown in Listing 3 and look like Figure 1.

Creating the ViewModel

Add a class to the ViewModels folder and name it ExpenseViewModel. Listing 6 shows the code for the ViewModel and Listing 7 shows the ViewModel wireup for the ExpenseView. Notice the inheritance from ViewModelBase, the reference to the CategoryModel and the use of Notify (our interprocess event).

Conclusion

In this part of the article, we’ve covered the basic concepts of Silverlight, Metro and an introduction to MVVM. By embracing these principles, you will be on the right path to developing professional software and applications for WP7. In Part 2 of this article, I’ll discuss the MVVM Light Framework, the Silverlight Unit Test Framework, and show you how to put it all together to develop a simple application.