February 2013

Volume 28 Number 02

Windows Store Apps - Windows Store Apps: A Guide for WPF and Silverlight Developers, Part 1

By Joel Fjordén | February 2013

Read Part 2 of this article

Windows Runtime, or WinRT, is the new Microsoft framework for building Windows Store apps targeting Windows 8. Windows Runtime supports development in C#, Visual Basic .NET and C++ as well as JavaScript. Windows Store apps run on both x86, x64 and Windows RT platforms without modification. These apps can run on both tablets and Windows 8 desktop computers. Windows Store apps can’t run on Windows Phone 8, however. You can write apps for Windows 8 and Windows RT that share code and look the same to users on each device because each has a Windows Runtime, a core CLR and similar XAML UI vocabularies; but you still need to build them as two different apps and publish them to two different stores: the Windows Store and the Windows Phone Store. Because of the differences in the APIs, you’ll also need to modify and adapt some code—UI design in particular—to the different form factors and resolutions.

This article is the first of two I’m writing for Windows Presentation Foundation (WPF) and Silverlight developers who are creating Windows Store apps. This first one is more theoretical, whereas the second is more practically oriented. In this first article, I explain some of the new features in Windows Runtime andthe most common differences you’ll encounter when transitioning to Windows Store app development, coming from a world of either Windows Phone 7, WPF/Silverlight or even traditional .NET development. (For a comprehensive list of changes, see the .NET for Windows Store apps overview.)

I assume you’re familiar with XAML and other concepts from a WPF/Silverlight environment, such as Windows Phone 7.

XAML

When you’re porting a WPF or Silverlight application to a Windows Store app, most differences you encounter regarding XAML and related concepts might not seem like a big deal. Still, they are worth mentioning because they can be annoying and you must often find a workaround. One minor difference is the importing of namespaces in XAML, which has a using keyword instead of the clr-namspace keyword.

xmlns:converters="using:MyCompany.MyWindowsStoreApp.Converters"

A bigger difference is that references to static members of a type—for example, enumeration values—aren’t supported in XAML because the x:Static markup extension is missing. I noticed the absence of the static markup extension when I was adding localization support to an app because I normally use that method for referencing static properties generated from resource files. Windows Store apps use resource files containing string resources with resw instead of resx as the file extension. The XML structure in the files is identical, so you can simply rename existing resx files to resw. For resw files, however, there is no automatic code generation to a corresponding class with static properties, for convenient and refactoring safe access in code. For these resources, you need to reference the resource key from XAML by using the x:Uid markup extension on elements that need to be localized.

<TextBlock x:Uid="ViewAppTitle" Style="{StaticResource PageSubheaderTextStyle}" />

In code, however, it’s much more convenient to access static properties, as in standard .NET development, rather than have to manually call GetString on a ResourceLoader object, passing in the resource key as a string argument. I prefer using T4 for this, creating a simple template that generates the code.

Silverlight had another localization technique, one that used bindings to a collection of localized strings. You can also convert this technique to the technique with x:Uid markup extension on elements and resw files for resources.

Another commonly used markup extension that I miss is the x:DataType for associating data templates with specific types. For me, the workaround is to use a DataTemplateSelector, for example, through the ItemTemplateSelector property in ItemsControl.

<ListViewItemTemplateSelector="{StaticResourceVehicleTypeItemTemplateSelector}" />

Windows Runtime doesn’t support behaviors, a convenient feature that the Expression Blend 3 SDK introduced for WPF and Silverlight some time ago. However, I did find a project on CodePlex, also available as a NuGet package, that implements the behavior functionality for Windows Runtime based on attached dependency properties. This workaround made it quite straightforward to convert many of my existing behaviors for Windows Runtime.

Data Bindings

The binding mechanism in Windows Runtime lacks some convenient and, to me, much needed features from WPF and later versions of Silverlight. The UpdateSourceTrigger for PropertyChanged is unavailable, but I found a workaround by implementing a custom behavior, utilizing the WinRtBehaviors project on CodePlex. For searching up the visual tree for a specified type, I sometimes create bindings that rely on RelativeSource together with FindAncestor. Windows Runtime doesn’t support this method of data binding.

Another member I miss is the convenient StringFormat property on Binding, but I can easily implement a custom converter through the IValueConverter interface to support custom formatting. Because I always use the Model-View-ViewModel (MVVM) pattern, I can often convert the bound value directly in the view model. Forcing a manual update of the Binding from source to target isn’t possible because a BindingExpression class (or any similar class) isn’t available. Another minor difference that has caused some compilation errors when I’m converting a Windows Phone 7 app is that the Binding constructor takes no source path as parameter; instead, the Path has to be set explicitly to a PropertyPath object.

I always think about virtualization when I’m performing data bindings to collections of any sort. There is UI virtualization of the item containers and then data virtualization, either random access or incremental. In Windows Runtime, virtualization is turned off in certain scenarios related to the size of the viewport—that is, the area of ItemsControl that displays content. For items outside the viewport to be virtualized, you need to ensure that the size of the viewport is restricted, either by the control itself or by its parent container.

You can also turn off virtualization when the size of each item is unknown. You must specify the size at the root element in the data template or in the style for the item containers. Utilizing different data templates through a data template selector also breaks virtualization. The framework can no longer cache data templates when a data template selector is used because it doesn’t know what type of template is needed until the data template selector executes.

Animations

Animation support in Windows Runtime is easier and more standardized. For example, UIElements have a Transitions property, Panels have a ChildrenTransitions property and ItemsControl have an ItemContainerTransitions property in which you can easily add animated transitions. Adding an EntranceThemeTransition, one of many available, causes the element to swiftly slide into view rather than just appear when first rendered. A Transition object represents a visual behavior that occurs when a control is affected by a predefined action or state change.

<ItemsControl>
  <ItemsControl.ItemContainerTransitions>
    <TransitionCollection>
      <AddDeleteThemeTransition />
    </TransitionCollection>
  </ItemsControl.ItemContainerTransitions>
</ItemsControl>

Theme animations enable more control over the timing and order of animation effects than transition animations do, while still using a consistent Windows theme for how the animation behaves. Theme animations also take less code than custom animations—for example, using FadeOutThemeAnimation to make an element fade out of view.

When theme animations aren’t enough for your app’s needs, you can create custom animations. Custom animations can be either independent or dependent. Independent animations affect properties that don’t affect the rest of the objects in a scene, and they run on the composition thread rather than the UI thread. Dependent animations affect layout and can’t be calculated without extra input from the UI thread. Dependent animations don’t run by default; you need to enable them explicitly by using the EnableDependentAnimation property. When enabled, dependent animations run smoothly if the UI thread remains unblocked; but if the framework or app is doing a lot of other work, their performance might be impacted.

Application Data and I/O

The ApplicationData class provides access to the app data store. Application data consists of files and settings that are local, roaming or temporary. A local data store means that persistent data exists only on the current device; a roaming data store means that the data exists on all devices on which the user has installed the app; a temporary data store indicates data that the system can remove at any time, for example, by the system maintenance task or manually by a user through the Disk Cleanup tool.

The ApplicationData class contains a number of useful members for accessing the various data stores.

  • Current Provides access to the app data store associated with the application’s app package.
  • LocalFolder Gets the root folder in the local app data store.
  • LocalSettings Gets the application settings container in the local app data store.
  • RoamingFolder Gets the root folder in the roaming app data store.
  • RoamingSettings Gets the application settings container in the roaming app data store.
  • RoamingStorageQuota Gets the maximum size of the data that can be synchronized to the cloud from the roaming app data store.
  • TemporaryFolder Gets the root folder in the temporary app data store.
  • Version Gets the version number of the application data in the app data store.

An application’s app package can also include files that can be accessed by using the Windows.ApplicationModel.Package.Current.InstalledLocation property as well as by using the ms-appx: scheme in a URI, so that UI markup can refer to app package resources.

I’m used to working with Directory/DirectoryInfo and File/FileInfo classes, but Windows Runtime introduces the concept of StorageFolder and StorageFile. To my delight, many of the I/O operations that can be performed are now asynchronous and fit well into the async/await pattern, introduced with the Async CTP library and now part of .NET Framework 4.5. With the new async and await keywords, I can write asynchronous code that looks similar to synchronous code. This programming model is now supported and widely used among methods in the WinRT API.

var documents = await KnownFolders.DocumentsLibrary.GetFilesAsync();

A number of new stream classes and interfaces are available in Windows Runtime. For example, you can call any of the Open methods on StorageFile to return a stream object as an interface, such as IInputStream or IRandomAccessStream. You can then attach a DataReader or DataWriter object to this stream for reading or writing.

var document = awaitKnownFolders.DocumentsLibrary.GetFileAsync("ReadMe.txt");
using (var stream = await document.OpenReadAsync()) { ... }

Through extension methods that target different I/O types, you can create a traditional .NET Stream object for backward compatibility with existing classes expecting a .NET Stream as an argument, such as for reading and writing XML files. Some new classes replace the traditional .NET Socket class. For example, StreamSocket supports network communication using a Transmission Control Protocol (TCP) stream socket, and DatagramSocket supports network communication using a User Datagram Protocol (UDP) datagram socket.

Specific WinRT Controls

Because I have a background in Windows Phone 7 development, I’m familiar with many of the WinRT controls. The Panorama and Pivot controls aren’t part of Windows Runtime, however, because they were designed mainly for the phone form factor and to help users navigate areas larger than the phone screen. The WinRT controls I use most often are GridView and ListView because they work on either full screen or snapped views and they can both handle grouped data.

The new FlipView control is convenient for providing a simple paging experience, such as flipping among the photos in a photo collection such as the built-in Photos app. I also like ToggleSwitch, with its Header, OnContent and OffContent properties. The IsOn property is what I normally expect from an IsChecked property.

<ToggleSwitchIsOn="{Binding IsPowerOn, Mode=TwoWay}"
 Header="Powers on/off the device" OnContent="Power On" OffContent="Power Off" />

The new WebView control replaces the WebBrowser control from WPF and Silverlight. WebView’s navigation-related events consist of an event for load completed and one for navigation failed. There is also an event, ScriptNotify, that occurs when the content contained in the WebView control passes a string to the application by using JavaScript. ScriptNotify can be useful when the Web page performs the navigation via DOM, but potentially notifying the host app via script first.

 I haven’t found a direct way to retrieve the HTML content in a WebView as I can in a WebBrowser control. If the hosted Web page is under my control, I might be able to add some custom JavaScript code that can access the HTML content.

I often use the WebView control in authentication scenarios, using OAuth to get an access token for the user logging in. Windows Runtime has a dedicated API, in the form of the WebAuthenticationBroker class, that handles these scenarios. WebAuthenticationBroker removes the need to host a WebView control that is used only for presenting a user interface for authentication. WebAuthenticationBroker is more suitable for MVVM scenarios, in a ViewModel, because it isn’t a graphical control like WebView. Unfortunately, WebAuthenticationBroker didn’t meet my requirements for authentication against Facebook and I ended up using WebView instead.

I like the AppBar better in Windows Runtime because it’s much more general than in Windows Phone 7 and now accepts any control as a child—for example, a Button with content. AppBar supports contextual commands and can be programmatically set to show up when an item has been selected, without changing views. The documentation states that if you have 10 or fewer app bar commands, your bar automatically hides labels and adjusts padding so that those commands still fit in snapped or portrait orientation. In the current release, this isn’t supported: you’re expected to implement this behavior for the AppBar yourself. The WinJS version of the AppBar control does support this behavior.

Windows Store App Concepts

For the application to feel alive, such that data the user inputs is always present and data from online services is updated so it’s always fresh, even when it has been suspended or terminated because of an application switch or energy save, three events are important to understand: Activated, Suspending and Resuming. The Activated event occurs when the application transitions from not running to running. This transition happens, for example, if the application has never been started, if the user has manually closed the application or if Windows terminated the application to save resources and energy—and then the user restarts the app. The Activated event arguments contain a PreviousExecutionState property with information about the state of the application before it was activated. When the previous state is Terminated, any previously stored session data and state must be restored. When the previous state is either ClosedByUser or NotRunning, the expected behavior is to start the application with default data and state.

The Suspending event occurs when the application transitions from running to suspended, for example, when the application switches out of the foreground. Any session data should be saved within five seconds. The Resuming event occurs when the application transitions from suspended to running. Because application state is still kept in memory, the previously suspended data doesn’t need to be restored. To keep the app current, however, you might need to update certain data, such as weather information.

When you’re providing a trial version of an app or utilizing in-app purchases to unlock features, for example, you need to arrange for licensing. You can obtain license information from the LicenseInformation property of the CurrentAppSimulator object during testing or from the LicenseInformation property of the CurrentApp object when distributed through the Windows Store.

I sometimes rely on the ICloneable interface for cloning objects, but Windows Runtime doesn’t include that interface. Instead, you must declare a custom method, preferably through a common interface. This isn’t a big concern, however, because I think complementing the ICloneable interface from the .NET Framework with a generic variant has always been a good practice. Still, I wish an ICloneable<T> interface had been included in Windows Runtime as a standardized and type-safe way to clone.

Reflection is another concept that is useful in specific scenarios for writing generic code, even if my need for it in Windows Store apps has been minimal. The first time I used WinRT reflection, however, I noticed that many members from the Type class have been moved to a separate TypeInfo class, and some have been renamed. You can retrieve the TypeInfo through an extension method on Type by including the System.Reflection namespace.

var typeInfo = typeof(DateTime).GetTypeInfo();
var propertyInfo = typeInfo.GetDeclaredProperty("DayOfWeek");

I couldn’t find the Managed Extensibility Framework (MEF) until I learned that it had been moved from the WinRT framework into a separate NuGet package, perhaps for a faster release cycle. To install MEF for a project, I simply chose Manage NuGet Packages from the Project menu and then searched online for MEF for Web and Windows Store apps.

I was also a little surprised to see that the WriteableBitmap class no longer has a Pixels property. Instead, there is a PixelBuffer property of type Windows.Storage.Streams.IBuffer that has only two properties, Capacity and Length. An extension method, AsStream, is included in the WindowsRuntimeBufferExtensions class. Make sure to include the System.Runtime.InteropServices.WindowsRuntime namespace so that the extension method, which returns the stream, is available to represent the same memory that the specified IBuffer interface represents. You can then read the bytes from this stream. Keep in mind, however, that you’re now working on the bytes directly—that is, the byte array is four times larger than the integer array returned from the Pixels property because it now contains separate values for BGRA, in that order.

using (var pixelStream = writeableBitmap.PixelBuffer.AsStream()) { ... }

Another difference regarding code specific to design time is that the DesignerProperties.GetIsInDesignMode method has been replaced with DesignMode.DesignModeEnabled. With DesignMode.DesignModeEnabled, you can write conditional code (for example, code that can’t be executed) to make a control design-friendly.

Conclusion

In this article, you have seen some of the differences and new concepts I encountered while developing my first Windows Store apps. Many of the differences in Windows Runtime, such as a completely new file/folder API as well as the transition to asynchronous rather than synchronous operations, are welcome. Some other features I’m used to relying on, such as behaviors and more advanced binding functionality, aren’t currently in the framework, probably because of time constraints and the focus on simplicity for the first release of Windows Runtime.

I tried to cover as much ground as possible, everything from simple changes in XAML to more general differences compared to the .NET Framework as a whole. My goal was to explain the new ways or workarounds I discovered to accomplish the same things traditionally done in a certain way in WPF/Silverlight or Windows Phone 7.

My second article will focus more on practical issues. You’ll see how to get started quickly with Windows Store app development, and I’ll recommend frameworks and patterns that will provide you with a good architectural setup. So stay tuned.

Read Part 2 of this article


Joel Fjordén works as a senior .NET developer and architect for Cenito Software in Malmö, Sweden. His area of expertise is application development targeting WPF/Silverlight, Windows Phone 7 and recently Windows 8 in the form of Windows Store apps. Currently Joel works mainly as a developer, but he is also involved as a mentor, an architect and an instructor in various .NET-related courses.

A special thanks goes to the following contributors for their technical review of this article: Wolf Schmidt and Jim Walker
Wolf Schmidt is an SDK writer for many of the Microsoft frameworks and technologies that incorporate XAML, including WPF, Silverlight and Windows Runtime. He focuses on each platform’s architecture and fundamentals for developers, as well as documenting the XAML language.
Jim Walker has been an SDK writer for the past six years covering WPF, Silverlight and now Windows Runtime, with a focus on XAML controls, text and layout.