Porting Silverlight or WPF XAML/code to a Windows Store app
If you're familiar with other XAML-based platforms such as Windows Presentation Foundation (WPF), Microsoft Silverlight or Silverlight for Windows Phone, then you can re-use these skills to create Windows Store apps for Windows 8. This topic lists high-level differences you should be aware of between programming on these different platforms.
Note If you are specifically porting a Windows Phone app, first read Migrating a Windows Phone 7 app to a Windows Store app using XAML.
Roadmap: How does this topic relate to others? See: Roadmap for Windows Store apps using C# or Visual Basic
Windows Store apps have a unique look and behavior (personality) that sets them apart from other apps including those apps you have created using other XAML-based platforms. Be sure to take some time to learn the best practices for creating a great Windows Store app. See Make great Windows Store apps and the UX guidelines for Windows Store apps.
- The application model for activation and app lifetime is different, because apps can be suspended and resumed. For more info, see Launching, resuming, and multitasking.
- The Application tag in app.xaml cannot be used to attach app lifetime events; behavior for events such as Suspending must be done as part of startup logic in the app.xaml code-behind file.
- The Window object is less directly equivalent to a running application HWND from a Microsoft Win32 programming perspective. Some of the advanced windowing features are surfaced on a separate object, which you can get using the value of the Window.CoreWindow property.
- On the other hand, if you are coming from a Silverlight app perspective, you no longer have the browser host as an intermediate programming boundary: your Windows Store app is running directly in the Windows Runtime. This simplifies things by taking away browser hosting issues that Silverlight had to work within, such as input handling going through a program access layer, limited storage access, and an Internet-centric security and caching model.
- Silverlight apps could either package application parts into the deployment package, as external parts, or download components on demand. A Windows Store app has these choices too, but the APIs used to access the package parts are different. Where Silverlight uses Application.GetResourceStream, a Windows Store app uses a more generalized model, where the installed package is just a storage folder. For example, you can get the Package.InstalledLocation property value and then call a variety of StorageFolder APIs (most of which are asynchronous) in order to get any other packaged components.
- The Windows Runtime app model introduces a capability concept. You must declare a capability as part of your development and deployment process, and a user can see in the Windows Store UI that your app has requested a particular capability. You might need to request capabilities to access library storage for a user, to use webcam APIs, and so on. For certain code that worked before in Silverlight and WPF, even if you have the code ported correctly at a syntax level, you might still need to request a Windows Runtime capability in order to access that code. For more info, see App capability declarations.
- Launching an app directly from a tile is not the only way a Windows Store app might be activated. For example your app can be launched by file associations. For more info see How to activate an app and other topics in Launching, resuming, and multitasking.
The architecture of the Windows Runtime is based on the principle that developers can use different languages to access the same underlying Windows Runtime functionality and concepts. One aspect of how different languages can each program against Windows Runtime and also preserve some of the characteristics of the developer's language choice is type projection. In the case of Microsoft .NET languages, developers for those languages are familiar with the .NET type system and with the base-level types and concepts implemented by the .NET mscorlib assembly.
There is a list of types that are specifically projected for .NET when programming for the Windows Runtime. These types exist either in the mscorlib assembly and System namespace, or are specifically added to one of the WindowsRuntime assemblies that are included as .NET reference assemblies for Windows Runtime programming.
Common collection interfaces project as the collection interfaces that are familiar to .NET programmers. IVector<T> projects as IList<T>. IMap<K,V> projects as IDictionary(TKey,TValue). Related view classes and read-only variants have similar projections. Through these projections, any Windows Runtime class that implements a collection interface can support the API of the projected .NET collection interface.
Common "primitives" project as the mscorlib/System type that developers are familiar with from .NET programming. For example any app code involving a double value can use the API supplied for System.Double when programming with a .NET language.
.NET APIs that interact with the type system can reference the .NET System.Type.
- ICommand patterns uses the .NET definition (System.Windows.Input.ICommand).
The interfaces that you used for binding-aware business objects written in .NET translate across when you use the object as a Windows Runtime data source. For example, a binding can respond to PropertyChanged or CollectionChanged as implemented on a business object class that was originally written for WPF or Silverlight.
Many of the structures that are commonly used as value types for XAML UI programming are projected as structures that have utility methods available. These structures have the same name and namespace location, but reference into a WindowsRuntime assembly so that the utility methods are supported for .NET. For example, .NET programmers can use utility API of Matrix3D such as HasInverse, or the built-in operators.
A related concept is that once a type is projected as a .NET type, it can support .NET extension methods. This enables .NET extension methods that are specifically intended for Windows Store app authors. For example, an existing .NET type such as StreamReader can support methods that use async patterns similar to those in Windows.Storage APIs.
Note Type projections are intended to aid with your XAML and code porting scenarios, particularly when you are porting the C#, Visual C++ component extensions (C++/CX), or Microsoft Visual Basic code-behind. So for the most part you can avoid having to think about whether a given type you are using is really a projected type. The compilers and project templates will do the right thing for you.
When you use types that are projected, you still might need namespace references for cases where the projections are there for runtime support, but are not part of the .NET core framework libraries and not defined in existing .NET namespaces like System.Collections.Generic. For example, if you have C# code that uses the Point structure, you'll still need a using statement that references the Windows.Foundation namespace, because that's how the projected Point is defined too.
For more info on .NET and Windows Store app using C++, C#, or Visual Basic programming, see .NET Framework Support for Windows Store apps and the Windows Runtime.
- If you are not programming with a .NET language, and are instead programming using C++/CX, structures have a basic C-style definition that doesn't support non-data members. You might need to call static methods from a related helper class. For example, to compare different values of a Duration structure, you don't call methods of Duration, you use methods of DurationHelper instead.
- The programming model has integrated syntax for asynchronous operations. Asynchronous operations are more prevalent in the programming model than they were for WPF or Silverlight, the goal here was to provide patterns that made it harder to inadvertently block the UI thread in an event handler or callback. For more information, see Quickstart: Calling asynchronous APIs in C# or Visual Basic.
- Because of async patterns or other background tasks that aren't on the UI thread, you might have a greater need to make calls from other threads that eventually update the UI thread, asynchronously. The API you use to get across threads is the same as in Silverlight, DependencyObject.Dispatcher.
- File and storage access that might have been done with mscorlib and system assembly APIs are now done with dedicated system API such as StorageFile.
- If you are programming using a .NET language, then you can also use existing System.IO.Stream based logic by accessing extension methods. In a code editor, these should appear as options in the Microsoft IntelliSense dropdowns whenever you have Stream instances.
The Silverlight navigation model used XAML pages, either loose or in the package, as the basis for targeting the content to navigate to. Windows Store apps use types, and in particular the type that is indicated as the x:Class for a XAML page. A good plan would be to use the Add New functionality from Solution Explorer to create new XAML pages within the Windows Store app project template of your choosing. Import the elements below the root level of the original Silverlight page, and work through any further conversion issues that may exist. Then build up your navigation structure using a Frame on the main page. Alternatively, create a new project using the Grid App or Split App templates; these include pages that already have a navigation framework, plus view state templates and suspend/resume logic. For more info, see Part 3: Navigation, layout, and views.
Windows Runtime has Page and Frame classes in the default control set, whereas in Silverlight these came from the SDK libraries and had to be distributed. If you're porting XAML for a Page or a Frame, you can remove the "sdk:" prefix. Make sure you're handling the NavigatedTo and NavigatedFrom events if pages need to do any cleanup during a navigation action. These events replace the Silverlight override methods of Page (OnNavigatedTo, OnNavigatedFrom). Also, where the Silverlight Frame had simple navigation buttons in its control template, the Windows Runtime navigation features are integrated with the layout-aware page templates. For more info see Quickstart: Navigating between pages.
Tile and notification features had varying levels of support in previous XAML frameworks, so there's no general recipe for how to convert these. For more info on how these features work in a Windows Store app, see Working with tiles, badges, and toast notifications. If you're specifically porting Windows Phone push notifications, see the relevant section in Migrating a Windows Phone 7 app to a Windows Store app using XAML.
For Windows Store apps that use .NET languages (C# or Visual Basic), the .NET Framework APIs that you call are part of a particular .NET Framework profile. This relationship is explained in detail in the topic .NET for Windows Store apps overview.
XAML for Windows Runtime is a very close match to XAML for Silverlight as far as the capabilities that are part of the XAML language itself. But there are a few differences.
- Instead of using a clr-namespace:/assembly= qualifier set for code-to-XAML namespace references, you use the using: qualifier. XAML namespaces no longer reference specific assemblies; all assembly qualification and inclusion is handled by the application model and how you compose your app package.
- Because you cannot map specific assemblies, some of the references that were made to mscorlib to support common language runtime (CLR) primitives will no longer work. Instead, you can use the XAML language intrinsic types such as x:String. For more info, see XAML intrinsic data types. Also, consider that many of the strings that you stored before as x:String in a ResourceDictionary might better be stored as a string in a resources file for the project. For more info see Globalizing your app.
- XAML for Windows Runtime currently doesn't support custom markup extensions.
- In rare cases, XAML where a non-prefixed Name attribute was acceptable in Silverlight may require an x:Name attribute instead.
- Some cases where an overqualified Setter.Property worked for Silverlight XAML won't work with Windows Runtime XAML. Most Setter.Property values should just be the simple name of the dependency property, and not attempt to qualify its owner (attached properties are the exception, you should still owner-qualify those.)
- There are no mouse-specific input events such as MouseLeftButtonDown. These events along with touch-input specific events are unified under Pointer events. In most cases you can convert the relevant mouse event to PointerPressed, PointerReleased, PointerEntered or PointerExited. For more info, see Responding to user interaction. For MouseWheel, use the PointerWheelChanged event. The wheel delta can be found in the PointerPointProperties on the primary PointerPoint from event data.
- If you were handling manipulations in Windows Phone code to enable actions in controls, and you created visual states for your manipulation handling, you should verify that the controls you're porting don't already have built-in manipulation or gesture support. For example the Windows Runtime ListBox has several interactions enabled already as theme transitions.
- Specific touch interactions can be enabled or disabled on a per-element basis, using properties. For example, you can set IsRightTapEnabled to false, and that element will not originate a RightTapped event. This is intended to avoid possible problems with gesture and manipulation recognition when events bubble through a control composition visual tree.
- Keys for key events do not have a PlatformKeyCode / Key separation. The reported key from event data uses a different enumeration, VirtualKey, and other key information is available as KeyStatus.
- Pointer capture from UIElement can capture multiple pointers, to support touch manipulations that initiate capture. To get the correct pointer reference, use a pointer-related event data class such as PointerRoutedEventArgs.
- Calls to Control.Focus should specify an enumeration value that states that the focus action was programmatic. The Windows Runtime separates the focus calls because its visual states use different behavior for programmatic focus calls. You may have to add new custom visual states for non-keyboard focus if you're trying to port these.
- In order to best optimize the element set for the capabilities of the new graphics stack, we cut some APIs/concepts that would slow down rendering. Examples include OpacityMask, non-rectangular clips, custom easing functions, and bitmap effects.
- VideoBrush is not supported in the Windows Runtime, nor is RadialGradientBrush.
- The Windows Runtime imaging API has a different and more capable underlying imaging component, the Windows Imaging Component (WIC). The good news for you is that this component supports more image source formats than did Silverlight or even WPF. You also have easy-to-use encoder and decoder types available, and some additional API for image manipulation that's already built-in to the WIC. For more info, see the Windows.Graphics.Imaging namespace.
- BitmapCache has different underlying logic than it did in Silverlight, Silverlight for Windows Phone, or WPF. Also, bitmap caching can have an interrelationship with animations and might cause some animations to be considered dependent. If you're using UIElement.CacheMode at all, you should re-profile your app and revisit whether using a UIElement.CacheMode setting for some of your UI is a performance gain for a Windows Store app. For more info, see UIElement.CacheMode and DebugSettings.IsOverdrawHeatMapEnabled.
- Windows Store apps and other frameworks that use XAML for UI definition have the same basic controls such as Button and ListBox, and basic layout containers such as Border, Grid and StackPanel. However Windows Store apps don't have what you might call "signature" controls like the Pivot and Panorama controls from Silverlight. Instead, they have collection-ready controls such as SemanticZoom and FlipView. Additionally, the GridView is now a stand-alone control instead of a component that is used in a ListView. For more info, see Controls by function.
- Although you can often use the same control you used in your original Silverlight or WPF app and perhaps even an entire UI can be ported over to equivalent components, that's not always the best approach. It's particularly when porting your app's UI where you may want to stop and review the Windows Store app design guidance again. For example, your original app and the controls in its UI might not have been designed for touch first, whereas your Windows Store app should be designed for touch first. For more info on design, see Designing UX for apps. For more info on UX guidelines for controls, see the Index of UX guidelines.
- The Windows Runtime adds the concept of a personality animations. These can be used in XAML as transition animations and theme animations applied directly to UI elements without needing to target multiple properties of that element. Storyboarded animations work nearly identically. However, not all storyboarded animations are enabled by default. Disabling dependent animations by default is intended to make developers more aware of the performance costs of animations that would significantly impact the main UI thread. If your animation isn't running as expected, try setting EnableDependentAnimations to true. However, do this judiciously, because running dependent animations has a performance cost. For more info, see Quickstart: Animating your UI, Storyboarded animations, and Make animations smooth.
- If you have any "vsm:" prefixes in your visual state XAML definitions, remove the prefix usages and the prefix definition. You no longer need to map visual state prefixes separately.
- If you are converting visual states, make sure to convert the "Mouse" concepts over to "Pointer" concepts, like you changed over item-level event handling. You may want to rename the visual state names themselves as well as adjusting which properties are changed by the state. Have a look at the existing theme dictionaries such as StandardStyles.xaml, these might suggest some patterns you can follow.
- If you already have an existing high-contrast theme for a custom control that you've converted, make sure to follow the ThemeDictionaries model for how you connect the themes to the control definition. In particular, you probably want to support the named themes identified in the HighContrastScheme enumeration. For more info see XAML high contrast style sample.
The media APIs are similar, but how Digital Rights Management (DRM) integrates with the media APIs is different. Unlike in Silverlight, Windows has a pluggable DRM model and PlayReady is one of possibly several that would be supported, so the APIs are different to account for a content protection manager.
- MediaElement is largely the same, although you probably want to define a new XAML template for any ported MediaElement transport control templates, to make the UI touch-aware. Notable Windows Runtime additions to the MediaElement API are that you can have a "poster" for loading, detect and use stereo video packing modes, and add video effects.
- Camera capture is pretty different between the platforms, you'll be rewriting code rather than porting if you have this feature. For more info see How to preview video from a webcam and Media capture using capture device sample. You'll be using a CaptureElement as the display surface, because VideoBrush isn't available.
Uniform Resource Identifier (URI) handling for file references works a little differently in Windows Runtime. Relative URIs are not supported, at least not at the level of the pure URI types. The .NET System.Uri might appear to give you a RelativeOrAbsolute choice in certain API calls, but in practice all such URIs are absolute, and are evaluated against concepts and locations such as the app package, user-selected locations, app data, and so on.
Any property value that takes a URI may have to be examined. You can't use file: scheme URIs. It's possible that you can bring across XAML with URI references to values such as Image.Source files without worrying about URI issues at all, and have it work as new Windows UI. But this depends on how your original app was structured. When specified in XAML, a URI often appears to be a relative URI, but these strings are processed and completed by the XAML parser before setting any properties at run time. To reproduce this same behavior in code-behind, use the FrameworkElement.BaseUri return as the baseUri parameter value in the Uri constructor that combines a base URI with a relative URI. For more info, see Defining app resources.
The techniques you use to access files and storage in the Windows Runtime are quite different than those in .NET, particularly since many of these APIs use the async pattern and async/await keywords. For more info, see Accessing data and files.
The area of .NET available to a Windows Store app using C++, C#, or Visual Basic doesn't include some of the XML DOM API from the framework, or forwards some of the base types to the Linq namespace. Look for similar APIs in Windows.Data.Xml.Dom and System.Xml.Linq.
Generally speaking, converting an entire project is best done by starting with one of the existing project templates for a Windows 8 app. Then, use existing Add functionality in Solution Explorer to introduce either new or existing XAML pages and code-behind files. Finally, port specific blocks of code into the XAML and code files. If you do it this way, you can avoid the previous framework's implementation details and infrastructure for projects and builds that might be there accidentally. You can use the using/Imports statements with the correct "Windows" namespaces, reference the current build types, and access the RESW resources system, because all of these will be available from newly templated projects and pages.
If your Silverlight project used the Binding-based localization system as documented in the topic How to: Make XAML Content Localizable, you should consider changing the localization technique over to using strings that are declared in the package resource index (PRI) system. Binding-based localization system will still work, but it doesn't have nearly the tooling support that's possible with PRI and .resw files both within Microsoft Visual Studio and for any dedicated localization processes or tools that are based on the Visual Studio localization methodology.
If you choose to attempt to bring over whole code files, you can often search and replace either using/Imports statements or fully qualified references. For example "System.Windows" should be replaced with "Windows.UI.Xaml". There are a few outliers to this general rule of how Silverlight/WPF types ported to the Windows Runtime and its namespaces, and we'll note these cases in the API documentation (in Remarks).
For more info on project templates, see C#, VB, and C++ project templates for Windows Store apps.
- If you have specific .NET code calls that you aren't sure will work in Windows Runtime, see .NET for Windows Store apps - supported APIs
- For more info on other porting scenarios specifically for Silverlight for Windows Phone, see Migrating a Windows Phone 7 app to a Windows Store app using XAML.
- As a top-level document view for creating Windows Store apps using C++, C#, or Visual Basic in general, see Roadmap for Windows Store apps using C# or Visual Basic.
- If you're porting a Windows Phone app that used Microsoft XNA but still had a primarily XAML-based UI, see DirectX and XAML interop.
- Migrating a Windows Phone 7 app to a Windows Store app using XAML
- Roadmap for Windows Store apps using C# or Visual Basic
- UX guidelines for Windows Store apps
- C#, VB, and C++ project templates for Windows Store apps
- .NET Framework Support for Windows Store apps and the Windows Runtime
Build date: 5/22/2013