Reusing Your Existing Silverlight Components With Windows Phone 7
Join the DZone community and get the full member experience.
Join For FreeUsing .NET is all about leveraging your code across platforms. That was
true with previous versions of Windows Mobile OS and it's true in
today's XAML-centric environment. But with Silverlight, a .NET developer
must pay special attention to the separation of core logic and UI in
order to reuse the most code. By organizing your app into the MVVM, or
Model-View-Presenter (aka View-Model) pattern, you'll be able to reuse a
surprising amount of code between your Web-based Silverlight apps and
your Windows Phone 7 apps. This walkthrough will take a basic
Silverlight app and demonstrate how to do just that.
This tutorial is structured of the article as follows:
MVVM Overview
MVVM is
an architecture pattern that aims to organize code in three layers: the
Model, the View and the ViewModel. There are numerous advantages of
doing so, the most important ones being:
Reusing The Code With MVVM
MVVM makes code reuse particularly powerful between Silverlight and WP7
applications thanks to the structuring of its layers. The Model contains
the business logic without framework specific details, thus all of it
can be shared between the Silverlight and WP7 implementations. If the
application's UI logic is identical or similar for both applications,
most of (if not all) of the ViewModel layer code can be shared as well.
The View, however in most cases is significantly different for the
Silverlight and WP7 applications. Even though it is possible to share
parts of the View between the two projects, since a web UI is usually
very different from a phone UI, doing so usually doesn’t make sense.
By using MVVM it is thus possible to reuse all of the code of the existing Silverlight application apart from the View. Considering Silverlight web applications and Windows Phone 7 ones call for different user interfaces most of the time, this means that with MVVM one only has to rewrite the UI specific part of the application.
Reusing Silverlight Components With WP7: An Example
To understand how code can efficiently be reused from an existing
Silverlight application when porting to Windows Phone 7, let's walk
through a simple example - a savings calculator.
The Silverlight Application
The Silverlight application in this example is a simple savings
calculator which looks like this when running:

In the application the user has to enter the initial deposited amount, monthly deposit, annual interest rate and number of years to save for. The application then calculates the total deposited amount as well as the final savings with the annually compounded interest added.
In the application the three layers of the project are structured in three separate projects. The model is a Silverlight 3 class library named SavingsCalculatorModel, the ViewModel is also a SL 3 class library named SavingsCalculatorViewModel and the View (the application to be run) is a SL 4 application named SavindsCalculatorSilverlight. Dependencies are the same one way as in the MVVM pattern: the ViewModel project references the Model and the View project references the ViewModel.
Having outlined the UI and architecture of the example application, let's take a look at how it's implemented using Silverlight.
The Model
The model layer is responsible for implementing the business logic. In
the case of this savings calculator application this means the
responsibility of calculating the savings without and with interest. The
code of the model is quite simple, consisting of several properties and
the CalculateSavings method which calculates the total deposit and the final savings. The code for this is as follows:
The View
In the View we display input fields for all of the required details, a
button to initiate calculation and the outcomes of this calculation. To
do so we'll need to create TextBlock elements for the texts, TextBoxes for the input and a Button
for the calculation button.
The values of the input TextBoxes are data binded to members of the ViewModel. This is done via a two way binding so that changes made by the user are applied on the ViewModel. For example the input field for the annual interest is set up the following way:
The ViewModel
The ViewModel is responsible for gluing the Model and View together. It
will have to expose all the properties that the View will bind to and
wrap these around the Model.
In this example the ViewModel is pretty simple: it acts as wrapper
around the model, sets default values on it when initializing and
exposes the CalculateCommand command to be triggered when the calculate button is pressed.
In the example a simple ICommand implementation is used - Josh Smith's RelayCommand version. The important parts of the ViewModel code are the following:
Porting the Silverlight Application to Windows Phone
Now that we've seen how the Silverlight application is constructed,
let's look into porting it to Windows Phone 7. We want to maintain the
same application logic, but optimize the UI a bit better for the phone
to give it a native feel.
The ported Windows Phone 7 application will look as follows after we've
finished:
Since the business logic hasn't changed, all the code of the model is
reused in the WP7 application. In this example, the Model was a
Silverlight class library, thus the Windows Phone project simply needs a
reference pointing to the model project.
Our UI requirements are functionally the same as for the Silverlight application, meaning that all of the ViewModel code can also be reused as well - no coding needed so far!
Porting the View
When porting the view of the application there's not much point in
reusing the View of the Silverlight application. On the interface of the
phone we'd want a UI that blends in to the WP7 world. We'll need to
modify the original View to achieve this. Some of the changes that we're
making in the view are as follow:
Porting this Silverlight application to Windows Phone proved to be
surprisingly easy: we were able to reuse the Model and ViewModel layers
of the original application without modification and only had to rewrite
the View. However, since a Silverlight application to be run in a
browser and that on a phone require different user interfaces, we would
have had to make changes to the phone UI in all cases.
Overall it's safe to say that by having developed the Silverlight example following the MVVM pattern, we were able to port it to Windows Phone 7 by reusing most of its code and only rewriting the Windows Phone user interface specific part - the View.
The solution containing the Model, ViewModel, the Silverlight View and
the Windows Phone 7 View can be downloaded from here. To run the Silverlight application, build and run the
SavingsCalculatorSilverlight project, for the Windows Phone application
build and run the SavingsCalculatorWP7 project.
Further Thoughts on Code Reuse between Silverlight and Windows Phone
Reusing Parts of the View With UserControls
In the example we didn't reuse any part of the View. The main reason for
this was that the XAML of a Silverlight page and that of a Windows
Phone page is different, making the sharing of the same XAML not
possible.
However, it is possible to reuse UserControls between Silverlight and Windows Phone applications. This can be done both at assembly level or by referencing the XAML of the UserControl.
Possible Problems When Reusing Silverlight Components with Windows Phone
Structuring the Silverlight project following the MVVM pattern does not
always guarantee that the code will be 100% reusable. If the Silverlight
application uses APIs that are not implemented on the Windows Phone 7
Silverlight runtime, the project will not compile for Windows Phone. As
Windows Phone 7 runs an extended Silverlight 3 runtime, at the moment
this issue is mostly localized to the few new APIs introduced by
Silverlight 4. However, when Silverlight 5 for the web is released, this
issue will probably be a more important one.
There are a few workarounds to resolve this, the two most common ones being:
In the example we've implemented commanding (binding the command of the
button to an action in the ViewModel) different for the Silverlight
application than for the Windows Phone port. The reason for this was
that Windows Phone input controls only have notions of triggers, not
commands. We've solved the situation by using the MVVM Light
framework's EventToCommand helper class to forward the events invoked
by triggers to the commands on the ViewModel. This means that while inside
the Silverlight project we've used the following syntax to bind to a
command:
Summary
The article has briefly highlighted some key advantages of using MVVM in
Silverlight projects and has outlined how structuring a project
following the MVVM pattern helps code reuse when porting to Windows
Phone. It then gave a walkthrough creating a simple example - a savings
calculator - giving a quick overview of how the project is structured.
It then explained how to port it to Windows Phone, reusing all of the
code except for the UI specific View layer. Finally, it explored some
other topics that might be important when reusing Silverlight code on
WP7, such as reusing parts of the view, commanding and possible
problems.
Summing it up, the article has shown yet another advantage of structuring Silverlight projects following the MVVM pattern. By doing so it's possible to later port it to Windows Phone 7 only having to rewrite the user interface specific parts of the application.
This tutorial is structured of the article as follows:
- MVVM and Reusing of Code
- Reusing Silverlight Components With WP7: An Example
- Further Thoughts on Code Reuse Between Silverlight and Windows Phone
- Summary
MVVM and Reusing of Code
MVVM Overview
MVVM is
an architecture pattern that aims to organize code in three layers: the
Model, the View and the ViewModel. There are numerous advantages of
doing so, the most important ones being:
- Separation of GUI logic and application logic. The pattern completely separates the View and the Model, so when changes are made in either, they can be done leaving the other unaffected.
- Support for unit tests. The application's functionality can fully tested by writing unit tests, minimizing (or removing) the need of UI-based tests.
- Tool support. The View populated by mock data can be edited in Blend and Visual Studio by designers without modifying other parts of the project.
Reusing The Code With MVVM
MVVM makes code reuse particularly powerful between Silverlight and WP7
applications thanks to the structuring of its layers. The Model contains
the business logic without framework specific details, thus all of it
can be shared between the Silverlight and WP7 implementations. If the
application's UI logic is identical or similar for both applications,
most of (if not all) of the ViewModel layer code can be shared as well.
The View, however in most cases is significantly different for the
Silverlight and WP7 applications. Even though it is possible to share
parts of the View between the two projects, since a web UI is usually
very different from a phone UI, doing so usually doesn’t make sense.
By using MVVM it is thus possible to reuse all of the code of the existing Silverlight application apart from the View. Considering Silverlight web applications and Windows Phone 7 ones call for different user interfaces most of the time, this means that with MVVM one only has to rewrite the UI specific part of the application.
Reusing Silverlight Components With WP7: An Example
To understand how code can efficiently be reused from an existing
Silverlight application when porting to Windows Phone 7, let's walk
through a simple example - a savings calculator.
The Silverlight Application
The Silverlight application in this example is a simple savings
calculator which looks like this when running: 
In the application the user has to enter the initial deposited amount, monthly deposit, annual interest rate and number of years to save for. The application then calculates the total deposited amount as well as the final savings with the annually compounded interest added.
In the application the three layers of the project are structured in three separate projects. The model is a Silverlight 3 class library named SavingsCalculatorModel, the ViewModel is also a SL 3 class library named SavingsCalculatorViewModel and the View (the application to be run) is a SL 4 application named SavindsCalculatorSilverlight. Dependencies are the same one way as in the MVVM pattern: the ViewModel project references the Model and the View project references the ViewModel.
Having outlined the UI and architecture of the example application, let's take a look at how it's implemented using Silverlight.
The Model
The model layer is responsible for implementing the business logic. In
the case of this savings calculator application this means the
responsibility of calculating the savings without and with interest. The
code of the model is quite simple, consisting of several properties and
the CalculateSavings method which calculates the total deposit and the final savings. The code for this is as follows:public class SavingsCalculatorModel
{
public int NumberOfYears { get; set; }
public double AnnualInterest { get; set; }
public double InitialAmount { get; set; }
public double MonthlyDeposit { get; set; }
public double FinalSavingsWithInterest { get; private set; }
public double FinalSavingsWithoutInterest { get; private set; }
/// Calculates FinalSavingsWithInterest and FinalSavingsWithoutInterest based on
/// InitialAmount, NumberOfYears, AnnualInterest and MonthlyDeposit
public void CalculateSavings()
{
// See source for details
}
}
The View
In the View we display input fields for all of the required details, a
button to initiate calculation and the outcomes of this calculation. To
do so we'll need to create TextBlock elements for the texts, TextBoxes for the input and a Button
for the calculation button.
The values of the input TextBoxes are data binded to members of the ViewModel. This is done via a two way binding so that changes made by the user are applied on the ViewModel. For example the input field for the annual interest is set up the following way:
<TextBox Text="{Binding InitialAmount, Mode=TwoWay}"/>We also need to bind the result of the calculations to the view. The results are not to be changed by the user, thus we can use a one way binding (and since this is the default, there's no need to specify the binding mode).
<TextBlock Text="{Binding FinalSavingsWithInterest}" FontWeight="Bold"/>The final part of setting up the View is forwarding the Click event of the Button to the ViewModel. This is done by commanding - that is relaying commands to the ViewModel. To do so, we need to bind the Command property of the Button to an ICommand to be exposed on the ViewModel:
<Button Command="{Binding CalculateCommand}"/>The code for the View can be found in the attached source code in the MainPage.xaml file.
public class SavingsCalculatorViewModel: INotifyPropertyChanged
{
private SavingsCalculatorModel _model;
public int NumberOfYears
{
get
{
return _model.NumberOfYears;
}
set
{
_model.NumberOfYears = value;
}
}
// Similarly wrapping of AnnualInterest, InitialAmount, MonthlyDeposit, FinalSavingsWithInterest and FinalSavingsWithoutInterest
(...)
public ICommand CalculateCommand
{
get
{
return new RelayCommand(CalculateSavings) { IsEnabled = true };
}
}
private void CalculateSavings()
{
_model.CalculateSavings();
RaisePropertyChanged("FinalSavingsWithoutInterest");
RaisePropertyChanged("FinalSavingsWithInterest");
}
// Constructor initializing the default values and INotifyProperyChanged implementations
(...)
The ViewModel
The ViewModel is responsible for gluing the Model and View together. It
will have to expose all the properties that the View will bind to and
wrap these around the Model.
In this example the ViewModel is pretty simple: it acts as wrapper
around the model, sets default values on it when initializing and
exposes the CalculateCommand command to be triggered when the calculate button is pressed.
In the example a simple ICommand implementation is used - Josh Smith's RelayCommand version. The important parts of the ViewModel code are the following:
public class SavingsCalculatorViewModel: INotifyPropertyChanged
{
private SavingsCalculatorModel _model;
public int NumberOfYears
{
get
{
return _model.NumberOfYears;
}
set
{
_model.NumberOfYears = value;
}
}
// Similarly wrapping of AnnualInterest, InitialAmount, MonthlyDeposit, FinalSavingsWithInterest and FinalSavingsWithoutInterest
(...)
public ICommand CalculateCommand
{
get
{
return new RelayCommand(CalculateSavings) { IsEnabled = true };
}
}
private void CalculateSavings()
{
_model.CalculateSavings();
RaisePropertyChanged("FinalSavingsWithoutInterest");
RaisePropertyChanged("FinalSavingsWithInterest");
}
// Constructor initializing the default values and INotifyProperyChanged implementations
(...)
Porting the Silverlight Application to Windows Phone
Now that we've seen how the Silverlight application is constructed,
let's look into porting it to Windows Phone 7. We want to maintain the
same application logic, but optimize the UI a bit better for the phone
to give it a native feel.
The ported Windows Phone 7 application will look as follows after we've
finished:
Porting of the Model and ViewModel
Since the business logic hasn't changed, all the code of the model is
reused in the WP7 application. In this example, the Model was a
Silverlight class library, thus the Windows Phone project simply needs a
reference pointing to the model project.
Our UI requirements are functionally the same as for the Silverlight application, meaning that all of the ViewModel code can also be reused as well - no coding needed so far!
Porting the View
When porting the view of the application there's not much point in
reusing the View of the Silverlight application. On the interface of the
phone we'd want a UI that blends in to the WP7 world. We'll need to
modify the original View to achieve this. Some of the changes that we're
making in the view are as follow:
- We want the form to fill most of the phone screen and offer input
boxes large enough to be easy to tap. To do so, instead of using the
default text style we'll use larger fonts by using the built-in Windows Phone theme resources:
<TextBlock Text="Monthly Deposit:" Style="{StaticResource PhoneTextTitle2Style}" />
- By default when tapping a text input field the user is presented
with a keyboard with alphabetical letters on it, forcing the user to
switch to numerical ones to enter numbers. To avoid this, let's set the InputScope property on the TextBoxes to Number:
<TextBox Text="{Binding InitialAmount, Mode=TwoWay}" InputScope="Number"/>
- Bold text doesn't stand out as much on the phone than it does on the
web. To have the final savings value stand out more, let's set its
color to be the phone's accent color:
<TextBlock Text="Final Savings:" Foreground="{StaticResource PhoneAccentBrush}" Style="{StaticResource PhoneTextTitle2Style}" FontWeight="Bold" />
- Windows Phone doesn't have support for ICommands on input elements, thus we'll have to tap into event triggers and have these triggers forwarded to commands. We'll be using the EventToCommand helper class from MVVM Light to do so. See the Implementing Commanding in a Consistent Way section for more details on this.
Porting Overview
Porting this Silverlight application to Windows Phone proved to be
surprisingly easy: we were able to reuse the Model and ViewModel layers
of the original application without modification and only had to rewrite
the View. However, since a Silverlight application to be run in a
browser and that on a phone require different user interfaces, we would
have had to make changes to the phone UI in all cases.
Overall it's safe to say that by having developed the Silverlight example following the MVVM pattern, we were able to port it to Windows Phone 7 by reusing most of its code and only rewriting the Windows Phone user interface specific part - the View.
Download the Code
The solution containing the Model, ViewModel, the Silverlight View and
the Windows Phone 7 View can be downloaded from here. To run the Silverlight application, build and run the
SavingsCalculatorSilverlight project, for the Windows Phone application
build and run the SavingsCalculatorWP7 project.
Further Thoughts on Code Reuse between Silverlight and Windows Phone
Reusing Parts of the View With UserControls
In the example we didn't reuse any part of the View. The main reason for
this was that the XAML of a Silverlight page and that of a Windows
Phone page is different, making the sharing of the same XAML not
possible.
However, it is possible to reuse UserControls between Silverlight and Windows Phone applications. This can be done both at assembly level or by referencing the XAML of the UserControl.
Possible Problems When Reusing Silverlight Components with Windows Phone
Structuring the Silverlight project following the MVVM pattern does not
always guarantee that the code will be 100% reusable. If the Silverlight
application uses APIs that are not implemented on the Windows Phone 7
Silverlight runtime, the project will not compile for Windows Phone. As
Windows Phone 7 runs an extended Silverlight 3 runtime, at the moment
this issue is mostly localized to the few new APIs introduced by
Silverlight 4. However, when Silverlight 5 for the web is released, this
issue will probably be a more important one.
There are a few workarounds to resolve this, the two most common ones being:
- Wrap the Silverlight 4 (or later on, Silverlight 5) specific calls between #if !WINDOWS_PHONE (...) #endif macro definitions. This way they will only be compiled in the Silverlight project as the default Windows Phone project has the WINDOWS_PHONE constant defined.
- Use partial classes and move the framework version-specific logic into a partial class file only referenced by the Silverlight solution.
Implementing Commanding in a Consistent Way
In the example we've implemented commanding (binding the command of the
button to an action in the ViewModel) different for the Silverlight
application than for the Windows Phone port. The reason for this was
that Windows Phone input controls only have notions of triggers, not
commands. We've solved the situation by using the MVVM Light
framework's EventToCommand helper class to forward the events invoked
by triggers to the commands on the ViewModel. This means that while inside
the Silverlight project we've used the following syntax to bind to a
command:
<Button Content="Calculate" Command="{Binding CalculateCommand}" />In Windows Phone on the other hand, we used this syntax:
<Button Content="Calculate" xmlns:mvvmlight="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WP7" xmlns:interactivity="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity">This situation could have been avoided by using the same MVVM framework for both the Silverlight and WP7 project. In the example simplicity was the key, thus no MVVM framework was used in the Silverlight example. However in a real-world project it's definitely worth using the same framework across the Silverlight and Windows Phone 7 projects to maximize the code reuse. MVVM frameworks supporting both Silverlight and WP7 environments include MVVM Light, Caliburn Micro and - to certain extent - Prism (Silverlight and WP7 build).
<interactivity:Interaction.Triggers>
<interactivity:EventTrigger EventName="Click">
<mvvmlight:EventToCommand Command="{Binding CalculateCommand}" />
</interactivity:EventTrigger>
</interactivity:Interaction.Triggers>
</Button>
Summary
The article has briefly highlighted some key advantages of using MVVM in
Silverlight projects and has outlined how structuring a project
following the MVVM pattern helps code reuse when porting to Windows
Phone. It then gave a walkthrough creating a simple example - a savings
calculator - giving a quick overview of how the project is structured.
It then explained how to port it to Windows Phone, reusing all of the
code except for the UI specific View layer. Finally, it explored some
other topics that might be important when reusing Silverlight code on
WP7, such as reusing parts of the view, commanding and possible
problems.
Summing it up, the article has shown yet another advantage of structuring Silverlight projects following the MVVM pattern. By doing so it's possible to later port it to Windows Phone 7 only having to rewrite the user interface specific parts of the application.
Windows Phone
mobile app
Opinions expressed by DZone contributors are their own.
Comments