Introduction

One of the cool announcements Microsoft made around the Windows 10 launch was the Universal Windows Platform (UWP), a single executable that can run on any Windows 10 device, from the Surface to a desktop to a Raspberry Pi. And to support this, Visual Studio 2015 makes it easy to create these apps from a single solution with a single project.

Prior to UWP, about half of all Windows Phone apps were written using WPS (Windows Phone Silverlight). These apps will need significant changes in order to be compatible with the UWP platform. However, once migrated to UWP, those apps can run on all Windows 10 devices. So this creates a lot of new opportunities for app developers.

To jumpstart this development, Mobilize.Net has created a free tool called Mobilize.Net Silverlight bridge that automates a big part of the conversion process from Windows Phone 8.0/Silverlight code to UWP (for Windows 10). An extension to Visual Studio, the tool takes as input your existing projects for both application code and class libs and outputs a new UWP project, converting C# and XAML files to the new UWP platform.

Suppose using Visual Studio 2013 you had created a Windows Phone Silverlight app (“CalculatorWP”):

Loading that project into Visual Studio 2015 with Mobilize SL bridge installed would create a new UWP project like this:

Getting and running the tool

The tool is a free Visual Studio extension. A technical preview is available for download immediately from http://www.mobilize.net/uwp-bridge. Once you download the tool and run the MSI installer, Mobilize SL bridge becomes available as a Visual Studio extension. Open Visual Studio and load your WPS application, then right click your project from the "Solution Explorer" and select the "Convert to UWP" option. The following dialog shows up:

Select your output directory and click "Start" in order to convert the application. After the app is converted, you can either open the new solution in a new Visual Studio instance or go to the folder where the new application was generated.

Converting an application

What does it mean to convert an application? Let's get into the details:

Rewriting your Windows Phone Silverlight application to run on UWP is tedious and may take a lot of time. There are many challenges involved in moving from the old model to UWP including the differences in project structure, new APIs, and namespace changes. The Mobilize SL bridge addresses these challenges.

Project and manifest conversion

Manifests of WPS 8.0 and 8.1 are very different from each other. The big difference is that WPS 8.0 manifests reference elements that come from different namespaces. Mobilize SL bridge saves developers a lot of work by converting both WPS manifest versions to the new UWP one.

The UWP project file is also different from WPS and references different basic assemblies and NuGet packages. Mobilize SL bridge generates the UWP project file and the new JSON project file that manages the NuGet package references. It also converts the WPS assembly and NuGet references to the new ones required by UWP projects.

API changes

UWP is an all new platform that introduces many new API elements when compared to WPS applications. Some of them are similar but others are substantially different. Changes are found through all the APIs via small details like a change in an enumeration or the datatype of a method parameter.

Mobilize SL bridge deals with API changes by providing a mechanism that "maps" elements of WPS APIs to UWP APIs. This feature is known as the Mapping Mechanism and it consists of XAML syntax files that describe the transformation of elements between both platforms. The mappings reduce the amount of manual effort you need to convert the app from the old platform to the new one. Here’s an example:

The XAML below shows how Microsoft.Phone.Controls.Pivot property Tab and event MouseMove are renamed to Tapped and PointerMoved respectively:

<MapUnit xmlns="clr-namespace:Mobilize.Mappers.Extensibility.Core;assembly=ExtensibleMappers"

xmlns:map="clr-namespace:Mobilize.Mappers.Extensibility.Code;assembly=ExtensibleMappers"

xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>

<MapUnit.Elements>

<map:CodeMapPackage Type="Microsoft.Phone.Controls.Pivot"> <!-- Defines a mapping for Pivot type -->

<map:CodeMapPackage.Maps>

<map:CodeMap Kind="MemberAccess" MemberName="MouseMove"> <!-- renames MouseMove to PointerMoved -->

<map:Rename NewName="PointerMoved" />

</map:CodeMap>

<map:CodeMap Kind="MemberAccess" MemberName="Tap"> <!-- retnames Tab property to Tapped -->

<map:Rename NewName="Tapped" />

</map:CodeMap>

</map:CodeMapPackage.Maps>

</map:CodeMapPackage>

</MapUnit.Elements>

</MapUnit>

The first release of Mobilize SL bridge includes 700 mappings, based on analysis that Microsoft did for Mobilize.Net of the most frequently used properties, methods, and events (PMEs). An additional 500 hundred mappings will be added in a couple of months and even more will be added in the future. The initial 1200 available by year end should cover about 80% of all APIs used in the Silverlight Phone apps in the Windows Store.

But the power of mappings is unlimited; the mechanism to create mappings and publish them is open source. Any Windows Phone developer can create their own mappings and share them through a GitHub repository that Mobilize.Net has created.

XAML changes

XAML files describing both WPS pages and user controls require some changes for UWP. Most UWP controls are similar to WPS ones but some properties and events have changed. In addition to the small changes, new components have been added and some WPS ones have an exact match in the new platform.

XAML changes can be seen in a very basic page definition, because WPS page element Microsoft.Phone.Controls.PhoneApplicationPage must be replaced by UWP Windows.UI.Xaml.Controls.Page.

Mobilize SL bridge provides the same Mapping Mechanism in order to convert XAML objects from WPS to UWP. Just like PME mappings, transformations between XAML elements are described in a XAML syntax file, and can be created and shared through the GitHub repository.

The sample below shows how to write a mapping that converts a WPS ListPicker element to a UWP ComboBox:

<MapUnit xmlns='clr-namespace:Mobilize.Mappers.Extensibility.Core;assembly=ExtensibleMappers'

xmlns:xmap='clr-namespace:Mobilize.XamlMappers;assembly=XamlMapper'

xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' >

<MapUnit.Elements>

<xmap:XamlElementMapper ElementName="ListPicker" <!-- indicates that following actions will be applied to ListPicker element and its properties -->

ElementNamespace="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit">

<xmap:XamlElementMapper.Maps>

<xmap:XamlMap Kind="Element"> <!-- starts mappings for ListPicker element -->

<xmap:XamlMap.Action> <!—lists actions to be applied to ListPicker element -->

<xmap:RenameElement NewName="ComboBox" <!-- Renames ListPicker element to ComboBox-->

NewNamespace="http://schemas.microsoft.com/winfx/2006/xaml/presentation" />

</xmap:XamlMap.Action>

</xmap:XamlMap>

</xmap:XamlElementMapper.Maps>

</xmap:XamlElementMapper>

</MapUnit.Elements>

</MapUnit>

Async and Await APIs

Starting with Windows Phone 8 many APIs are exposed using Async and Await. These features improve the responsiveness of the application by avoiding blocking threads while waiting for operations to finish.

As indicated above, UWP provides a new API that takes advantage of the Async/Await programming model. This is goodness for your application, but it introduces an additional challenge when moving applications from WPS to UWP platform.

Manually changing method calls from a method that is not async to an async version can be tedious, because once a call is changed to async it is necessary to propagate the async keyword through the stack of method calls on top of the method containing the new async call. In addition to that, calls must be prefixed with the await keyword. The following example illustrates how WPS code changes with the introduction of just one new async call:

Windows Phone Silverlight

private void Button_Click(object sender, RoutedEventArgs e)

{

Operation1();

Start();

Operation2();

}

private void Start()

{

MessageBox.Show("Warning");

DoStartProcess();

}

Equivalent UWP code

private async void Button_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)

{

Operation1();

await Start();

Operation2();

}

private async Task Start()

{

await ShowWarning();

DoStartLongProcess();

}

private static async Task ShowWarning()

{

await (new Windows.UI.Popups.MessageDialog("Warning")).ShowAsync();

}

Mobilize SL bridge automates the process by analyzing the code that is involved in the async call, propagating the async and await keywords through the appropriate code path. This propagation is heavily integrated with the Mapping Mechanism, so Windows Phone developers can also indicate which new API methods are now asynchronous.

Below the mapping sample shows how the SetView member of Microsoft.Phone.Controls.Maps.Core.MapCore class is marked as async by adding it to the CodeMapPackage.Metadata section and annotated as "ASYNC_MEMBERS". By doing this, Mobilize SL bridge propagates the async/await modifiers through the stack of calls referencing the MapCore.SetView member.

<MapUnit xmlns="clr-namespace:Mobilize.Mappers.Extensibility.Core;assembly=ExtensibleMappers"

xmlns:map="clr-namespace:Mobilize.Mappers.Extensibility.Code;assembly=ExtensibleMappers">

<MapUnit.Elements>

<map:CodeMapPackage Type="Microsoft.Phone.Controls.Maps.Core.MapCore">

<map:CodeMapPackage.Maps> ... </map:CodeMapPackage.Maps>

<map:CodeMapPackage.Metadata>

<map:PackageMetadata Key="ASYNC_MEMBERS" Value="SetView"/>

</map:CodeMapPackage.Metadata>

</map:CodeMapPackage>

</MapUnit.Elements>

</MapUnit>

Extensibility

There’s a huge number of Windows Phone Silverlight specific APIs either included with the framework or provided by third party vendors. Mobilize SL bridge comes with a set of 700 mappings in its first release (technical preview) and will grow up to 1200 in a couple of months. The APIs that ship with Mobilize SL bridge handle the most common scenarios based on counting which APIs are used most in Windows Phone apps.

If your application uses a specific API extensively that is not included in the tool, you can save manual work by taking advantage of the Mobilize SL bridge Extensibility Mechanism.

In order to make writing custom mappings a good experience, Mobilize.Net has provided the following:

All mappings bundled with the tool have been open sourced and published in a public GitHub repository (https://github.com/MobilizeNet/UWPConversionMappings). This way developers all around the world can use them as a reference implementation to write their own.

Usage and reference documentation is provided in the same GitHub repository inside the Wiki section.

In order to use custom mappings in the tool, a developer only needs to copy their own XAML mapping files inside of "%localappdata%\Mobilize.NET\WinPhone2UWP\Mappings". Mobilize SL Bridge will automatically load them the next time it runs.

Because of the nature of GitHub collaboration, developers can either share their own mappings or reuse mappings created by other developers, or even improve core tool mappings by using the GitHub Pull Request feature.

Timing and Availability

The tool is free and a technical preview is available for download immediately. It includes 700 mappings and more mappings are being developed. All 1200 mappings will be completed in early November. You can download the tool at http://www.mobilize.net/uwp-bridge.

Microsoft Blog Post

Microsoft has also written a blog post about the tool: http://aka.ms/silverlightbridge