Windows Phone 7 Development Using MVVM and Unit Testing
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 | & | | 
By: John Baird
John Baird is the founder of Xamlware, a professional consulting firm specializing in Silverlight and Windows Phone 7 development. John has 30 years of experience designing, coding, and implementing software solutions.
John co-founded the Northern Delaware .Net Users group, is heavily involved in the local .Net communities, and travels extensively presenting to user groups, code camps and special interest groups. John is also a three-time recipient of Microsoft’s MVP award and is one of the first MVPs for Windows Phone 7.
jbaird@ordertek.com |