What Is a Universal Windows Platform (UWP) App?

The concept of a common application architecture was first introduced in Windows 8 as the Windows Runtime. Windows Runtime (WinRT) was an evolution of the Windows app model, intended to be a common application architecture. When Windows Phone 8.1 became available, the Windows Runtime was aligned between Windows Phone 8.1 and Windows. This enabled developers to create Universal Windows 8 apps that target both Windows and Windows Phone, using a shared codebase. This article introduces you to the Universal Windows Platform.

Introduction

Windows 10 introduces the Universal Windows Platform (UWP), which further evolves the Windows Runtime model and brings it to the Windows 10 unified core. As part of the core, the Universal Windows Platform now provides a common app platform available on every device that runs Windows 10.

Apps that target the Universal Windows Platform can call not only the WinRT APIs that are common to all devices but also APIs (including Win32 and .NET APIs) that are specific to the device family the app is running on.

The Universal Windows Platform provides a guaranteed core API layer across devices. This means you can create a single app package that can be installed on a wide range of devices.

1. Device Families

Windows 8.1 and Windows Phone 8.1 apps target an operating system (OS), Windows or Windows Phone. With Windows 10, an app no longer targets an operating system. Instead, an app targets one or more device families.

A device family identifies the APIs, system characteristics, and behaviors that you can expect across devices within the device family. It also determines the set of devices on which your app can be installed from the Store.

The decision which device family (or families) your app will target determines:

  • the set of APIs that your app can assume to be present when it runs.
  • the set of API calls that are safe only inside conditional statements. To isolate sections of code that are platform-specific, use the #ifdef directive.
  • the set of devices on which your app can be installed from the Store.

Here are some considerations to help you decide which device family to target:

  • Target the universal device family to reach the maximum range of devices.
  • Choose to target your app at one of the child families if it is specialized for, for example, a desktop PC or Xbox.
  • Target two (or more) child device families instead of targeting the universal device family.
  • In some cases, you may want your app to run everywhere except on devices with a particular version of a particular device family.

By default, Microsoft Visual Studio specifies Windows.Universal as the target device family in the app package manifest. To specify the device families for your app, manually configure the TargetDeviceFamily element in the Package.appxmanifest file.

2. User Interface and Universal Input

Windows helps you target your user interface to multiple devices with the following features:

Universal Controls and Layout Panels

Windows 10 includes new controls, such as the calendar and split view. Controls have been updated to work well on larger screens, adapt themselves based on the device’s screen resolution, and work well with multiple input types, such as keyboard, mouse, touch, pen, and controllers, such as the Xbox controller.

To help you adapt the user interface of an app based on the amount of available screen space, Windows 10 introduces adaptive panels and design states.

The new RelativePanel implements a style of layout that is defined by the relationships between its child elements. It is intended for use in creating app layouts that can adapt to changes in screen resolution.

Visual State Triggers

Your app’s user interface may need to adapt to changes in window size. Adaptive visual states allow you to change the visual state in response to changes in the size of the window.

State triggers define a threshold at which a visual state is activated, which then sets layout properties appropriate for the window size that triggered the state change. Here is the XAML for the visual state triggers described above.

Windows 10 introduces an evolution of the existing scaling model. In addition to scaling vector content, there is a unified set of scale factors that provides a consistent size for user interface elements across a variety of screen sizes and display resolutions.

You can build a universal Windows app using universal controls that handle various inputs, such as a mouse, keyboard, touch, pen, and controller (such as the Xbox controller).

3. Writing Code

Your programming language options for your Windows 10 project in Visual Studio include Visual C++, C#, Visual Basic, and JavaScript. For C# and Visual Basic, you can use XAML for a full-fidelity, native user interface experience.

For Visual C++, you can choose to draw with either or use XAML. For JavaScript, your presentation layer will be HTML. Let’s look at these different cases.

Whenever you want to call an API, you’ll need to know whether the API is implemented by the device family that your app is targeting. If you want to call just a small number of APIs, you could use the ApiInformation.IsTypePresent method like this.

A UWP app or Windows Runtime Component is written in C++/CX has access to the Win32 APIs that are part of the UWP. These Win32 APIs are implemented by all Windows 10 device families. Windowsapp.lib is an umbrella lib that provides the exports for the UWP APIs. Linking to Windowsapp.lib will add to your app dependencies on DLLs that are present on all Windows 10 device families.

4. User Experience

A UWP app allows you to take advantage of the unique capabilities of the device on which it is running. It provides a set of built-in features and universal building blocks that make it much easier to create a great user experience for multiple devices.

You can still have one app package that runs on all devices by checking what device family your app is running on before calling an extension API. Here are some of the features that you get when you create a UWP app:

  • When your app runs on a Windows-powered device, the system uses an algorithm to normalize the way controls, fonts, and other UI elements display on the screen. This scaling algorithm takes into account viewing distance and screen density to optimize for perceived size.
  • Although you can design for specific input devices, apps use an input system that uses “smart” interactions. That means that you can design around a click interaction without having to know whether the click comes from an actual mouse click or the tap of a finger.
  • The UWP provides a set of universal controls that are guaranteed to work well on all Windows-powered devices. These controls are input-aware and deploy with the proper set of input affordances, event states, and overall functionality for each device family.
  • Your UWP app automatically gets a default set of styles which can be customized to give your app a personal touch, or can be replaced completely to create a unique visual experience.

Conclusion

Here are some of the characteristics that make UWP apps on Windows 10 different:

  • You target device families, not an OS. A device family identifies the APIs, system characteristics, and behaviors that you can expect across devices within the device family. It also determines the set of devices on which your app can be installed from the store.
  • All UWP apps are distributed as a .appx package, providing a trustworthy installation mechanism and ensures that the apps can be deployed and updated seamlessly.
  • There’s one store for all devices. You can submit and manage all your apps for Windows devices in one place.
  • The UWP core APIs are the same for all Windows device families. App using only the core APIs will run on any Windows 10 device.
  • Extension SDKs are specialized APIs for each device family, which can be used if the app is intended for a particular device family.
  • UI elements use effective pixels, so they automatically adapt themselves based on the number of screen pixels available on the device.

How to Build a Gauge Control for Universal Windows App

In this tutorial I will show you how to build a Gauge Control for your Universal Windows App. This is how it looks.

Here are the steps to building a custom Gauge control for your universal Windows app:

Step 1: Add Gauge class in the Shared Project

Add Gauge class to Controls folder in the Shared project. Replace the empty Gauge class with the following code.

Step 2: Add a Reference to Controls Directory in MainPage.xaml

Add a xmlns reference to Controls directory in MainPage.xaml.

Step 3: Add the Style for Gauge Control in Page Resources

Now add the style for Gauge control in <Page.Resources></Page.Resources>.

Instead of adding the Style in MainPage.xaml you could add the Style in SharedResources.xaml folder. Follow our tutorial on Shared theme resources to see how to use shared resources in universal Windows Apps.

Using Shared Theme Resources in Universal Windows Apps.

Step 4: Add the XAML for Gauge Control in the Page

Now simply use the Gauge control in your page.

Deploy the app to see if it works.

Feel free to download the source code for reference or clone it from Github.

Download full project Gauge.zip

Using Shared Theme Resources in Universal Windows Apps

Using Resource Dictionary to store reusable Styles and DataTemplates is a clean way of building an app. In Universal Windows Apps you can have shared Theme Resources which can be used in both Windows Phone and Windows project. To handle scenarios where some resources are platform specific and others are shared you could have two resource dictionaries.

  • SharedResources: For shared resources(In shared project)
  • PlatformSpecificThemes: For platform specific resources(In each of the platform specific projects using the same name)

The solution should something similar to the image shown below.

We will use the same name PlatformSpecificThemes in both the Windows Phone and Windows project for our platform specific resources. What the compiler will do for us is that it will automatically resolve the resource to be used in each of the projects. Anything contained in the “Shared” pseudo-project gets compiled individually into each platform-specific project.

Here are the steps to add shared theme resources in your app:

Step 1: Add a new Resource Dictionary in the Shared Project

Add a new Resource Dictionary named SharedResources.xaml in your Shared project. We have added this resource dictionary under Themes folder. This resource dictionary will contain resources which will be common for both the apps. Styles and Templates defined in this file cab be used on both Windows Phone and Windows.

Step 2: Add a new Resource Dictionary in each of the Platform Specific Projects

Next, we add a new Resource Dictionary file named PlatformSpecificThemes.xaml in each of the platform specific projects ie. Windows Phone and Windows. We keep the folder structure same for all the three projects. The platform specific resource file is kept under Themes folder in both the Windows Phone and Windows apps. You can refer to the project structure screenshot at the beginning of the tutorial.

Step 3: Define Resources in App.xaml

In the App.xaml file of the Shared project define the ResourceDictionary to be used by your projects.

From there, just put any XAML resources you need in the platform-specific PlatformSpecificThemes.xaml file and they will become available throughout your application. Any styles or other resources will work in the Visual Studio designer window and the new XAML static resource auto-completion will continue to work exactly as you’d expect.

The App.xaml file looks similar to this after defining the ResourceDictionary.

Note that ReSharper may continue to show an error but the project will build successfully.

This also makes it easier to share pages and user controls between platforms. You can reference platform-specific styles, DataTemplates, or any other static resource from shared pages/controls as long as a resource exists with the same name on each platform.

Using Platform Specific Resource in Shared Page.

Here’s an example with a shared page. The style MyTextBlockStyle sets the text color to red on Windows and green on Windows Phone. (By the way, you can switch between viewing within the context of Windows or Windows Phone by using the drop-down box.)

In the PlatformSpecificThemes.xaml for Windows Phone project add the following style.

In the PlatformSpecificThemes.xaml for Windows project add the following style.

In the MainPage.xaml add a TextBlock that uses MyTextBlockStyle.

When you deploy the solution on Windows you will see the text appear in red and when you run it on Windows Phone it will appear green.

Here’s how the page looks on Windows.

And here’s how the page looks on Windows Phone.

Using Shared Resource in Platform Specific Project

This is a more general scenario where resources defined in the shared project can be used in any of the platform specific projects. We define a SolidColorBrush named ThemeColor in our SharedResources.xaml file and we can then use it in any of the projects ie any XAML page in the shared project or in Windows Phone or Windows.

We add a BlankPage.xaml in each of the platform specific projects and add the following XAML code in both of them.

Here’s how the XAML is rendered on Windows Phone.

Here’s how it is rendered on Windows.

Notice the following,

  • Both the apps picked up ThemeColor resource from SharedResource.xaml
  • The apps picked up MyTextBlockStyle resource from their PlatformSpecificThemes.xaml

Please, feel free to download the source code for reference or clone it from Github.

Download project SharedThemeResources.zip

How to Display Local Toast in Universal Windows Apps

In this article I will show how to display local toast notifications in Universal Windows Apps. No backend is required to display local toasts. It can be triggered to show completion of some event or notify about some error in the task being executed.

Step 1: Setup the UI of your page to Trigger a Local Toast

We add a TextBox and Button on our page. On clicking the Button, TextBox’s Text will be displayed as a local Toast. We are keeping the MainPage.xaml in the Shared project itself as the UI for both Windows Phone and Windows app will be common for our sample project.

Step 2: Add a Toast Service class in the Shared project

We create a new ToastService class and add a static method ShowToastNotification which takes a string argument message to it.

This method is responsible for the following:

  • Set toast’s text to the message passed as argument
  • Set image source to some hardcoded value
  • Set toast’s duration. In our sample we are setting the duration to short.
  • Set toast’s navigation. This is the NavigationUri string which can be handled by the app to navigate to a particular page when the notification is tapped. Arguments can also be passed to it.
  • Create the toast notification based on the XML content you’ve specified.
  • Show the toast notification

Step 3: Add a Click event handler to trigger local toast

Add a click event handler for the Button to trigger a local toast to be displayed. In the code behind for the click event, the ShowToastNotification method is called with the TextBox’s text passed as an argument.

Here’s how the toast notification appears in the action center.

Feel free to download the full project’s source code or clone it from GitHub.

Download project LocalToast.zip

Application Data in Universal Windows Apps

Application data is state than an app manages within its app data folders. Local, Roaming and Temporary along with LocalCache are the different data folders for Windows Phone 8.1 apps. The existence of app data is tied to the existence of the app so that uninstalling the app deletes the app data from that device. Roaming app data persists in the cloud independently, and is shared between Windows and Windows Phone apps that share the same Package Family name in their manifests.
App data is preserved across app updates delivered by the Windows Store and Windows Phone Store. So app updates must be prepared to load app data that was generated by any previous version of the app.

Folders

Local and LocalCache folders are both intended for storing device-specific app data. The difference is that Local app data is included with Windows Phone 8.1 backups, whereas LocalCache and Temporary are not. The difference between LocalCache and Temporary is that the system can delete temporary app data at any time to free up storage resources, whereas LocalCache data is under the app’s control. The LocalFolder, RoamingFolder, and TemporaryFolder properties (and LocalCacheFolder on Windows Phone 8.1) each map to discrete folders within the app’s root app data folder, which is located in %localappdata%packages{app_package_family_name}.

The LocalFolder of the app data can be accessed as follows:

var localFolder = ApplicationData.Current.LocalFolder;

Instead of targeting LocalFolder you could also target RoamingFolder or TemporaryFolder.

Version Numbers

The version number that you set by using Windows.ApplicationData.SetVersionAsync is independent from the version number of the app as set in its manifest. Any number of app versions can share the same app data version. When an app update needs to change the structure of the app data, it should call SetVersionAsync and provide a callback method to handle migration of an older version of its state. Subsequent updates can then continue to use that same app data version until such time as another change is needed.

The version of your app data primarily determines how different versions of roaming state are managed in the cloud. OneDrive maintains the most recent copy of each version of roaming app data that is in use by those versions of the app that the user has installed.
The version start at zero and can be obtain by checking

var version = ApplicationData.Current.Version;

If the version is lower than the expected to some converting and set the version to the correct one

ApplicationData.Current.SetVersionAsync(1, SetVersionHandler);

Saving Data

Saving data to local storage works as before.

var localFolder = ApplicationData.Current.LocalFolder;
var localFile = await localFolder.CreateFileAsync("localFile.txt", CreationCollisionOption.ReplaceExisting);
var fileBytes = System.Text.Encoding.UTF8.GetBytes("some text string");
using (var s = await localFile.OpenStreamForWriteAsync())
{
    s.Write(fileBytes, 0, fileBytes.Length);
}

Instead of targeting LocalFolder you could also target RoamingFolder or TemporaryFolder.

Another function which is very useful is the FileIO.WriteTextAsync. This makes it very easy to write text to files.

var tempFolder = ApplicationData.Current.TemporaryFolder;
var tempFile = await roamingFolder.CreateFileAsync("tempFile.txt", CreationCollisionOption.ReplaceExisting);
await FileIO.WriteTextAsync(tempFile, "some text string");

TemporaryFolder

This is the place where you can save data without thinking of have to remove it later. TemporaryFolder can be used for example for sharing data between several views when you for some reason don´t want to keep the data in memory. You can save images to the temporary folder for use in your views if you don´t want to persist them in your local folder. From XAML you can target the TemporaryFolder by using ms-appdata:///temp/.

RoamingFolder

If you save data to the RoamingFolder the data is available on every device the app is installed. If you want to find out when roaming data has been changed by someone else you need to listen to DataChanged. This fires if roaming data is change by another app:

applicationData.DataChanged += DataChangedHandler;

private async void DataChangedHandler(ApplicationData appData, object o)
{
    // Add code
}

RoamingStorageQuota

By calling RoamingStorageQuota you get the amount of data possible to roam. If you try to roam more data than RoamingStorageQuota specifies the system stop replication the data until it below the limit again. The normal amount of data possible to roam is 100kb.

var quota = applicationData.RoamingStorageQuota;

Settings

Instead of targeting LocalStorage it is possible to target LocalSettings, there is also a RoamingSettings. This works the same as folders does, local saves locally and roaming saves to the cloud. Its quite easy to save settings.

var roamingSettings = ApplicationData.Current.RoamingSettings;
roamingSettings.Values["MySetting"] = "Hello World";

In addition to save text to a setting one can save a composite value. This is a setting which contains several settings:

var composite = new ApplicationDataCompositeValue();
composite[settingName1] = 1;
composite[settingName2] = "world";
roamingSettings.Values["MyCompositeSetting"] = composite;

It is also possible to create containers in the settings. This for making it easier to structure the settings. Example of a container:

var container = localSettings.CreateContainer("exampleContainer", ApplicationDataCreateDisposition.Always);
if (localSettings.Containers.ContainsKey("exampleContainer"))
{
    localSettings.Containers["MyContainer"].Values["MySetting"] = "Hello Windows";
}

Universal Windows App Project File Structure

All Universal Windows apps following MVVM pattern should have a similar directory structure. The following snapshot shows a possible project file structure of a Universal Windows app.

Let us see briefly what all things go into each folders.

  • App.xaml
  • Controls: Reusable UI controls (application independent views) without view models. Platform specific Controls are added directly to the specific project and Shared controls are added in the Shared Project.
  • Strings: Classes and resources for application localization
    • en-US: Separate directory for every supported language.
      • Resources.resw
  • Models: Model and domain classes
  • ViewModels: View models classes
    • MainWindowModel.cs
    • MyViewModel.cs
    • Dialogs
      • SelectItemDialogModel.cs
  • Converters: This folder includes the Value Converters. Follow this article to see how Converters can be used in Windows apps.
  • Themes: It contains Theme Resources that is Resource Dictionary. Platform specific resources are added directly to the specific project and Shared resources are added in the Shared Project.
  • Services: This could include classes for web service calls, navigation service etc.
  • Utils: It includes all utility functions that would be used across the app. This may include AppCache, FileUtils, Constants, NetworkAvailability, GeoLocation, DataTemplateSelector etc.
  • Views: Contains the views. Platform specific Views are added directly to the specific project and Shared Views are added in the Shared Project.
    • MainWindow.xaml
    • MyView.xaml
    • Dialogs
      • SelectItemDialog.xaml

As shown in the list, the name of a view should end with its type:

  • Window: A non-modal window
  • Dialog: A (modal) dialog window
  • Page: A page view (mostly used in Windows Phone and Windows Store apps)
  • View: A view which is used as subview in another view, page, window or dialog

The name of a view model should be composed of the corresponding view’s name and the word “Model”. The view models are stored in the same location in the ViewModels directory as their corresponding views in the Views directory.

Universal Windows App Project Setup

This tutorial is a part of the series on Building a Universal Windows app using MVVM pattern. In this tutorial we will setup a new project for building a Universal Windows app.

Setting up the Project

In Visual Studio click on New Project and choose Blank App (Universal Windows 8.1) from the existing Templates. If you are unable to find this template in your Installed templates list then head over to the following link to download the latest SDK for Windows Phone.

https://dev.windows.com/en-us/develop/download-phone-sdk

Structure of Universal Windows app

When you first open up the Solution, the project structure looks something like this.

Each of the platform specific projects contain an Assets folder and a MainPage.xaml file. The shared project contains the App.xaml file which is shared by both the Windows 8.1 and Windows Phone 8.1 apps. The Windows and Windows Phone projects are platform projects and are responsible for creating the application packages (.appx), targeting the respective platforms. The shared project is a container for code that runs on both platforms. They don’t have a binary output, but their contents are imported by the platform projects and used as part of the build process to generate the app packages (.appx).

Switching between Startup projects

To set the startup project, right-click on the project node in the Solution Explorer and choose the option Set as Startup Project. You can quickly switch the startup project from the Debug target drop-down that now enumerates all the possible projects in the solution. The project that you choose is shown in bold in the Solution Explorer. The available debug targets change when switching startup projects.

  • When the Windows project is the startup project, the Debug target drop-down displays options for the Windows Simulator or Local Machine.
  • When the Windows Phone project is the startup project, the drop-down displays options for Device as well as various emulators.

Switch context in Code Editor

When writing code in a shared project, you can use the project context switcher in the navigation bar to select the platform you are actively targeting, which in turn customizes the IntelliSense experience in the code editor.

Cross-Platform Code in Shared Project

In the shared project, you typically write code that is common to both platforms. To isolate sections of code that are platform-specific, use the #ifdef directive. The constants WINDOWS_APP and WINDOWS_PHONE_APP are predefined for you.

We are done setting up our project and getting familiar with a few handy features of Visual Studio while building a Universal app. You could reference the following article to create your first universal Windows app.

Creating Your First Universal Windows App

Series Introduction: Building a Universal Windows app using MVVM pattern

I am starting a new series to help you get started with Universal Windows app development. If you take care of a few things then you could save a lot of time while building a Universal app. Almost all the code can be shared and only the UI needs to be built separately. Even the UI can be shared. In this series I will touching upon a lot of small things that can be used while building the app.

We will be following MVVM design pattern as much as possible. I will strive to have zero code behind and all the code in ViewModel itself. Getting started with MVVM has a bit of learning curve involved but I think it’s best to follow MVVM while building a universal Windows app. I will keep updating this article with link to other parts of the series as I cover them.

Universal Windows App Project Setup

Universal Windows App Project File Structure

How to Check for Network Availability in Universal Windows apps

Application Data in Universal Windows Apps

How to Display Local Toast in Universal Windows Apps

Using Shared Theme Resources in Universal Windows Apps

How to Build a Gauge Control for Universal Windows App

How to Check for Network Availability in Universal Windows apps

If you are building a universal Windows app or an app for Windows Phone 8.1/Windows 8.1 then the following class can help you check for network availability.

Network Availability class

This is a singleton class, which means only a single instance of it will exist during the lifecycle of the app.

The method NetworkInformationOnNetworkStatusChanged gets called whenever the network status changes. This method in turn updates the IsNetworkAvailable property with the current network profile information.

Usage

Whenever you need to check if the network is available, simply use:

Wrap Grid with Variable Sized Items for Windows Phone 8.1

In this tutorial I will show you how to wrap variable sized ListView Items in Windows Phone 8.1. This is how our end product looks.

.wrap_grid

Here are the steps:

Step 1: Create a custom WrapGrid

Firstly we would be creating a custom WrapGrid by overriding MeasureOverride and ArrangeOverride methods of Panel. So we have added a new class WrapPanel in our project under Controls folder.
controls_folder

The WrapGrid class to be added is as follows.

Step 2: Define ItemsPanelTemplate

We will be defining the ItemsPanelTemplate for the ListView to be used. Define this as local resources.

Step 3: Define DataTemplate for the ListView

Next we arbitrarily define a DataTemplate for the ListView which we are using. Define this as local resources.

Step 4: Define ListView Style

For our convenience and for allowing reusability we will be defining a Style for our ListView as local resource.

Step 5: Add a ListView in MainPage.xaml

Next, we add a ListView in our MainPage.

Step 6: Add a AddItems method to populate items.

We call this function in the OnNavigatedTo event handler to set the ItemSource of our ListView.

That’s it. Try running the app in the emulator and see the magic for yourself. Download the full source code for your reference.

Windows Phone 8.1/Windows 10 WinRT

Download full project Wrap Grid 8.1

Windows Phone 8.1 Silverlight

Code for implementing it in Windows Phone 8 is quite similar. You can grab the following project if you are working on Windows Phone 8 or Windows Phone 8.1 Silverlight.

Download full project Wrap Grid WP8