Windows 10 - UWP development | Windows 10 | Microsoft Visual Studio

November 8, 2017 | Author: Anonymous | Category: IDE
Share Embed


Short Description

Windows 10 - UWP development - Ebook download as PDF File (.pdf), Text File (.txt) or read book online. Manual que conti...

Description

Table of Contents Get started with Universal Windows Platform What's a UWP app? Guide to Universal Windows Platform apps Get set up Enable your device for development Sign up Your first app Create a "Hello, world" app (C#) Create a "Hello, world" app (JS) Create a "Hello, world" app (C++) A 2D UWP game in JavaScript A 3D UWP game in JavaScript A UWP game in MonoGame Plan your app What's next? Get UWP app samples Design & UI Layout Intro to app UI design Navigation basics Command basics Content basics Screen sizes and breakpoints Define page layouts with XAML Layout panels Alignment, margins, and padding Creating app layouts with Grid and StackPanel Style Color

Icons Motion Sound Typography Styling controls Controls and patterns Intro Index of controls by function App bar and command bar Auto-suggest box Buttons Check box Date and time Dialogs and flyouts Flip view Hub Hyperlinks Images and image brushes Inking controls Lists Master/details Media playback Menus and context menus Nav pane Progress Radio button Scrolling and panning controls Search Semantic zoom Slider Split view Tabs and pivot

Text Tiles, badges, and notifications Toggle Tooltip Web view Inputs and devices Input primer Device primer Usability Accessibility App settings Globalization and localization Guidelines for app help Microsoft Design Language Downloads Develop Windows apps App-to-app communication Share data Receive data Copy and paste Drag and drop Audio, video, and camera Camera Media playback Detect faces in images or videos Custom video effects Custom audio effects Media compositions and editing Audio device information properties Create, edit, and save bitmap images Transcode media files Process media files in the background

Audio graphs MIDI Import media from a device Camera-independent Flashlight Supported codecs Contacts and calendar Select contacts Send email Send an SMS message Manage appointments Connect your app to actions on a contact card Data access Entity framework Core with SQLite for C# apps SQLite databases Data binding Data binding overview Data binding in depth Sample data on the design surface, and for prototyping Bind hierarchical data and create a master/details view Debugging, testing, and performance Deploying and debugging UWP apps Testing and debugging tools for PLM Test with the Microsoft Emulator for Windows 10 Test Surface Hub apps using Visual Studio Beta testing Windows Device Portal Windows App Certification Kit Performance Version adaptive code Develop UWP education apps Take a Test API Devices, sensors, and power

Enable device capabilities Enable usermode access Enumerate devices Pair devices Point of service Sensors Bluetooth Printing and scanning 3D printing NFC Get battery information Enterprise Windows Information Protection (WIP) Enterprise shared storage Files, folders, and libraries Enumerate and query files and folders Create, write, and read a file Get file properties Open files and folders with a picker Save a file with a picker Accessing HomeGroup content Determining availability of Microsoft OneDrive files Files and folders in the Music, Pictures, and Videos libraries Track recently used files and folders Access the SD card File access permissions Games and DirectX Windows 10 game development guide Planning UWP programming DirectX programming Game porting guides

Game development videos Direct3D Graphics Learning Guide Coordinate systems and geometry Vertex and index buffers Devices Lighting Depth and stencil buffers Textures Graphics pipeline Views Compute pipeline Resources Streaming resources Appendices Graphics and animation Draw shapes Use brushes Animations overview Transforms overview Visual layer Hosted Web Apps Launching, resuming, and background tasks App lifecycle Launch an app with a URI Launch an app through file activation Reserved file and URI scheme names Auto-launching with AutoPlay Use app services Support your app with background tasks Connected apps and devices (Project "Rome") Splash screens Maps and location

Request authentication key Display maps Map control Display POI Display routes and directions Overlay tiled images Perform geocoding Get current location Design guidance for location-aware apps Set up a geofence Design guidance for geofencing Monetization, engagement, and Store services In-app purchases and trials Microsoft Store Services SDK Run app experiments with A/B testing Launch Feedback Hub from your app Configure your app for targeted push notifications Log custom events for Dev Center Display ads in your app Windows Store services Create a Retail Demo Experience (RDX) app Networking and web services Networking basics Which networking technology? Network communications in the background Sockets WebSockets HttpClient RSS/Atom feeds Background transfers Packaging apps Package a UWP app with Visual Studio

Manual app packaging Install apps with the WinAppDeployCmd.exe tool App capability declarations Set up automated builds for your UWP app Download and install package updates for your app Porting apps to Windows 10 Move from Windows Phone Silverlight to UWP Move from Windows Runtime 8.x to UWP Desktop to UWP Bridge Windows apps concept mapping for Android and iOS developers Move from iOS to UWP Hosted Web Apps Security Intro to secure Windows app development Authentication and user identity Cryptography Threading and async programming Asynchronous programming (UWP apps) Asynchronous programming in C++ (UWP apps) Best practices for using the thread pool Call asynchronous APIs in C# or Visual Basic Create a periodic work item Submit a work item to the thread pool Use a timer to submit a work item UWP on Xbox One Getting started What's new Xbox best practices Known issues FAQ Xbox One Developer Mode activation Tools

Development environment setup System resource allocation Introduction to multi-user applications Samples Bringing existing games to Xbox Disabling developer mode on Xbox One API reference Windows Runtime components Creating Windows Runtime components in C++ Walkthrough: Creating a basic Windows Runtime component in C++ and calling it from JavaScript or C# Creating Windows Runtime components in C# and Visual Basic Walkthrough: Creating a Simple Windows Runtime component and calling it from JavaScript Raising events in Windows Runtime components Brokered Windows Runtime components for side-loaded Windows Store apps XAML platform XAML overview Dependency properties overview Custom dependency properties Attached properties overview Custom attached properties Events and routed events overview API reference App development for Windows as a service Choose a UWP version Services What's new in Windows 10 for developers Prerelease APIs in Windows 10 preview builds What's new in Windows 10, version 1607 What's new in Windows 10, version 1607 Preview What's new in Windows 10, version 1511 What's new in Windows 10, version 1507

Windows 8.x guides Windows Phone Silverlight 8.x guides Publish Windows apps Using the Windows Dev Center dashboard Account types, locations, and fees Opening a developer account Managing your account settings and profile info How your app appears in the Store for Windows 10 customers Trademark and copyright protection Dev Center Insider Program Manage account users Set custom permissions for account users Create your app by reserving a name App submissions Set app pricing and availability Enter app properties Age ratings Upload app packages Create app Store listings Notes for certification The app certification process Package flights Gradual package rollout Beta testing and targeted distribution Distribute LOB apps to enterprises Add-on submissions Set your add-on product ID and product type Enter add-on properties Set add-on pricing and availability Create add-on Store listings Manage add-ons in bulk Monetize with ads

About affiliate ads App management and services Use map services View app identity details Manage app names Generate preinstall packages for OEMs Analytics Acquisitions report Add-on acquisitions report Installs report Usage report Health report Ratings report Reviews report Feedback report Channels and conversions report Ad mediation report Advertising performance report Affiliates performance report Promote your app report Download analytics reports Create customer groups Create customer segments App promotion and customer engagement Create an ad campaign for your app Create a custom app promotion campaign Send targeted push notifications to your app's customers Generate promotional codes Put apps and add-ons on sale Respond to customer feedback Respond to customer reviews App marketing guidelines

Link to your app Make your app easier to promote Getting paid Setting up your payout account and tax forms Payout thresholds, methods, and timeframes Payout summary Tax details for paid apps Understand IRS tax forms Mobile operator billing VAT info Store Policies and Code of Conduct Windows Store Policies App quality Developer Code of Conduct

What's a Universal Windows Platform (UWP) app? 3/7/2017 • 5 min to read • Edit on GitHub

The Universal Windows Platform (UWP) is the app platform for Windows 10. You can develop apps for UWP with just one API set, one app package, and one store to reach all Windows 10 devices – PC, tablet, phone, Xbox, HoloLens, Surface Hub and more. It’s easier to support a number of screen sizes, and also a variety of interaction models, whether it be touch, mouse and keyboard, a game controller, or a pen. At the core of UWP apps is the idea that users want their experiences to be mobile across ALL their devices, and they want to use whatever device is most convenient or productive for the task at hand. UWP is also flexible: you don't have to use C# and XAML if you don't want to. Do you like developing in Unity or MonoGame? Prefer JavaScript? Not a problem, use them all you want. Have a C++ desktop app that you want to extend with UWP features and sell in the store? That's okay, too. The bottom line: You can spend your time working with familiar programming languages, frameworks and APIs, all in single project, and have the very same code run on the huge range of Windows hardware that exists today. Once you've written your UWP app, you can then publish it to the store for the world to see.

So, what exactly is a UWP app? What makes a UWP app special? Here are some of the characteristics that make UWP apps on Windows 10 different. Apps target device families, not an OS A device family, like Xbox or PC, identifies the APIs, system characteristics, and behaviors that you can use in your app. Users with that kind of device can buy your app from the store. Apps are packaged using the .AppX packaging format and distributed from the Store. All UWP apps are distributed as an AppX package. This provides a trustworthy installation mechanism and ensures that your apps can be deployed and updated seamlessly. There's one store for all devices. After you register as an app developer, you can submit your app to the store and make it available on all device families, or only those you choose. You submit and manage all your apps for Windows devices in one place. There's a common API surface across device families. The Universal Windows Platform (UWP) core APIs are the same for all Windows device families. If your app uses only the core APIs, it will run on any Windows 10 device. Extension SDKs make your app light up on specialized devices. Extension SDKs add specialized APIs for each device family. If your app is intended for a particular device family, like HoloLens, you can add HoloLens features in addition to the normal UWP core APIs. Your app has

a single app package that runs on all devices, but you can check what device family your app is running on before calling an extension API for HoloLens. Apps support adaptive controls and input UI elements use effective pixels (see Responsive design 101 for UWP apps), so they can respond with a layout that works based on the number of screen pixels available on the device. And they work well with multiple types of input such as keyboard, mouse, touch, pen, and Xbox One controllers. If you need to further tailor your UI to a specific screen size or device, new layout panels and tooling help you adapt your UI to the devices your app may run on.

Use a language you already know UWP apps use the Windows Runtime, a native API built into the operating system. This API is implemented in C++ and supported in C#, Visual Basic, C++, and JavaScript. Some options for writing apps in UWP include: XAML UI and a C#, VB, or C++ backend DirectX UI and a C++ backend JavaScript and HTML Microsoft Visual Studio 2015 provides a UWP app template for each language that lets you create a single project for all devices. When your work is finished, you can produce an app package and submit it to the Windows Store from within Visual Studio to get your app out to customers on any Windows 10 device.

UWP apps come to life on Windows On Windows, your app can deliver relevant, real-time info to your users and keep them coming back for more. In the modern app economy, your app has to be engaging to stay at the front of your users’ lives. Windows provides you with lots of resources to help keep your users returning to your app: Live tiles and the lock screen show contextually relevant and timely info at a glance. Push notifications bring real-time, breaking alerts to your user’s attention when they're needed. The Action Center is a place where you can organize and display notifications and content that users need to take action on. Background execution and triggers bring your app to life just when the user needs it. Your app can use voice and Bluetooth LE devices to help users interact with the world around them. Finally, you can use roaming data and the Windows Credential Locker to enable a consistent roaming experience across all of the Windows screens where users run your app. Roaming data gives you an easy way to store a user’s preferences and settings in the cloud, without having to build your own sync infrastructure. And you can store user credentials in the Credential Locker, where security and reliability are the top priority.

Monetize your app On Windows, you can choose how you'll monetize your app—across phones, tablets, PCs, and other devices. We give you a number of ways to make money with your app and the services it delivers. All you need to do is choose the one that works best for you: A paid download is the simplest option. Just name your price. Trials let users try your app before buying it, providing easier discoverability and conversion than the more traditional "freemium" options. Use sale prices for apps and add-ons. In-app purchases and ads are also available.

Let's get started For a more detailed look at the UWP, read the Guide to Universal Windows Platform apps. Then, check out Get set up to download the tools you need to start creating apps.

More advanced topics .NET Native - What it means for Universal Windows Platform (UWP) developers Universal Windows apps in .NET .NET for UWP apps

Intro to the Universal Windows Platform 3/6/2017 • 19 min to read • Edit on GitHub

In this guide, you'll learn about the Universal Windows Platform (UWP) and Windows 10: What a device family is, and how to decide which one to target. New UI controls and panels for adapting your UI to different screen sizes or rotations. How to understand and control the API surface that is available to your app. Windows 10 introduces the Universal Windows Platform (UWP), which provides a common app platform available on every device that runs Windows 10. With this evolution, apps that target the UWP 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 UWP provides a guaranteed core API layer across devices. This means you can create a single app package that can be installed onto a wide range of devices. And, with that single app package, the Windows Store provides a unified distribution channel to reach all the device types your app can run on.

Because your UWP app runs on a wide variety of devices with different form factors and types of input, you want it to be tailored to each device and be able to unlock the unique capabilities of each device. Each device family has unique APIs, in addition to the guaranteed core API layer. You can write code to access those unique APIs conditionally so that your app lights up features specific to one type of device while presenting a different experience on other devices. Adaptive UI controls and new layout panels help you to tailor your UI across a broad range of screen resolutions.

Device families Windows 8.1 and Windows Phone 8.1 apps target an operating system (OS): either Windows, or Windows Phone. With Windows 10 you no longer target an operating system but you instead target your app to 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. Here is the device family hierarchy.

A device family is a set of APIs collected together and given a name and a version number. A device family is the foundation of an OS. PCs run the desktop OS, which is based on the desktop device family. Phones and tablets, etc., run the mobile OS, which is based on the mobile device family. And so on. The universal device family is special. It is not, directly, the foundation of any OS. Instead, the set of APIs in the universal device family is inherited by child device families. The universal device family APIs are thus guaranteed to be present in every OS and on every device. Each child device family adds its own APIs to the ones it inherits. The resulting union of APIs in a child device family is guaranteed to be present in the OS based on that device family, and on every device running that OS. One benefit of device families is that your app can run on any, or even all, of a variety of devices from phones, tablets, desktop computers, Surface Hubs, Xbox consoles, and HoloLens. Your app can also use adaptive code to dynamically detect and use features of a device that are outside of the universal device family. The decision about which device family (or families) your app will target is yours to make. And that decision impacts your app in these important ways. It determines: The set of APIs that your app can assume to be present when it runs (and can therefore call freely). The set of API calls that are safe only inside conditional statements. The set of devices on which your app can be installed from the Store (and consequently the form factors that you need to consider). There are two main consequences of making a device family choice: the API surface that can be called unconditionally by the app, and the number of devices the app can reach. These two factors involve tradeoffs and are inversely related. For example, a UWP app is an app that specifically targets the universal device family, and consequently is available to all devices. An app that targets the universal device family can assume the presence of only the APIs in the universal device family (because that's what it targets). Other APIs must be called conditionally. Also, such an app must have a highly adaptive UI and comprehensive input capabilities because it can run on a wide variety of devices. A Windows mobile app is an app that specifically targets the mobile device family, and is available to devices whose OS is based on the mobile device family (which includes phones, tablets, and similar devices). A mobile device family app can assume the presence of all APIs in the mobile device family, and its UI has to be moderately adaptive. An app that targets the IoT device family can be installed only on IoT devices and can assume the presence of all APIs in the IoT device family. That app can be very specialized in its UI and input capabilities because you know that it will run only on a specific type of device.

Here are some considerations to help you decide which device family to target: Maximizing your app's reach To reach the maximum range of devices with your app, and to have it run on as many kinds of devices as possible, your app will target the universal device family. By doing so, the app automatically targets every device family that's based on universal (in the diagram, all the children of universal). That means that the app runs on every OS based on those device families, and on all the devices that run those operating systems. The only APIs that are guaranteed to be available on all those devices is the set defined by the particular version of the universal device family that you target. (With this release, that version is always 10.0.x.0.) To find out how an app can call APIs outside of its target device family version, see Writing code later in this topic. Limiting your app to one kind of device You may not want your app to run on a wide range of devices; perhaps it's specialized for a desktop PC or for an Xbox console. In that case you can choose to target your app at one of the child device families. For example, if you target the desktop device family, the APIs guaranteed to be available to your app include the APIs inherited from the universal device family plus the APIs that are particular to the desktop device family. Limiting your app to a subset of all possible devices Instead of targeting the universal device family, or targeting one of the child device families, you can instead target two (or more) child device families. Targeting desktop and mobile might make sense for your app. Or desktop and HoloLens. Or desktop, Xbox and Surface Hub, and so on. Excluding support for a particular version of a device family In rare cases you may want your app to run everywhere except on devices with a particular version of a particular device family. For example, let's say your app targets version 10.0.x.0 of the universal device family. When the operating system version changes in the future, say to 10.0.x.2, at that point you can specify that your app runs everywhere except version 10.0.x.1 of Xbox by targeting your app to 10.0.x.0 of universal and 10.0.x.2 of Xbox. Your app will then be unavailable to the set of device family versions within Xbox 10.0.x.1 (inclusive) and earlier. By default, Microsoft Visual Studio specifies Windows.Universal as the target device family in the app package manifest file. To specify the device family or device families that your app is offered to from within the Store, manually configure the TargetDeviceFamily element in your Package.appxmanifest file.

UI and universal input A UWP app can run on many different kinds of devices that have different forms of input, screen resolutions, DPI density, and other unique characteristics. Windows 10 provides new universal controls, layout panels, and tooling

to help you adapt your UI to the devices your app may run on. For example, you can tailor the UI to take advantage of the difference in screen resolution when your app is running on a desktop computer versus on a mobile device. Some aspects of your app's UI will automatically adapt across devices. Controls such as buttons and sliders automatically adapt across device families and input modes. Your app's user-experience design, however, may need to adapt depending on the device the app is running on. For example, a photos app should adapt the UI when running on a small, hand-held device to ensure that usage is ideal for single-hand use. When the photos app is running on a desktop computer, the UI should adapt to take advantage of the additional screen space. Windows helps you target your UI to multiple devices with the following features: Universal controls and layout panels help you to optimize your UI for the screen resolution of the device Common input handling allows you to receive input through touch, a pen, a mouse, or a keyboard, or a controller such as a Microsoft Xbox controller Tooling helps you to design UI that can adapt to different screen resolutions Adaptive scaling adjusts to resolution and DPI differences across devices Universal controls and layout panels

Windows 10 includes new controls such as the calendar and split view. The pivot control, which was previously available only for Windows Phone, is also now available for the universal device family. Controls have been updated to work well on larger screens, adapt themselves based on the number of screen pixels available on the device, and work well with multiple types of input such as keyboard, mouse, touch, pen, and controllers such as the Xbox controller. You may find that you need to adapt your overall UI layout based on the screen resolution of the device your app will be running on. For example, a communication app running on the desktop may include a picture-in-picture of the caller and controls well suited to mouse input:

However, when the app runs on a phone, because there is less screen real-estate to work with, your app may eliminate the picture-in-picture view and make the call button larger to facilitate one-handed operation:

To help you adapt your overall UI layout based on the amount of available screen space, Windows 10 introduces adaptive panels and design states. Design adaptive UI with adaptive panels

Layout panels give sizes and positions to their children, depending on available space. For example, StackPanel orders its children sequentially (horizontally or vertically). Grid is like a CSS grid that places its children into cells. The new RelativePanel implements a style of layout that is defined by the relationships between its child elements. It's intended for use in creating app layouts that can adapt to changes in screen resolution. The RelativePanel eases the process of rearranging elements by defining relationships between elements, which allows you to build more dynamic UI without using nested layouts. In the following example, blueButton will appear to the right of textBox1 regardless of changes in orientation or layout, and orangeButton will appear immediately below, and aligned with, blueButton—even as the width of textBox1 changes as text is typed into it. It would previously have required rows and columns in a Grid to achieve this effect, but now it can be done using far less markup.



Use visual state triggers to build UI that can adapt to available screen space

Your UI may need to adapt to changes in window size. Adaptive visual states allows you to change the visual state in response to changes in the size of the window. StateTriggers define a threshold at which a visual state is activated, which then sets layout properties as appropriate for the window size that triggered the state change. In the following example, when the window size is 720 pixels or more in width, the visual state named wideView is triggered, which then arranges the Best-rated games panel to appear to the right of, and aligned with the top of, the Top free games panel.

When the window is less than 720 pixels, the narrowView visual state is triggered because the wideView trigger is no longer satisfied and so no longer in effect. The narrowView visual state positions the Best-rated games panel below, and aligned with the left of, the Top paid games panel:

Here is the XAML for the visual state triggers described above. The definition of the panels, alluded to by " ... " below, has been removed for brevity. ...

Tooling

By default, you'll probably want to target the broadest possible device family. When you're ready to see how your

app looks and lays out on a particular device, use the device preview toolbar in Visual Studio to preview your UI on a small or medium mobile device, on a PC, or on a large TV screen. That way you can tailor and test your adaptive visual states:

You don’t have to make a decision up front about every device type that you'll support. You can add an additional device size to your project later. Adaptive scaling

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 UI elements across a variety of screen sizes and display resolutions. The scale factors are also compatible with the scale factors of other operating systems such as iOS and Android. This makes it easier to share assets between these platforms. The Store picks the assets to download based in part of the DPI of the device. Only the assets that best match the device are downloaded. Common input handling

You can build a Universal Windows app using universal controls that handle various inputs such as mouse, keyboard, touch, pen, and controller (such as the Xbox controller). Traditionally, inking has been associated only with pen input, but with Windows 10, you can ink with touch on some devices, and with any pointer input. Inking is supported on many devices (including mobile devices) and can easily be incorporated with a just few lines of code. The following APIs provide access to input: CoreIndependentInputSource is a new API that allows you to consume raw input on the main thread or a background thread. PointerPoint unifies raw touch, mouse, and pen data into a single, consistent set of interfaces and events that can be consumed on the main thread or background thread by using CoreInput. PointerDevice is a device API that supports querying device capabilities so that you can determine what kinds of input are available on the device. The new InkCanvas XAML control and InkPresenter Windows Runtime APIs allow you to access ink stroke data.

Writing code Your programming language options for your Windows 10 project in Visual Studio include Visual C++, C#, Visual Basic, and JavaScript. For Visual C++, C#, and Visual Basic, you can use XAML for a full-fidelity, native UI experience. For Visual C++ you can choose to draw with DirectX either instead of or as well as using XAML. For JavaScript, your presentation layer will be HTML, and HTML is of course a cross-platform web standard. Much of your code and UI will be universal and it will run the same way everywhere. But for code tailored to particular device families, and for UI tailored to particular form factors, you'll have the option to use adaptive code and adaptive UI. Let's look at these different cases. Calling an API that's implemented by your target device family 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 in doubt, you can look it up in the API reference documentation. If you open the relevant topic and look at the Requirements section, you'll see what the implementing device family is. Let's say that your app is targeting version 10.0.x.0 of the universal device family and you want to call members of the Windows.UI.Core.SystemNavigationManager class. In this example, the device family is "Universal". It's a good idea to further confirm that the class members that you want to call are also within your target, and in this case they are. So in this example, you now know that the APIs are guaranteed to be present on every device that your app can be installed on, and you can call the APIs in your code just like you normally would. Windows.UI.Core.SystemNavigationManager.GetForCurrentView().BackRequested += TestView_BackRequested;

As another example, imagine that your app is targeting version 10.0.x.0 of the Xbox device family, and the reference topic for an API that you want to call says that the API was introduced in version 10.0.x.0 of the Xbox device family. In that case, again, the API is guaranteed to be present on every device that your app can be installed on. So you would be able to call that API in your code in the normal way. Note that Visual Studio's IntelliSense will not recognize APIs unless they are implemented by your app's target device family or any extension SDKs that you have referenced. Consequently, if you haven't referenced any extension SDKs, you can be sure that any APIs that appear in IntelliSense must therefore be in your target device family and you can call them freely. Calling an API that's NOT implemented by your target device family There will be cases when you want to call an API, but your target device family is not listed in the documentation. In that case you can opt to write adaptive code in order to call that API. Writing adaptive code with the ApiInformation class There are two steps to write adaptive code. The first step is to make the APIs that you want to access available to your project. To do that, add a reference to the extension SDK that represents the device family that owns the APIs that you want to conditionally call. See Extension SDKs. The second step is to use the Windows.Foundation.Metadata.ApiInformation class in a condition in your code to test for the presence of the API you want to call. This condition is evaluated wherever your app runs, but it evaluates to true only on devices where the API is present and therefore available to call. If you want to call just a small number of APIs, you could use the ApiInformation.IsTypePresent method like this.

// Note: Cache the value instead of querying it more than once. bool isHardwareButtonsAPIPresent = Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons"); if (isHardwareButtonsAPIPresent) { Windows.Phone.UI.Input.HardwareButtons.CameraPressed += HardwareButtons_CameraPressed; }

In this case we can be confident that the presence of the HardwareButtons class implies the presence of the CameraPressed event, because the class and the member have the same requirements info. But in time, new members will be added to already-introduced classes, and those members will have later "introduced in" version numbers. In such cases, instead of using IsTypePresent, you can test for the presence of individual members by using IsEventPresent, IsMethodPresent, IsPropertyPresent, and similar methods. Here's an example. bool isHardwareButtons_CameraPressedAPIPresent = Windows.Foundation.Metadata.ApiInformation.IsEventPresent ("Windows.Phone.UI.Input.HardwareButtons", "CameraPressed");

The set of APIs within a device family is further broken down into subdivisions known as API contracts. You can use the ApiInformation.IsApiContractPresent method to test for the presence of an API contract. This is useful if you want to test for the presence of a large number of APIs that all exist in the same version of an API contract. bool isWindows_Devices_Scanners_ScannerDeviceContract_1_0Present = Windows.Foundation.Metadata.ApiInformation.IsApiContractPresent ("Windows.Devices.Scanners.ScannerDeviceContract", 1, 0);

Win32 APIs in the UWP A UWP app or Windows Runtime Component 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. Link your app with Windowsapp.lib. 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. For the full list of Win32 APIs available to UWP apps, see API Sets for UWP apps and Dlls for UWP apps.

User experience A Universal Windows app allows you to take advantage of the unique capabilities of the device on which it is running. Your app can make use of all of the power of a desktop device, the natural interaction of direct manipulation on a tablet (including touch and pen input), the portability and convenience of mobile devices, the collaborative power of Surface Hub, and other devices that support UWP apps. Good design is the process of deciding how users will interact with your app, as well as how it will look and function. User experience plays a huge part in determining how happy people will be with your app, so don't skimp on this step. Design basics introduce you to designing a Universal Windows app. See the Introduction to Universal Windows Platform (UWP) apps for designers for information on designing UWP apps that delight your users. Before you start coding, see the device primer to help you think through the interaction experience of using your app on all the different form factors you want to target.

In addition to interaction on different devices, plan your app to embrace the benefits of working across multiple devices. For example: Use cloud services to sync across devices. Learn how to connect to web services in support of your app experience. Consider how you can support users moving from one device to another, picking up where they left off. Include notifications and in-app purchases in your planning. These features should work across devices. Design your workflow using Navigation design basics for UWP apps to accommodate mobile, small-screen, and large-screen devices. Lay out your user interface to respond to different screen sizes and resolutions. Consider whether there are features of your app that don’t make sense on a small mobile screen. There may also be areas that don’t make sense on a stationary desktop machine and require a mobile device to light up. For example, most scenarios around location imply a mobile device. Consider how you'll accommodate multiple kinds of input. See the Guidelines for interactions to learn how users can interact with your app by using Cortana, Speech, Touch interactions, the Touch keyboard and more. See the Guidelines for text and text input for more tradition interaction experiences.

Submit a Universal Windows app through your Dashboard The new unified Windows Dev Center dashboard lets you manage and submit all of your apps for Windows devices in one place. New features simplify processes while giving you more control. You'll also find detailed analytic reports combined payout details, ways to promote your app and engage with your customers, and much more. See Using the unified Windows Dev Center dashboard to learn how to submit your apps for publication in the Windows Store.

See Also For more introductory material, see Windows 10 - An Introduction to Building Windows Apps for Windows 10 Devices

Get set up 3/7/2017 • 1 min to read • Edit on GitHub

It's easier than you think to get going. Follow these instructions and start creating Universal Windows Platform (UWP) apps for Windows 10.

1. Get Windows 10 To develop UWP apps, you need the latest version of Windows. Get Windows 10 online Are you an MSDN subscriber? You can get ISO downloads here: Get Windows 10 from MSDN Subscriber Downloads

2. Download or update Visual Studio Microsoft Visual Studio 2017 helps you design, code, test, and debug your apps. If you don't already have Visual Studio 2017, you can install the free Microsoft Visual Studio Community 2017. This download includes device simulators for testing your apps: Download Windows 10 developer tools When you install Visual Studio, make sure to select the Universal Windows App Development Tools option, as shown here:

Need some help with Visual Studio? See Get Started with Visual Studio. If you have already started using Visual Studio, but discover you are missing some components, you can launch the installer again from the New project dialog:

3. Enable your device for development It’s important to test your UWP apps on a real PCs and phones. Before you can deploy apps to your PC or Windows Phone, you have to enable it for development. For detailed instructions, see Enable your device for development.

4. Register as an app developer

You can start developing apps now, but before you can submit them to the store, you need a developer account. To get a developer account, go to the Sign up page.

What's next? After you've installed the tools and gotten a developer license or a developer account, use our tutorials to create your first app: Create your first app tutorials

Want more tools and downloads? For the complete list of tools and downloads, see Downloads.

Enable your device for development 3/13/2017 • 8 min to read • Edit on GitHub

Activate Developer Mode, sideload apps and access other developer features

If you are using Visual Studio on a computer for first time, you will need to enable Developer Mode on both the development PC, and on any devices you'll use to test your code. Opening a UWP project when Developer Mode is not enabled will either open the For developers settings page, or cause this dialog to appear in Visual Studio:

When you see this dialog, click settings for developers to open the For developers settings page. NOTE You can go to the For developers page at any time to enable or disable Developer Mode: simply enter "for developers" into the Cortana search box in the taskbar.

Accessing settings for Developers To enable Developer mode, or access other settings: 1. From the For developers settings dialog, choose the level of access that you need. 2. Read the disclaimer for the setting you chose, then click Yes to accept the change.

NOTE If your device is owned by an organization, some options might be disabled by your organization.

Here's the settings page on the desktop device family:

Here's the settings page on the mobile device family:

Which setting should I choose: sideload apps or Developer Mode? You can enable a device for development, or just for sideloading. Windows Store apps is the default setting. If you aren't development apps, or using special internal apps issued by your company, keep this setting active. Sideloading is installing and then running or testing an app that has not been certified by the Windows Store. For example, an app that is internal to your company only. Developer mode lets you sideload apps, and also run apps from Visual Studio in debug mode. By default, you can only install Universal Windows Platform (UWP) apps from the Windows Store. Changing these settings to use developer features can change the level of security of your device. You should not install apps from unverified sources. Sideload apps

The Sideload apps setting is typically used by companies or schools that need to install custom apps on managed devices without going through the Windows Store. In this case, it's common for the organization to enforce a policy that disables the Windows Store apps setting, as shown previously in the image of the settings page. The organization also provides the required certificate and install location to sideload apps. For more info, see the TechNet articles Sideload apps in Windows 10 and Get started with app deployment in Microsoft Intune. Device family specific info On the desktop device family: You can install an app package (.appx) and any certificate that is needed to run the app by running the Windows PowerShell script that is created with the package ("Add-AppDevPackage.ps1"). For more info, see Packaging UWP apps. On the mobile device family: If the required certificate is already installed, you can tap the file to install any .appx sent to you via email or on an SD card. Sideload apps is a more secure option than Developer Mode because you cannot install apps on the device without a trusted certificate. NOTE If you sideload apps, you should still only install apps from trusted sources. When you install a sideloaded app that has not been certified by the Windows Store, you are agreeing that you have obtained all rights necessary to sideload the app and that you are solely responsible for any harm that results from installing and running the app. See the Windows > Windows Store section of this privacy statement.

Developer Mode

Developer Mode replaces the Windows 8.1 requirements for a developer license. In addition to sideloading, the Developer Mode setting enables debugging and additional deployment options. This includes starting an SSH service to allow this device to be deployed to. In order to stop this service, you have to disable Developer Mode. Device family specific info On the desktop device family: Enable Developer Mode to develop and debug apps in Visual Studio. As stated previously, you will be prompted in Visual Studio if Developer Mode is not enabled. Allows enabling of the Windows subsystem for Linux. For more info, see About Bash on Ubuntu on Windows. On the mobile device family: Enable developer mode to deploy apps from Visual Studio and debug them on the device. You can tap the file to install any .appx sent to you via email or on an SD card. Do not install apps from unverified sources.

Additional Developer Mode features For each device family, additional developer features might be available. These features are available only when Developer Mode is enabled on the device, and might vary depending on your OS version. When you enable Developer Mode, a package of options is installed that includes: Installs Windows Device Portal. Device Portal is enabled and firewall rules are configured for it only when the Enable Device Portal option is turned on. Installs, enables, and configures firewall rules for SSH services that allow remote installation of apps. (Desktop only) Allows enabling of the Windows subsystem for Linux. For more info, see About Bash on Ubuntu on Windows. This image shows developer features for the mobile device family on Windows 10:

Device Portal

To learn more about device discovery and Device Portal, see Windows Device Portal overview. For device specific setup instructions, see: Device Portal for Desktop Device Portal for HoloLens Device Portal for IoT Device Portal for Mobile Device Portal for Xbox If you encounter problems enabling Developer Mode or Device Portal, see the Known Issues forum to find workarounds for these issues. SSH

SSH services are enabled when you enable Developer Mode on your device. This is used when your device is a deployment target for UWP applications. The names of the services are 'SSH Server Broker' and 'SSH Server Proxy'. NOTE This is not Microsoft's OpenSSH implementation, which you can find on GitHub.

In order to take advantage of the SSH services, you can enable device discovery to allow pin pairing. If you intend to run

another SSH service, you can set this up on a different port or turn off the Developer Mode SSH services. To turn off the SSH services, simply disable Developer Mode. Device Discovery

When you enable device discovery, you are allowing your device to be visible to other devices on the network through mDNS. This feature also allows you to get the SSH pin for pairing to this device.

You should enable device discovery only if you intend to make the device a deployment target. For example, if you use Device Portal to deploy an app to a phone for testing, you need to enable device discovery on the phone, but not on your development PC. Error reporting (Mobile only)

Set this value to specify how many crash dumps are saved on your phone. Collecting crash dumps on your phone gives you instant access to important crash information directly after the crash occurs. Dumps are collected for developer-signed apps only. You can find the dumps in your phone's storage in the Documents\Debug folder. For more info about dump files, see Using dump files. Optimizations for Windows Explorer, Remote Desktop, and PowerShell (Desktop only)

On the desktop device family, the For developers settings page has shortcuts to settings that you can use to optimize your PC for development tasks. For each setting, you can select the checkbox and click Apply, or click the Show settings link to open the settings page for that option. Tip There are several tools you can use to deploy an app from a Windows 10 PC to a Windows 10 mobile device. Both devices must be connected to the same subnet of the network by a wired or wireless connection, or they must be connected by USB. Either of the ways listed installs only the app package (.appx); they do not install certificates. Use the Windows 10 Application Deployment (WinAppDeployCmd) tool. Learn more about the WinAppDeployCmd tool. Starting in Windows 10, Version 1511, you can use Device Portal to deploy from your browser to a mobile device

running Windows 10, Version 1511 or later. Use the Apps page in Device Portal to upload an app package (.appx) and install it on the device.

Use group policies or registry keys to enable a device For most developers, you want to use the settings app to enable your device for debugging. In certain scenarios, such as automated tests, you can use other ways to enable your Windows 10 desktop device for development. You can use gpedit.msc to set the group policies to enable your device, unless you have Windows 10 Home. If you do have Windows 10 Home, you need to use regedit or PowerShell commands to set the registry keys directly to enable your device. Use gpedit to enable your device 1. Run Gpedit.msc. 2. Go to Local Computer Policy > Computer Configuration > Administrative Templates > Windows Components > App Package Deployment 3. To enable sideloading, edit the policies to enable: Allow all trusted apps to install OR To enable developer mode, edit the policies to enable both: Allow all trusted apps to install Allows development of Windows Store apps and installing them from an integrated development environment (IDE) 4. Reboot your machine. Use regedit to enable your device 1. Run regedit. 2. To enable sideloading, set the value of this DWORD to 1: HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock\AllowAllTrustedApps OR To enable developer mode, set the values of this DWORD to 1: HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock\AllowDevelopmentWithoutDevLicense Use PowerShell to enable your device 1. Run PowerShell with administrator privileges. 2. To enable sideloading, run this command: PS C:\WINDOWS\system32> reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock" /t REG_DWORD /f /v "AllowAllTrustedApps" /d "1" OR To enable developer mode, run this command: PS C:\WINDOWS\system32> reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock" /t REG_DWORD /f /v "AllowDevelopmentWithoutDevLicense" /d "1"

Upgrade your device from Windows 8.1 to Windows 10 When you create or sideload apps on your Windows 8.1 device, you have to install a developer license. If you upgrade

your device from Windows 8.1 to Windows 10, this information remains. Run the following command to remove this information from your upgraded Windows 10 device. This step is not required if you upgrade directly from Windows 8.1 to Windows 10, Version 1511 or later. To unregister a developer license 1. Run PowerShell with administrator privileges. 2. Run this command: unregister-windowsdeveloperlicense. After this you need to enable your device for development as described in this topic so that you can continue to develop on this device. If you don't do that, you might get an error when you debug your app, or you try to create a package for it. Here is an example of this error: Error : DEP0700 : Registration of the app failed.

See Also What's a Universal Windows app? Get set up Sign up for Windows account

Ready to sign up? 3/6/2017 • 1 min to read • Edit on GitHub

Register now for a developer account so you can get your apps into the Windows Store and participate in other Microsoft programs. Sign up now!

Opening your developer account We offer individual and company accounts in locations around the world. Check out our overview of the sign-up process to see how it works.

Have a name for your app? As soon as you open your developer account, you can create your app by reserving a name.

Create your first app 3/13/2017 • 2 min to read • Edit on GitHub

Write a UWP app using your favorite programming language

Welcome to the UWP platform! These tutorials will help you create your first UWP app in the language of your choice. You'll learn how to: Create a UWP app project in Microsoft Visual Studio. Add UI elements and code to your project. Use third party libraries to add new functionality. Build and debug your app on your local machine. To get started, choose your favorite language!

C# and XAML Use your .NET, WPF, or Silverlight skills to build apps using XAML with C#. Create a "Hello, world" app using XAML with C# We assume you're already comfortable with XAML and either C#. If you want to learn the basics, or just refresh your memory, try these courses from the Microsoft Virtual Academy. And as a language refresher: C# Fundamentals for Absolute Beginners VB Fundamentals for Absolute Beginners A Developer's Guide to Windows 10 If you are ready to attempt something more fun than "Hello, World!", try this C# and MonoGame tutorial: A simple 2D UWP game for the Windows Store, written in C# and MonoGame

JavaScript and HTML Take advantage of your web skills to build apps using HTML5, Cascading Style Sheets, Level 3 (CSS3), and

JavaScript. Create a "Hello, world" app using HTML and JavaScript A simple 2D UWP game for the Windows Store, written in JavaScript and CreateJS A 3D UWP game for the Windows Store, written in JavaScript and threeJS We assume you're already comfortable with HTML5, CSS3, and JavaScript. If you want to learn the basics, or just refresh your memory, try these courses from the Microsoft Virtual Academy. JavaScript Fundamentals for Absolute Beginners HTML5 & CSS3 Fundamentals for Absolute Beginners

Visual C++ component extensions (C++/CX) and XAML Take advantage of your C++ programming expertise to build apps using Visual C++ component extensions (C++/CX) with XAML. Create a "Hello, world" app using XAML with C++/CX We assume you're already comfortable with XAML and C++. If you want to learn the basics, or just refresh your memory, try these courses from the Microsoft Virtual Academy. C++: A General Purpose Language and Library Jump Start

Objective-C Are you more of an iOS developer? Use the Windows Bridge for iOS to convert your existing code to a UWP app, and keep developing in Objective C.

Cross-platform and mobile development Need to target Android and iOS? Check out Xamarin.

Related topics Publishing your Windows Store app. How-to articles on developing UWP apps Code Samples for UWP developers What's a Universal Windows app? Get set up Sign up for Windows account

Create a "Hello, world" app (XAML) 3/9/2017 • 7 min to read • Edit on GitHub

This tutorial teaches you how to use XAML and C# to create a simple "Hello, world" app for the Universal Windows Platform (UWP) on Windows 10. With a single project in Microsoft Visual Studio, you can build an app that runs on any Windows 10 device. Here you'll learn how to: Create a new Visual Studio 2017 project that targets Windows 10 and the UWP. Write XAML to change the UI on your start page. Run the project on the local desktop in Visual Studio. Use a SpeechSynthesizer to make the app talk when you press a button.

Before you start... What's a Universal Windows app? To complete this tutorial, you need Windows 10 and Visual Studio 2017. Get set up. We also assume you're using the default window layout in Visual Studio. If you change the default layout, you can reset it in the Window menu by using the Reset Window Layout command. NOTE This tutorial is using Visual Studio Community 2017. If you are using a different version of Visual Studio, it may look a little different for you.

Step 1: Create a new project in Visual Studio. 1. Launch Visual Studio 2017. 2. From the File menu, select New > Project... to open the New Project dialog. 3. From the list of templates on the left, open Installed > Templates > Visual C# > Windows, and then choose Universal to see the list of UWP project templates. (If you don't see any Universal templates, you might be missing the components for creating UWP apps. You can repeat the installation process and add UWP support by clicking Open Visual Studio installer on the New Project dialog. See Get set up

4. Choose the Blank App (Universal Windows) template, and enter "HelloWorld" as the Name. Select OK.

NOTE If this is the first time you have used Visual Studio, you might see a Settings dialog asking you to enable Developer mode. Developer mode is a special setting that enables certain features, such as permission to run apps directly, rather than only from the Store. For more information, please read Enable your device for development. To continue with this guide, select Developer mode, click Yes, and close the dialog.

1. The target version/minimum version dialog appears. The default settings are fine for this tutorial, so select OK to create the project.

2. When your new project opens, its files are displayed in the Solution Explorer pane on the right. You may need to choose the Solution Explorer tab instead of the Properties tab to see your files.

Although the Blank App (Universal Window) is a minimal template, it still contains a lot of files. These files are essential to all UWP apps using C#. Every project that you create in Visual Studio contains them. What's in the files?

To view and edit a file in your project, double-click the file in the Solution Explorer. Expand a XAML file just like a folder to see its associated code file. XAML files open in a split view that shows both the design surface and the XAML editor. NOTE What is XAML? Extensible Application Markup Language (XAML) is the language used to define your app's user interface. It can be entered manually, or created using the Visual Studio design tools. A .xaml file has a .xaml.cs code-behind file which contains the logic. Together, the XAML and code-behind make a complete class. For more information, see XAML overview.

App.xaml and App.xaml.cs App.xaml is where you declare resources that are used across the app. App.xaml.cs is the code-behind file for App.xaml. Like all code-behind pages, it contains a constructor that calls the InitializeComponent method. You don't write the InitializeComponent method. It's generated by Visual Studio, and its main purpose is to initialize the elements declared in the XAML file. App.xaml.cs is the entry point for your app. App.xaml.cs also contains methods to handle activation and suspension of the app. MainPage.xaml MainPage.xaml is where you define the UI for your app. You can add elements directly using XAML markup, or you can use the design tools provided by Visual Studio. MainPage.xaml.cs is the code-behind page for MainPage.xaml. It's where you add your app logic and event handlers. Together these two files define a new class called MainPage , which inherits from Page, in the HelloWorld namespace.

Package.appxmanifest A manifest file that describes your app: its name, description, tile, start page, etc. Includes a list of the files that your app contains. A set of logo images Assets/Square150x150Logo.scale-200.png represents your app in the start menu. Assets/StoreLogo.png represents your app in the Windows Store. Assets/SplashScreen.scale-200.png is the splash screen that appears when your app starts.

Step 2: Adding a button Using the designer view

Let's add a button to our page. In this tutorial, you work with just a few of the files listed previously: App.xaml, MainPage.xaml, and MainPage.xaml.cs. 1. Double-click on MainPage.xaml to open it in the Design view. You'll notice there is a graphical view on the top part of the screen, and the XAML code view underneath. You can make changes to either, but for now we'll use the graphical view.

2. Click on the vertical Toolbox tab on the left to open the list of UI controls. (You can click the pin icon in its title bar to keep it visible.)

3. Expand Common XAML Controls, and drag the Button out to the middle of the design canvas.

If you look at the XAML code window, you'll see that the Button has been added there too:



4. Change the button's text. Click in the XAML code view, and change the Content from "Button" to "Hello, world!".

Notice how the button displayed in the design canvas updates to display the new text.

Step 3: Start the app At this point, you've created a very simple app. This is a good time to build, deploy, and launch your app and see what it looks like. You can debug your app on the local machine, in a simulator or emulator, or on a remote device. Here's the target device menu in Visual Studio.

Start the app on a Desktop device

By default, the app runs on the local machine. The target device menu provides several options for debugging your app on devices from the desktop device family.

Simulator Local Machine Remote Machine To start debugging on the local machine 1. In the target device menu ( selected. (It's the default selection.)

) on the Standard toolbar, make sure that Local Machine is

2. Click the Start Debugging button (

) on the toolbar.

–or– From the Debug menu, click Start Debugging. –or– Press F5. The app opens in a window, and a default splash screen appears first. The splash screen is defined by an image (SplashScreen.png) and a background color (specified in your app's manifest file). The splash screen disappears, and then your app appears. It looks like this.

Press the Windows key to open the Start menu, then show all apps. Notice that deploying the app locally adds its tile to the Start menu. To run the app again later (not in debugging mode), tap or click its tile in the Start menu. It doesn't do much—yet—but congratulations, you've built your first UWP app! To stop debugging Click the Stop Debugging button (

) in the toolbar.

–or– From the Debug menu, click Stop debugging. –or– Close the app window.

Step 3: Event handlers An "event handler" sounds complicated, but it's just another name for the code that is called when an event happens (such as the user clicking on your button). 1. Stop the app from running, if you haven't already. 2. Double-click on the button control on the design canvas to make Visual Studio create an event handler for your button. You can of course, create all the code manually too. Or you can click on the button to select it, and look in the Properties pane on the lower right. If you switch to Events (the little lightning bolt) you can add the name of your event handler. 3. Edit the event handler code in MainPage.xaml.cs, the code-behind page. This is where things get interesting. The default event handler looks like this: private void Button_Click(object sender, RouteEventArgs e) { }

Let's change it, so it looks like this: private async void Button_Click(object sender, RoutedEventArgs e) { MediaElement mediaElement = new MediaElement(); var synth = new Windows.Media.SpeechSynthesis.SpeechSynthesizer(); Windows.Media.SpeechSynthesis.SpeechSynthesisStream stream = await synth.SynthesizeTextToStreamAsync("Hello, World!"); mediaElement.SetSource(stream, stream.ContentType); mediaElement.Play(); }

Make sure you include the async keyword as well, or you'll get an error when you try to run the app. What did we just do?

This code uses some Windows APIs to create a speech synthesis object, and then gives it some text to say. (For more information on using SpeechSynthesis, see the SpeechSynthesis namespace docs.) When you run the app and click on the button, your computer (or phone) will literally say "Hello, World!".

Summary Congratulations, you've created your first app for Windows 10 and the UWP! To learn how to use XAML for laying out the controls your app will use, try the grid tutorial, or jump straight to next steps?

Create a "Hello, world" app (JS) 3/7/2017 • 4 min to read • Edit on GitHub

This tutorial teaches you how to use JavaScript and HTML to create a simple "Hello, world" app that targets the Universal Windows Platform (UWP) on Windows 10. With a single project in Microsoft Visual Studio, you can build an app that runs on any Windows 10 device. NOTE This tutorial is using Visual Studio Community 2017. If you are using a different version of Visual Studio, it may look a little different for you.

Here you'll learn how to: Create a new Visual Studio 2017 project that targets Windows 10 and the UWP. Add HTML and JavaScript content Run the project on the local desktop in Visual Studio

Before you start... What's a Universal Windows app? To complete this tutorial, you need Windows 10 and Visual Studio 2017. Get set up. We also assume you're using the default window layout in Visual Studio. If you change the default layout, you can reset it in the Window menu by using the Reset Window Layout command.

Step 1: Create a new project in Visual Studio. 1. Launch Visual Studio 2017. 2. From the File menu, select New > Project... to open the New Project dialog. 3. From the list of templates on the left, open Installed > Templates > JavaScript, and then choose Windows Universal to see the list of UWP project templates. (If you don't see any Universal templates, you might be missing the components for creating UWP apps. You can repeat the installation process and add UWP support by clicking Open Visual Studio installer on the New Project dialog. See Get set up 4. Choose the Blank App (Universal Windows) template, and enter "HelloWorld" as the Name. Select OK.

NOTE If this is the first time you have used Visual Studio, you might see a Settings dialog asking you to enable Developer mode. Developer mode is a special setting that enables certain features, such as permission to run apps directly, rather than only from the Store. For more information, please read Enable your device for development. To continue with this guide, select Developer mode, click Yes, and close the dialog.

1. The target version/minimum version dialog appears. The default settings are fine for this tutorial, so select OK to create the project.

2. When your new project opens, its files are displayed in the Solution Explorer pane on the right. You may need to choose the Solution Explorer tab instead of the Properties tab to see your files.

Although the Blank App (Universal Window) is a minimal template, it still contains a lot of files. These files are essential to all UWP apps using JavaScript. Every project that you create in Visual Studio contains them. What's in the files?

To view and edit a file in your project, double-click the file in the Solution Explorer. default.css The default stylesheet used by the app. main.js The default JavaScript file. It's referenced in the index.html file. index.html The app's web page, loaded and displayed when the app is launched. A set of logo images Assets/Square150x150Logo.scale-200.png represents your app in the start menu. Assets/StoreLogo.png represents your app in the Windows Store. Assets/SplashScreen.scale-200.png is the splash screen that appears when your app starts.

Step 2: Adding a button Click on index.html to select it in the editor, and change the HTML it contains to read: Hello World Click the button.. Hello world!

It should look like this:

This HTML references the main.js that will contain our JavaScript, and then adds a single line of text and a single button to the body of the web page. The button is given an ID so the JavaScript will be able to reference it.

Step 3: Adding some JavaScript Now we'll add the JavaScript. Click on main.js to select it, and add the following:

// Your code here! window.onload = function () { document.getElementById("button").onclick = function (evt) { sayHello() } }

function sayHello() { var messageDialog = new Windows.UI.Popups.MessageDialog("Hello, world!", "Alert"); messageDialog.showAsync(); }

It should look like this:

This JavaScript declares two functions. The window.onload function is called automatically when index.html is displayed. It finds the button (using the ID we declared) and adds an onclick handler: the method that will be called when the button is clicked. The second function, sayHello(), creates and displays a dialog. This is very similar to the Alert() function you may know from previous JavaScript development.

Step 4: Run the app! Now you can run the app by pressing F5. The app will load, the web page will be displayed. Click on the button, and the message dialog will pop-up.

Summary Congratulations, you've created a JavaScript app for Windows 10 and the UWP! This is a rediculously simple example, however, you can now start adding your favorite JavaScript libraries and frameworks to create your own app. And as it's a UWP app, you can publish it to the Store. For example of how third party frameworks can be added, see these projects: A simple 2D UWP game for the Windows Store, written in JavaScript and CreateJS A 3D UWP game for the Windows Store, written in JavaScript and threeJS

Create a "hello world" app in C++ 3/9/2017 • 16 min to read • Edit on GitHub

With Microsoft Visual Studio 2015, you can use C++ to develop an app that runs on Windows 10 with a UI that's defined in Extensible Application Markup Language (XAML). NOTE This tutorial is using Visual Studio Community 2017. If you are using a different version of Visual Studio, it may look a little different for you.

Before you start... To complete this tutorial, you must use Visual Studio Community 2017, or one of the non-Community versions of Visual Studio 2017, on a computer that's running Windows 10. To download, see Get the tools. We assume you have a basic understanding of standard C++, XAML, and the concepts in the XAML overview. We assume you're using the default window layout in Visual Studio. To reset to the default layout, on the menu bar, choose Window > Reset Window Layout.

Comparing C++ desktop apps to Windows apps If you're coming from a background in Windows desktop programming in C++, you'll probably find that some aspects of writing apps for the UWP are familiar, but other aspects require some learning. What's the same?

You can use the STL, the CRT (with some exceptions), and any other C++ library as long as the code does not attempt to call Windows functions that are not accessible from the Windows Runtime environment. If you're accustomed to visual designers, you can still use the designer built into Microsoft Visual Studio, or you can use the more full-featured Blend for Visual Studio. If you're accustomed to coding UI by hand, you can hand-code your XAML. You're still creating apps that use Windows operating system types and your own custom types. You're still using the Visual Studio debugger, profiler, and other development tools. You're still creating apps that are compiled to native machine code by the Visual C++ compiler. Windows Store apps in C++ don't execute in a managed runtime environment. What's new?

The design principles for Windows Store apps and Universal Windows apps are very different from those for desktop apps. Window borders, labels, dialog boxes, and so on, are de-emphasized. Content is foremost. Great Universal Windows apps incorporate these principles from the very beginning of the planning stage. You're using XAML to define the entire UI. The separation between UI and core program logic is much clearer in a Windows Universal app than in an MFC or Win32 app. Other people can work on the appearance of the UI in the XAML file while you're working on the behavior in the code file. You're primarily programming against a new, easy-to-navigate, object-oriented API, the Windows Runtime, although on Windows devices Win32 is still available for some functionality. You use C++/CX to consume and create Windows Runtime objects. C++/CX enables C++ exception

handling, delegates, events, and automatic reference counting of dynamically created objects. When you use C++/CX, the details of the underlying COM and Windows architecture are hidden from your app code. For more information, see C++/CX Language Reference. Your app is compiled into a package that also contains metadata about the types that your app contains, the resources that it uses, and the capabilities that it requires (file access, internet access, camera access, and so forth). In the Windows Store and Windows Phone Store your app is verified as safe by a certification process and made discoverable to millions of potential customers.

Hello World Store app in C++ Our first app is a "Hello World" that demonstrates some basic features of interactivity, layout, and styles. We'll create an app from the Windows Universal app project template. If you've developed apps for Windows 8.1 and Windows Phone 8.1 before, you might remember that you had to have three projects in Visual Studio, one for the Windows app, one for the phone app, and another with shared code. The Windows 10 Universal Windows Platform (UWP) makes it possible to have just one project, which runs on all devices, including desktop and laptop computers running Windows 10, devices such as tablets, mobile phones, VR devices and so on. We'll start with the basics: How to create a Universal Windows project in Visual Studio 2017. How to understand the projects and files that are created. How to understand the extensions in Visual C++ component extensions (C++/CX), and when to use them. First, create a solution in Visual Studio 1. In Visual Studio, on the menu bar, choose File > New > Project. 2. In the New Project dialog box, in the left pane, expand Installed > Visual C++ > Windows Universal. NOTE You may be prompted to install the Windows Universal tools for C++ development.

1. In the center pane, select Blank App (Universal Windows). (If you don't see these options, make sure you have the Universal Windows App Development Tools installed. See Get set up for more info.) 2. Enter a name for the project. We'll name it HelloWorld.

3. Choose the OK button. NOTE If this is the first time you have used Visual Studio, you might see a Settings dialog asking you to enable Developer mode. Developer mode is a special setting that enables certain features, such as permission to run apps directly, rather than only from the Store. For more information, please read Enable your device for development. To continue with this guide, select Developer mode, click Yes, and close the dialog.

Your project files are created. Before we go on, let’s look at what's in the solution.

About the project files

Every .xaml file in a project folder has a corresponding .xaml.h file and .xaml.cpp file in the same folder and a .g file and a .g.hpp file in the Generated Files folder, which is on disk but not part of the project. You modify the XAML files to create UI elements and connect them to data sources (DataBinding). You modify the .h and .cpp files to add custom logic for event handlers. The auto-generated files represent the transformation of the XAML markup into C++. Don't modify these files, but you can study them to better understand how the code-behind works. Basically, the generated file contains a partial class definition for a XAML root element; this class is the same class that you modify in the *.xaml.h and .cpp files. The generated files declare the XAML UI child elements as class members so that you can reference them in the code you write. At build time, the generated code and your code are merged into a complete class definition and then compiled. Let's look first at the project files. App.xaml, App.xaml.h, App.xaml.cpp: Represent the Application object, which is an app's entry point. App.xaml contains no page-specific UI markup, but you can add UI styles and other elements that you want to be accessible from any page. The code-behind files contain handlers for the OnLaunched and OnSuspending events. Typically, you add custom code here to initialize your app when it starts and perform cleanup when it's suspended or terminated.

MainPage.xaml, MainPage.xaml.h, MainPage.xaml.cpp:Contain the XAML markup and code-behind for the default "start" page in an app. It has no navigation support or built-in controls. pch.h, pch.cpp: A precompiled header file and the file that includes it in your project. In pch.h, you can include any headers that do not change often and are included in other files in the solution. Package.appxmanifest: An XML file that describes the device capabilities that your app requires, and the app version info and other metadata. To open this file in the Manifest Designer, just double-click it. HelloWorld_TemporaryKey.pfx:A key that enables deployment of the app on this machine, from Visual Studio.

A first look at the code If you examine the code in App.xaml.h, App.xaml.cpp in the shared project, you'll notice that it's mostly C++ code that looks familiar. However, some syntax elements might not be as familiar if you are new to Windows Runtime apps, or you've worked with C++/CLI. Here are the most common non-standard syntax elements you'll see in C++/CX: Ref classes Almost all Windows Runtime classes, which includes all the types in the Windows API--XAML controls, the pages in your app, the App class itself, all device and network objects, all container types--are declared as a ref class. (A few Windows types are value class or value struct). A ref class is consumable from any language. In C++, the lifetime of these types is governed by automatic reference counting (not garbage collection) so that you never explicitly delete these objects. You can create your own ref classes as well. namespace HelloWorld { /// /// An empty page that can be used on its own or navigated to within a Frame. /// public ref class MainPage sealed { public: MainPage(); }; }

All Windows Runtime types must be declared within a namespace and unlike in ISO C++ the types themselves have an accessibility modifier. The public modifier makes the class visible to Windows Runtime components outside the namespace. The sealed keyword means the class cannot serve as a base class. Almost all ref classes are sealed; class inheritance is not broadly used because Javascript does not understand it. ref new and ^ (hats) You declare a variable of a ref class by using the ^ (hat) operator, and you instantiate the object with the ref new keyword. Thereafter you access the object's instance methods with the -> operator just like a C++ pointer. Static methods are accessed with the :: operator just as in ISO C++. In the following code, we use the fully qualified name to instantiate an object, and use the -> operator to call an instance method. Windows::UI::Xaml::Media::Imaging::BitmapImage^ bitmapImage = ref new Windows::UI::Xaml::Media::Imaging::BitmapImage(); bitmapImage->SetSource(fileStream);

Typically, in a .cpp file we would add a

using namespace Windows::UI::Xaml::Media::Imaging

directive and the auto keyword,

so that the same code would look like this: auto bitmapImage = ref new BitmapImage(); bitmapImage->SetSource(fileStream);

Properties A ref class can have properties, which, just as in managed languages, are special member functions that appear as fields to consuming code. public ref class SaveStateEventArgs sealed { public: // Declare the property property Windows::Foundation::Collections::IMap^ PageState { Windows::Foundation::Collections::IMap^ get(); } ... }; ... // consume the property like a public field void PhotoPage::SaveState(Object^ sender, Common::SaveStateEventArgs^ e) { if (mruToken != nullptr && !mruToken->IsEmpty()) { e->PageState->Insert("mruToken", mruToken); } }

Delegates Just as in managed languages, a delegate is a reference type that encapsulates a function with a specific signature. They are most often used with events and event handlers // Delegate declaration (within namespace scope) public delegate void LoadStateEventHandler(Platform::Object^ sender, LoadStateEventArgs^ e); // Event declaration (class scope) public ref class NavigationHelper sealed { public: event LoadStateEventHandler^ LoadState; }; // Create the event handler in consuming class MainPage::MainPage() { auto navigationHelper = ref new Common::NavigationHelper(this); navigationHelper->LoadState += ref new Common::LoadStateEventHandler(this, &MainPage::LoadState); }

Adding content to the app Let's add some content to the app. Step 1: Modify your start page 1. In Solution Explorer, open MainPage.xaml.

2. Create controls for the UI by adding the following XAML to the root Grid, immediately before its closing tag. It contains a StackPanel that has a TextBlock that asks the user's name, a TextBox element that accepts the user's name, a Button, and another TextBlock element.

3. At this point, you have created a very basic Universal Windows app. To see what the UWP app looks like, press F5 to build, deploy, and run the app in debugging mode. The default splash screen appears first. It has an image—Assets\SplashScreen.scale-100.png—and a background color that are specified in the app's manifest file. To learn how to customize the splash screen, see Adding a splash screen. When the splash screen disappears, your app appears. It displays the main page of the App.

It doesn't do much—yet—but congratulations, you've built your first Universal Windows Platform app! To stop debugging and close the app, return to Visual Studio and press Shift+F5. For more information, see Run a Store app from Visual Studio. In the app, you can type in the TextBox, but clicking the Button doesn't do anything. In later steps, you create an event handler for the button's Click event, which displays a personalized greeting.

Step 2: Create an event handler 1. In MainPage.xaml, in either XAML or design view, select the "Say Hello" Button in the StackPanel you added earlier. 2. Open the Properties Window by pressing Alt+Enter, and then choose the Events button ( ). 3. Find the Click event. In its text box, type the name of the function that handles the Click event. For this example, type "Button_Click".

4. Press Enter. The event handler method is created in MainPage.xaml.cpp and opened so that you can add the code that's executed when the event occurs. At the same time, in MainPage.xaml, the XAML for the Button is updated to declare the Click event handler, like this: Existing Item. Locate and select the green rectangle in the file browser Name the item “grass.png” and select Add. 3. Add class variables

To load this image as a sprite texture, open Game1.cs and add the following class variables. const float SKYRATIO = 2f/3f; float screenWidth; float screenHeight; Texture2D grass;

The SKYRATIO variable tells us how much of the scene we want to be sky versus grass—in this case, two-thirds. screenWidth and screenHeight will keep track of the app window size, while grass is where we’ll store our green rectangle. 4. Initialize class variables and set window size

The screenWidth and screenHeight variables still need to be initialized, so add this code to the Initialize method: ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.FullScreen; screenHeight = (float)ApplicationView.GetForCurrentView().VisibleBounds.Height; screenWidth = (float)ApplicationView.GetForCurrentView().VisibleBounds.Width; this.IsMouseVisible = false;

Along with getting the screen’s height and width, we also set the app’s windowing mode to Fullscreen, and make the mouse invisible. 5. Load the texture

To load the texture into the grass variable, add the following to the LoadContent method: grass = Content.Load("grass.png");

6. Draw the sprite

To draw the rectangle, add the following lines to the Draw method:

GraphicsDevice.Clear(Color.CornflowerBlue); spriteBatch.Begin(); spriteBatch.Draw(grass, new Rectangle(0, (int)(screenHeight * SKYRATIO), (int)screenWidth, (int)screenHeight), Color.White); spriteBatch.End();

Here we use the spriteBatch.Draw method to place the given texture within the borders of a Rectangle object. A Rectangle is defined by the x and y coordinates of its top left and bottom right corner. Using the screenWidth, screenHeight, and SKYRATIO variables we defined earlier, we draw the green rectangle texture across the bottom one-third of the screen. If you run the program now you should see the blue background from before, partially covered by the green rectangle.

Scale to high DPI screens If you’re running Visual Studio on a high pixel-density monitor, like those found on a Surface Pro or Surface Studio, you may find that the green rectangle from the steps above doesn’t quite cover the bottom third of the screen. It’s probably floating above the bottom-left corner of the screen. To fix this and unify the experience of our game across all devices, we will need to create a method that scales certain values relative to the screen’s pixel density: public float ScaleToHighDPI(float f) { DisplayInformation d = DisplayInformation.GetForCurrentView(); f *= (float)d.RawPixelsPerViewPixel; return f; }

Next replace the initializations of screenHeight and screenWidth in the Initialize method with this: screenHeight = ScaleToHighDPI((float)ApplicationView.GetForCurrentView().VisibleBounds.Height); screenWidth = ScaleToHighDPI((float)ApplicationView.GetForCurrentView().VisibleBounds.Width);

If you’re using a high DPI screen and try to run the app now, you should see the green rectangle covering the bottom third of the screen as intended.

Build the SpriteClass Before we start animating sprites, we’re going to make a new class called “SpriteClass,” which will let us reduce the surface-level complexity of sprite manipulation. 1. Create a new class

In the Solution Explorer, right-click MonoGame2D (Universal Windows) and select Add -> Class. Name the class “SpriteClass.cs” then select Add. 2. Add class variables

Add this code to the class you just created: public Texture2D texture { get; } public float x { get; set; } public float y { get; set; } public float angle { get; set; } public float dX { get; set; } public float dY { get; set; } public float dA { get; set; } public float scale { get; set; }

Here we set up the class variables we need to draw and animate a sprite. The x and y variables represent the sprite’s current position on the plane, while the angle variable is the sprite’s current angle in degrees (0 being upright, 90 being tilted 90 degrees clockwise). It’s important to note that, for this class, x and y represent the coordinates of the center of the sprite, (the default origin is the top-left corner). This is makes rotating sprites easier, as they will rotate around whatever origin they are given, and rotating around the center gives us a uniform spinning motion. After this, we have dX, dY, and dA, which are the per-second rates of change for the x, y, and angle variables respectively. 3. Create a constructor

When creating an instance of SpriteClass, we provide the constructor with the graphics device from Game1.cs, the path to the texture relative to the project folder, and the desired scale of the texture relative to its original size. We’ll set the rest of the class variables after we start the game, in the update method. public SpriteClass (GraphicsDevice graphicsDevice, string texturePath, float scale) { this.scale = scale; if (texture == null) { using (var stream = TitleContainer.OpenStream(textureName)) { texture = Texture2D.FromStream(graphicsDevice, stream); } } }

4. Update and Draw

There are still a couple of methods we need to add to the SpriteClass declaration: public void Update (float elapsedTime) { this.x += this.dX * elapsedTime; this.y += this.dY * elapsedTime; this.angle += this.dA * elapsedTime; } public void Draw (SpriteBatch spriteBatch) { Vector2 spritePosition = new Vector2(this.x, this.y); spriteBatch.Draw(texture, spritePosition, null, Color.White, this.angle, new Vector2(texture.Width/2, texture.Height/2), new Vector2(scale, scale), SpriteEffects.None, 0f); }

The Update SpriteClass method is called in the Update method of Game1.cs, and is used to update the sprites x, y, and angle values based on their respective rates of change. The Draw method is called in the Draw method of Game1.cs, and is used to draw the sprite in the game window.

User input and animation Now we have the SpriteClass built, we’ll use it to create two new game objects, The first is an avatar that the player can control with the arrow keys and the space bar. The second is an object that the player must avoid 1. Get the textures

For the player’s avatar we’re going to use Microsoft’s very own ninja cat, riding on his trusty t-rex. Click here to download the image. Now for the obstacle that the player needs to avoid. What do ninja-cats and carnivorous dinosaurs both hate more than anything? Eating their veggies! Click here to download the image. Just as before with the green rectangle, add these images to Content.mgcb via the MonoGame Pipeline, naming them “ninja-cat-dino.png” and “broccoli.png” respectively. 2. Add class variables

Add the following code to the list of class variables in Game1.cs:

SpriteClass dino; SpriteClass broccoli; bool spaceDown; bool gameStarted; float broccoliSpeedMultiplier; float gravitySpeed; float dinoSpeedX; float dinoJumpY; float score; Random random;

dino and broccoli are our SpriteClass variables. dino will hold the player avatar, while broccoli holds the broccoli obstacle. spaceDown keeps track of whether the spacebar is being held down as opposed to pressed and released. gameStarted tells us whether the user has started the game for the first time. broccoliSpeedMultiplier determines how fast the broccoli obstacle moves across the screen. gravitySpeed determines how fast the player avatar accelerates downward after a jump. dinoSpeedX and dinoJumpY determine how fast the player avatar moves and jumps. score tracks how many obstacles the player has successfully dodged. Finally, random will be used to add some randomness to the behavior of the broccoli obstacle. 3. Initialize variables

Next we need to initialize these variables. Add the following code to the Initialize method: broccoliSpeedMultiplier = 0.5f; spaceDown = false; gameStarted = false; score = 0; random = new Random(); dinoSpeedX = ScaleToHighDPI(1000f); dinoJumpY = ScaleToHighDPI(-1200f); gravitySpeed = ScaleToHighDPI(30f);

Note that the last three variables need to be scaled for high DPI devices, because they specify a rate of change in pixels. 4. Construct SpriteClasses

We will construct SpriteClass objects in the LoadContent method. Add this code to what you already have there: dino = new SpriteClass(GraphicsDevice, "Content/ninja-cat-dino.png", ScaleToHighDPI(1f)); broccoli = new SpriteClass(GraphicsDevice, "Content/broccoli.png", ScaleToHighDPI(0.2f));

The broccoli image is quite a lot larger than we want it to appear in the game, so we’ll scale it down to 0.2 times its original size. 5. Program obstacle behavior

We want the broccoli to spawn somewhere offscreen, and head in the direction of the player’s avatar, so they need to dodge it. To accomplish they, add this method to the Game1.cs class:

public void SpawnBroccoli() { int direction = random.Next(1, 5); switch (direction) { case 1: broccoli.x = -100; broccoli.y = random.Next(0, (int)screenHeight); break; case 2: broccoli.y = -100; broccoli.x = random.Next(0, (int)screenWidth); break; case 3: broccoli.x = screenWidth + 100; broccoli.y = random.Next(0, (int)screenHeight); break; case 4: broccoli.y = screenHeight + 100; broccoli.x = random.Next(0, (int)screenWidth); break; } if (score % 5 == 0) broccoliSpeedMultiplier += 0.2f; broccoli.dX = (dino.x - broccoli.x) * broccoliSpeedMultiplier; broccoli.dY = (dino.y - broccoli.y) * broccoliSpeedMultiplier; broccoli.dA = 7f; }

The first part of the of the method determines what off screen point the broccoli object will spawn from, using two random numbers. The second part determines how fast the broccoli will travel, which is determined by the current score. It will get faster for every five broccoli the player successfully dodges. The third part sets the direction of the broccoli sprite’s motion. It heads in the direction of the player avatar (dino) when the broccoli is spawned. We also give it a dA value of 7f, which will cause the broccoli to spin through the air as it chases the player. 6. Program game starting state

Before we can move on to handling keyboard input, we need a method that sets the initial game state of the two objects we’ve created. Rather than the game starting as soon as the app runs, we want the user to start it manually, by pressing the spacebar. Add the following code, which sets the initial state of the animated objects, and resets the score: public void StartGame() { dino.x = screenWidth / 2; dino.y = screenHeight * SKYRATIO; broccoliSpeedMultiplier = 0.5f; SpawnBroccoli(); score = 0; }

1. Handle keyboard input Next we need a new method to handle user input via the keyboard. Add this this method to Game1.cs:

void KeyboardHandler() { KeyboardState state = Keyboard.GetState(); // Quit the game if Escape is pressed. if (state.IsKeyDown(Keys.Escape)) { Exit(); } // Start the game if Space is pressed. if (!gameStarted) { if (state.IsKeyDown(Keys.Space)) { StartGame(); gameStarted = true; spaceDown = true; gameOver = false; } return; } // Jump if Space is pressed if (state.IsKeyDown(Keys.Space) || state.IsKeyDown(Keys.Up)) { // Jump if the Space is pressed but not held and the dino is on the floor if (!spaceDown && dino.y >= screenHeight * SKYRATIO - 1) dino.dY = dinoJumpY; spaceDown = true; } else spaceDown = false; // Handle left and right if (state.IsKeyDown(Keys.Left)) dino.dX = dinoSpeedX * -1; else if (state.IsKeyDown(Keys.Right)) dino.dX = dinoSpeedX; else dino.dX = 0; }

Above we have a series of four if-statements: The first quits the game if the Escape key is pressed. The second starts the game if the Space key is pressed, and the game is not already started. The third makes the dino avatar jump if Space is pressed, by changing its dY property. Note that the player cannot jump unless they are on the “ground” (dino.y = screenHeight * SKYRATIO), and will also not jump if the space key is being help down rather than pressed once. This stops the dino from jumping as soon as the game is started, piggybacking on the same keypress that starts the game. Finally, the last if/else clause checks if the left or right directional arrows are being pressed, and if so changes the dino’s dX property accordingly. Challenge: can you make the keyboard handling method above work with the WASD input scheme as well as the arrow keys? 8. Add logic to the Update method

Next we need to add logic for all of these parts to the Update method in Game1.cs:

float elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds; KeyboardHandler(); // Handle keyboard input // Update animated SpriteClass objects based on their current rates of change dino.Update(elapsedTime); broccoli.Update(elapsedTime); // Accelerate the dino downward each frame to simulate gravity. dino.dY += gravitySpeed; // Set game floor so the player does not fall through it if (dino.y > screenHeight * SKYRATIO) { dino.dY = 0; dino.y = screenHeight * SKYRATIO; } // Set game edges to prevent the player from moving offscreen if (dino.x > screenWidth - dino.texture.Width/2) { dino.x = screenWidth - dino.texture.Width/2; dino.dX = 0; } if (dino.x < 0 + dino.texture.Width/2) { dino.x = 0 + dino.texture.Width/2; dino.dX = 0; } // If the broccoli goes offscreen, spawn a new one and iterate the score if (broccoli.y > screenHeight+100 || broccoli.y < -100 || broccoli.x > screenWidth+100 || broccoli.x < -100) { SpawnBroccoli(); score++; }

9. Draw SpriteClass objects

Finally, add the following code to the Draw method of Game1.cs, just after the last call of spriteBatch.Draw: broccoli.Draw(spriteBatch); dino.Draw(spriteBatch);

In MonoGame, new calls of spriteBatch.Draw will draw over any prior calls. This means that both the broccoli and the dino sprite will be drawn over the existing grass sprite, so they can never be hidden behind it regardless of their position. Try running the game now, and moving around the dino with the arrow keys and the spacebar. If you followed the steps above, you should be able to make your avatar move within the game window, and the broccoli should at an ever-increasing speed.

Render text with SpriteFont Using the code above, we keep track of the player’s score behind the scenes, but we don’t actually tell the player what it is. We also have a fairly unintuitive introduction when the app starts up—the player sees a blue and green window, but has no way of knowing they need to press Space to get things rolling. To fix both these problems, we’re going to use a new kind of MonoGame object called SpriteFonts. 1. Create SpriteFont description files

In the Solution Explorer find the Content folder. In this folder, Right-Click the Content.mgcb file and select Open With. From the popup menu select MonoGame Pipeline, then press OK. In the new window, Right-Click the Content item and select Add -> New Item. Select SpriteFont Description, name it “Score” and press OK. Then, add another SpriteFont description named “GameState” using the same procedure. 2. Edit descriptions

Right click the Content folder in the MonoGame Pipeline and select Open File Location. You should see a folder with the SpriteFont description files that you just created, as well as any images you’ve added to the Content folder so far. You can now close and save the MonoGame Pipeline window. From the File Explorer open both description files in a text editor (Visual Studio, NotePad++, Atom, etc). Each description contains a number of values that describe the SpriteFont. We're going to make a few changes: In Score.spritefont, change the value from 12 to 36. In GameState.spritefont, change the value from 12 to 72, and the value from Arial to Agency. Agency is another font that comes standard with Windows 10 machines, and will add some flair to our intro screen. 3. Load SpriteFonts

Back in Visual Studio, we’re first going to add a new texture for the intro splash screen. Click here to download the image. As before, add the texture to the project by right-clicking the Content and selecting Add -> Existing Item. Name the new item “start-splash.png”. Next, add the following class variables to Game1.cs: Texture2D startGameSplash; SpriteFont scoreFont; SpriteFont stateFont;

Then add these lines to the LoadContent method:

startGameSplash = Content.Load("start-splash"); scoreFont = Content.Load("Score"); stateFont = Content.Load("GameState");

4. Draw the score

Go to the Draw method of Game1.cs and add the following code just before spriteBatch.End(); spriteBatch.DrawString(scoreFont, score.ToString(), new Vector2(screenWidth - 100, 50), Color.Black);

The code above uses the sprite description we created (Arial Size 36) to draw the player’s current score near the top right corner of the screen. 5. Draw horizontally centered text

When making a game, you will often want to draw text that is centered, either horizontally or vertically. To horizontally center the introductory text, add this code to the Draw method just before spriteBatch.End(); if (!gameStarted) { // Fill the screen with black before the game starts spriteBatch.Draw(startGameSplash, new Rectangle(0, 0, (int)screenWidth, (int)screenHeight), Color.White); String title = "VEGGIE JUMP"; String pressSpace = "Press Space to start"; // Measure the size of text in the given font Vector2 titleSize = stateFont.MeasureString(title); Vector2 pressSpaceSize = stateFont.MeasureString(pressSpace); // Draw the text horizontally centered spriteBatch.DrawString(stateFont, title, new Vector2(screenWidth / 2 - titleSize.X / 2, screenHeight / 3), Color.ForestGreen); spriteBatch.DrawString(stateFont, pressSpace, new Vector2(screenWidth / 2 - pressSpaceSize.X / 2, screenHeight / 2), Color.White); }

First we create two Strings, one for each line of text we want to draw. Next, we measure the width and height of each line when printed, using the SpriteFont.MeasureString(String) method. This gives us the size as a Vector2 object, with the X property containing its width, and Y its height. Finally, we draw each line. To center the text horizontally, we make the X value of it’s position vector equal to screenWidth / 2 - textSize.X / 2 Challenge: how would you change the procedure above to center the text vertically as well as horizontally? Try running the game. Do you see the intro splash screen? Does the score count up each time the broccoli respawns?

Collision detection So we have a broccoli that follows you around, and we have a score that ticks up each time a new one spawns—but as it is there is no way to actually lose this game. We need a way to know if the dino and broccoli sprites collide, and if when they do, to declare the game over. 1. Rectangular collision

When detecting collisions in a game, objects are often simplified to reduce the complexity of the math involved. We are going to treat both the player avatar and broccoli obstacle as rectangles for the purpose of detecting collision between them. Open SpriteClass.cs and add a new class variable: const float HITBOXSCALE = .5f;

This value will represent how “forgiving” the collision detection is for the player. With a value of .5f, the edges of the rectangle in which the dino can collide with the broccoli—often call the “hitbox”—will be half of the full size of the texture. This will result in few instances where the corners of the two textures collide, without any parts of the images actually appearing to touch. Feel free to tweak this value to your personal taste. Next, add a new method to SpriteClass.cs: public bool RectangleCollision(SpriteClass otherSprite) { if (this.x + this.texture.Width * this.scale * HITBOXSCALE / 2 < otherSprite.x - otherSprite.texture.Width * otherSprite.scale / 2) return false; if (this.y + this.texture.Height * this.scale * HITBOXSCALE / 2 < otherSprite.y - otherSprite.texture.Height * otherSprite.scale / 2) return false; if (this.x - this.texture.Width * this.scale * HITBOXSCALE / 2 > otherSprite.x + otherSprite.texture.Width * otherSprite.scale / 2) return false; if (this.y - this.texture.Height * this.scale * HITBOXSCALE / 2 > otherSprite.y + otherSprite.texture.Height * otherSprite.scale / 2) return false; return true; }

This method detects if two rectangular objects have collided. The algorithm works by testing to see if there is a gap between any of the side sides of the rectangles. If there is any gap, there is no collision—if no gap exists, there must be a collision. 2. Load new textures

Then, open Game1.cs and add two new class variables, one to store the game over sprite texture, and a Boolean to track the game’s state:

Texture2D gameOverTexture; bool gameOver;

Then, initialize gameOver in the Initialize method: gameOver = false;

Finally, load the texture into gameOverTexture in the LoadContent method: gameOverTexture = Content.Load("game-over");

3. Implement “game over” logic

Add this code to the Update method, just after the KeyboardHandler method is called: if (gameOver) { dino.dX = 0; dino.dY = 0; broccoli.dX = 0; broccoli.dY = 0; broccoli.dA = 0; }

This will cause all motion to stop when the game has ended, freezing the dino and broccoli sprites in their current positions. Next, at the end of the Update method, just before base.Update(gameTime), add this line: if (dino.RectangleCollision(broccoli)) gameOver = true;

This calls the RectangleCollision method we created in SpriteClass, and flags the game as over if it returns true. 4. Add user input for resetting the game

Add this code to the KeyboardHandler method, to allow the user to reset them game if they press Enter: if (gameOver && state.IsKeyDown(Keys.Enter)) StartGame(); gameOver = false; }

5. Draw game over splash and text

Finally, add this code to the Draw method, just after the first call of spriteBatch.Draw (this should be the call that draws the grass texture).

if (gameOver) { // Draw game over texture spriteBatch.Draw(gameOverTexture, new Vector2(screenWidth / 2 - gameOverTexture.Width / 2, screenHeight / 4 - gameOverTexture.Width / 2), Color.White); String pressEnter = "Press Enter to restart!"; // Measure the size of text in the given font Vector2 pressEnterSize = stateFont.MeasureString(pressEnter); // Draw the text horizontally centered spriteBatch.DrawString(stateFont, pressEnter, new Vector2(screenWidth / 2 - pressEnterSize.X / 2, screenHeight - 200), Color.White); }

Here we use the same method as before to draw text horizontally centered (reusing the font we used for the intro splash), as well as centering gameOverTexture in the top half of the window. And we’re done! Try running the game again. If you followed the steps above, the game should now end when the dino collides with the broccoli, and the player should be prompted to restart the game by pressing the Enter key.

Publish to the Windows Store Because we built this game as a UWP app, it is possible to publish this project to the Windows Store. There are a few steps to the process. You must be registered as a Windows Developer. You must use the app submission checklist. The app must be submitted for certification. For more details, see Publishing your Windows Store app.

Plan your Universal Windows Platform (UWP) app 3/6/2017 • 19 min to read • Edit on GitHub

On Microsoft design teams, our process for creating apps consists of five distinct stages: concept, structure, dynamics, visual, and prototype. We encourage you to adopt a similar process and have fun making new experiences for the world to enjoy.

Concept Focus your app When planning your Universal Windows Platform (UWP) app, you should determine not only what your app will do and who it's for, but also what your app will be great at. At the core of every great app is a strong concept that provides a solid foundation. Say you want to create a photo app. Thinking about the reasons users work with, save, and share their photos, you’ll realize that they want to relive memories, connect with others through the photos, and keep the photos safe. These, then, are the things that you want the app to be great at, and you use these experience goals to guide you through the rest of the design process. What's your app about? Start with a broad concept and list all of the things that you want to help users do with your app. For example, suppose you want to build an app that helps people plan their trips. Here are some ideas you might sketch out on the back of a napkin: Get maps of all the places on an itinerary, and take them with you on the trip. Find out about special events happening while you're in a city. Let travel buddies create separate but shareable lists of must-do activities and must-see attractions. Let travel buddies compile all of their photos to share with friends and family. Get recommended destinations based on flight prices. Find a consolidated list of deals for restaurants, shops, and activities around your destination.

What's your app great at? Take a step back and look at your list of ideas to see if a particular scenario really jumps out at you. Challenge yourself to trim the list to just a single scenario that you want to focus on. In the process, you might cross off many good ideas, but saying "no" to them is crucial to making a single scenario great.

After you choose a single scenario, decide how you would explain to an average person what your app is great at by writing it down in one sentence. For example: My travel app is great at helping friends create itineraries collaboratively for group trips. My workout app is great at letting friends track their workout progress and share their achievements with each other. My grocery app is great at helping families coordinate their weekly grocery shopping so they never miss or duplicate a purchase.

This is your app's "great at" statement, and it can guide many design decisions and tradeoffs that you make as you build your app. Focus on the scenarios you want users to experience in your app, and be careful not to turn this into a feature list. It should be about what your users will be able to do, as opposed to what your app will be able to do. The design funnel It’s very tempting—having thought of an idea you like—to go ahead and develop it, perhaps even taking it quite a ways into production. But let’s say you do that and then another interesting idea comes along. It’s natural that you’ll be tempted to stick with the idea you’ve already invested in regardless of the relative merits of the two ideas. If only you’d thought of that other idea earlier in the process! Well, the design funnel is a technique to help uncover your best ideas as early as possible. The term "funnel" comes from its shape. At the wide end of the funnel, many ideas go in and each one is realized as a very low-fidelity design artifact (a sketch, perhaps, or a paragraph of text). As this collection of ideas travels through toward the narrow end of the funnel, the number of ideas is trimmed down while the fidelity of the artifacts representing the ideas increases. Each artifact should capture only the information necessary to judge one idea against another, or to answer a particular question such as "is this usable, or intuitive?". Put no more time and effort into each than that. Some ideas will fall by the wayside as you test them, and you’ll be okay with that because you won’t be invested in them any more than was necessary to judge the idea. Ideas that survive to move further into the funnel will receive successively high-fidelity treatments. In the end, you’ll have a single design artifact that represents the winning idea. This is the idea that won because of its merits, not merely because it came along first. You will have designed the best app you could.

Structure Organization makes everything easier

When you're happy with your concept, you're ready for the next stage—creating your app's blueprint. Information architecture (IA) gives your content the structural integrity it needs. It helps define your app's navigational model and, ultimately, your app's identity. By planning how your content will be organized—and how your users will discover that content—you can get a better idea of how users will experience your app. Good IA not only facilitates user scenarios, but it helps you envision the key screens to start with. The Audible app, for example, launches directly into a hub that provides access to the user's library, store, news, and stats. The experience is focused, so users can get and enjoy audiobooks quickly. Deeper levels of the app focus on more specific tasks. For related guidelines, see Navigation design basics.

Dynamics Execute your concept If the concept stage is about defining your app's purpose, the dynamics stage is all about executing that purpose. This can be accomplished in many ways, such as using wireframes to sketch out your page flows (how you get from one place to the next within the app to achieve their goals), and thinking about the voice and the words used throughout your app's UI. Wireframes are a quick, low-fidelity tool to help you make critical decisions about your app's user flow. Your app flow should be tightly tied to your "great at" statement, and should help users achieve that single scenario that you want to light up. Great apps have flows that are easy to learn, and require minimal effort. Start thinking on a screen-to-screen level—see your app as if you're using it for the first time. When you pinpoint user scenarios for pages you create, you'll give people exactly what they want without lots of unnecessary screen touches. Dynamics are also about motion. The right motion capabilities will determine fluidity and ease of use from one page to the next. Common techniques to help with this step: Outline the flow: What comes first, what comes next? Storyboard the flow: How should users move through your UI to complete the flow? Prototype: Try out the flow with a quick prototype. What should users be able to do? For example, the travel app is "great at helping friends collaboratively create itineraries for group trips." Let's list the flows that we want to enable: Create a trip with general information. Invite friends to join a trip. Join a friend's trip. See itineraries recommended by other travelers. Add destinations and activities to trips. Edit and comment on destinations and activities that friends added.

Share itineraries for friends and families to follow.

Visual Speak without words

Once you've established the dynamics of your app, you can make your app shine with the right visual polish. Great visuals define not only how your app looks, but how it feels and comes alive through animation and motion. Your choice of color palette, icon, and artwork are just a few examples of this visual language. All apps have their own unique identity, so explore the visual directions you can take with your app. Let the content guide the look and feel; don't let the look dictate your content.

Prototype Refine your masterpiece Prototyping is a stage in the design funnel—a technique we talked about earlier—at which the artifact representing your idea develops into something more than a sketch, but less complicated than a complete app. A prototype might be a flow of hand-drawn screens shown to a user. The person running the test might respond to cues from the user by placing different screens down, or sticking or unsticking smaller pieces of UI on the pages, to simulate a running app. Or, a prototype might be a very simple app that simulates some workflows, provided the operator sticks to a script and pushes the right buttons. At this stage, your ideas begin to really come alive and your hard work is tested in earnest. When prototyping areas of your app, take the time to sculpt and refine the components that need it the most. To new developers, we can't stress enough: Making great apps is an iterative process. We recommend that you prototype early and often. Like any creative endeavor, the best apps are the product of intensive trial and error.

Decide what features to include When you know what your users want and how you can help them get there, you can look at the specific tools in your toolbox. Explore the Universal Windows Platform (UWP) and associate features with your app's needs. Be sure to follow the user experience (UX) guidelines for each feature. Common techniques: Platform research: Find out what features the platform offers and how you can use them. Association diagrams: Connect your flows with features. Prototype: Exercise the features to ensure that they do what you need.

App contracts Your app can participate in app contracts that enable broad, cross-app, cross-feature user flows. Share Let your users share content from your app with other people through other apps, and receive shareable content from other people and apps, too. Play To Let your users enjoy audio, video, or images streamed from your app to other devices in their home network. File picker and file picker extensions Let your users load and save their files from the local file system, connected storage devices, HomeGroup, or even other apps. You can also provide a file picker extension so other apps can load your app's content. For more info, see App contracts and extensions. Different views, form factors, and hardware configurations Windows puts users in charge and your app in the forefront. You want your app UI to shine on any device, using any input mode, in any orientation, in any hardware configuration, and in whatever circumstance the user decides to use it. Touch first Windows provides a unique and distinctive touch experience that does more than simply emulate mouse functionality. For example, semantic zoom is a touch-optimized way to navigate through a large set of content. Users can pan or scroll through categories of content, and then zoom in on those categories to view more and more detailed information. You can use this to present your content in a more tactile, visual, and informative way than with traditional navigation and layout patterns like tabs. Of course, you can take advantage of a number of touch interactions, like rotate, pan, swipe, and others. Learn more about Touch and other user interactions. Engaging and fresh Be sure your app feels fresh and engages users with these standard experiences: Animations Use our library of animations to make your app fast and fluid for your users. Help users understand context changes and tie experiences together with visual transitions. Learn more about animating your UI. Toast notifications Let your users know about time-sensitive or personally relevant content through toast notifications, and invite them back to your app even when your app is closed. Learn more about tiles, badges, and toast notifications. App tiles Provide fresh and relevant updates to entice users back into your app. There's more info about this in the next section. Learn more about app tiles. Personalization Settings Let your users create the experience they want by saving app settings. Consolidate all of your settings on one screen, and then users can configure your app through a common mechanism that they are already familiar with. Learn more about Adding app settings. Roaming Create a continuous experience across devices by roaming data that lets users pick up a task right where they left off and preserves the UX they care most about, regardless of the device they're using. Make it easy to use your app anywhere—their kitchen family PC, their work PC, their personal tablet, and other form factors—by maintaining settings and states with roaming. Learn more about Managing application data and see Guidelines for roaming application data. User tiles Make your app more personal to your users by loading their user tile image, or let the users set content from your app as their personal tile throughout Windows. Device capabilities Be sure your app takes full advantage of the capabilities of today's devices. Proximity gestures Let your users connect devices with other users who are physically in close proximity, by physically tapping the devices together (multiplayer games). Learn more about proximity and tapping. Cameras and external storage devices Connect your users to their built-in or plugged-in cameras for

chatting and conferencing, recording vlogs, taking profile pics, documenting the world around them, or whatever activity your app is great at. Learn more about Accessing content on removable storage. Accelerometers and other sensors Devices come with a number of sensors nowadays. Your app can dim or brighten the display based on ambient light, reflow the UI if the user rotates the display, or react to any physical movement. Learn more about sensors. Geolocation Use geolocation information from standard web data or from geolocation sensors to help your users get around, find their position on a map, or get notices about nearby people, activities, and destinations. Learn more about geolocation. Let's consider the travel app example again. To be great at helping friends collaboratively create itineraries for group trips, you could use some of these features, just to name a few: Share: Users share upcoming trips and their itineraries to multiple social networks to share the pre-trip excitement with their friends and families. Search: Users search for and find activities or destinations from others' shared or public itineraries that they can include in their own trips. Notifications: Users are notified when travel companions update their itineraries. Settings: Users configure the app to their preference, like which trip should bring up notifications or which social groups are allowed to search the users' itineraries. Semantic zoom: Users navigate through the timeline of their itinerary and zoom in to see greater details of the long list of activities they've planned. User tiles: Users choose the picture they want to appear when they share their trip with friends.

Decide how to monetize your app You have a lot of options for earning money from your app. If you decide to use in-app ads or sales, you'll want to design your UI to support that. For more information, see Plan for monetization.

Design the UX for your app This is about getting the basics right. Now that you know what your app is great at, and you've figured out the flows that you want to support, you can start to think about the fundamentals of user experience (UX) design. How should you organize UI content? Most app content can be organized into some form of groupings or hierarchies. What you choose as the top-level grouping of your content should match the focus of your "great at" statement. To use the travel app as an example, there are multiple ways to group itineraries. If the focus of the app is discovering interesting destinations, you might group them based on interest, like adventure, fun in the sun, or romantic getaways. However, because the focus of the app is planning trips with friends, it makes more sense to organize itineraries based on social circles, like family, friends, or work. Choosing how you want to group your content helps you decide what pages or views you need in your app. See UI basics for more info. How should you present UI content? After you've decided how to organize your UI, you can define UX goals that specify how your UI gets built and presented to your user. In any scenario, you want to make sure that your user can continue using and enjoying your app as quickly as possible. To do this, decide what parts of your UI need to be presented first, and make sure that those parts are complete before you spend time building the noncritical parts. In the travel app, probably the first thing the user will want to do in the app is find a specific trip itinerary. To present this info as fast as possible, you should show the list of trips first, using a ListView control.

After showing the trips list, you could start loading other features, like a news feed of their friends' trips. What UI surfaces and commands do you need? Review the flows that you identified earlier. For each flow, create a rough outline of the steps users take. Let's look at the "Share itineraries for friends and families to follow" flow. We'll assume that the user has already created a trip. Sharing a trip itinerary might require these steps: 1. 2. 3. 4. 5. 6. 7.

The user opens the app and sees a list of trips she created. The user taps on the trip she wants to share. The details of the trip appear on screen. The user accesses some UI to initiate sharing. The user selects or enters the email address or name of the friend she wants to share the trip with. The user accesses some UI to finalize sharing. Your app updates the trip details with the list of people she has shared her trip with.

During this process, you begin to see what UI you need to create and the additional details you need to figure out (like drafting a standard email boilerplate for friends who aren't using your app yet). You also can start eliminating unnecessary steps. Perhaps the user doesn't actually need to see the details of the trip before sharing, for example. The cleaner the flow, the easier to use. For more details on how to use different surfaces, take a look at . What should the flow feel like? When you have defined the steps your user will take, you can turn that flow into performance goals. For more info, see Plan for performance. How should you organize commands? Use your outline of the flow steps to identify potential commands that you need to design for. Then think about where to use those commands in your app. Always try to use the content. Whenever possible, let users directly manipulate the content on the app's canvas, rather than adding commands that act on the content. For example, in the travel app, let users rearrange their itinerary by dragging and dropping activities in a list on the canvas, rather than by selecting the activity and using Up or Down command buttons. If you can't use the content. Place commands on one of these UI surfaces if you are not able to use the content: In the command bar: You should put most commands on the command bar, which is usually hidden until the user taps to make it visible. On the app's canvas: If the user is on a page or view that has a single purpose, you can provide commands for that purpose directly on the canvas. There should be very few of these commands. In a context menu: You can use context menus for clipboard actions (such as cut, copy, and paste), or for

commands that apply to content that cannot be selected (like adding a push pin to a location on a map). Decide how to lay out your app in each view. Windows supports landscape and portrait orientations and supports resizing apps to any width, from full screen to a minimum width. You want your app to look and work great at any size, on any screen, in either orientation. This means you need to plan the layout of your UI elements for different sizes and views. When you do this, your app UI changes fluidly to meet your user's needs and preferences.

For more info on designing for different screen sizes, see .

Make a good first impression Think about what you want users to think, feel, or do when they first launch your app. Refer back to your "great at" statement. Even though you won't get a chance to personally tell your users what your app is great at, you can convey the message to them when you make your first impression. Take advantage of these: Tile and notifications The tile is the face of your app. Among the many other apps on a user's Start screen, what will make the user want to launch your app? Be sure your tile highlights your app's brand and shows what the app is great at. Use tile notifications so your app will always feel fresh and relevant, bringing the user back to your app again and again. Splash screen The splash screen should load as fast as possible, and remain on the screen only as long as you need to initialize your app state. What you show on the splash screen should express your app's personality. First launch Before users sign up for your service, log in to their account, or add their own content, what will they see? Try to demonstrate the value of your app before asking users for information. Consider showing sample content so people can look around and understand what your app does before you ask them to commit. Home page The home page is where you bring users each time they launch your app. The content here should have a clear focus, and immediately showcase what your app is tailored to do. Make this page great at one thing and trust that people will explore the rest of your app. Focus on eliminating distractions on the landing page, and not on discoverability.

Validate your design Before you get too far into developing your app, you should validate your design or prototype against guidelines, user impressions, and requirements to avoid having to rework it later. Each feature has a set of UX guidelines to help you polish your app, and a set of Store requirements that you must meet to publish your app in the Windows Store. You can use the Windows App Certification Kit to test for technical compliance with Store requirements. You can also use the performance tools in Microsoft Visual Studio to make sure that you're giving your users a great experience in every scenario.

Use the detailed UX guidelines for UWP apps to stay focused on important features. Use the Visual Studio performance tools to analyze the performance of each of your app's scenarios.

3/6/2017 • 3 min to read • Edit on GitHub

What's next? So you want to write an app and publish it to the Windows Store: where do you start? If you're completely new to the UWP platform, try some of the Channel 9 videos and Microsoft Virtual Academy and LinkedIn Learning courses. If you are already familiar with Windows development, you can start reading through the topics below, or go straight to downloading some samples. There are many tools and frameworks available to help you write apps, and many support cross-platform development. For example, if you want to write 2D games, you might want to look at Monogame or some of the many JavaScript/HTML frameworks. For 3D games, there's Unity, and don't forget Xamarin if your focus is mobile devices. If you want to get started writing something that isn't a game, our recommendation is that you look through the UWP topics to get a feel for the platform, and then investigate creating your user interface by using, and then customizing, XAML controls. You'll use XAML to design your app (here's a tutorial that will walk you through it), but XAML's main strength is the use of data binding which couples the controls to the information your app wants to display: if you are new to the Windows platform, this will be an important concept to understand.

UWP and the UWP app Lifecycle How does an app start, what happens when you start another one? Here’s the story. Guide to Universal Windows Platform (UWP) apps UWP app lifecycle What's cool in Windows 10

UX and UI What controls do you have at your disposal, and how can they be used? These topics explain how controls and code work together, and how you can customize them to suit the look of your app. Design and UI Define page layouts with XAML Controls by function Intro to controls and patterns Styling controls Screen sizes and break points for responsive design Use the UWP Community Toolkit for a selection of prebuilt controls and patterns

Data and Services Learn about data binding, which lets your code automatically populate lists and grids. Discover how to link to external resources to get data into your apps. Data binding ListViews, GridViews and data binding Data access

Publishing Share your work with the world, make money. We’ll walk you through the process of getting your app onto the store. Publish Windows apps Packaging apps

Other resources Samples, tutorials, videos, other tools and SDKs. Take it to the next level. How-to articles Code samples C# reference API Reference Writing apps for Xbox One Developing for HoloLens Porting apps to Windows 10 Writing apps for the Enterprise The UWP Community Toolkit

Windows Developer Blog The Windows Developer Blog includes regular postings on the latest in coding techniques, project ideas, and tools. Here are some you might find useful as you explore Windows development. Animations with the Visual layer Interop between XAML and the Visual layer Creating beautiful effects for UWP Beautiful apps made possible and easy with Windows.UI Polishing your app with animation and audio cues Adding color to your design

Finding help in the Dev Center The docs.microsoft.com site contains a multitude of documentation for many different tools, frameworks and platforms. When you are browsing for topics and samples, you should make sure you are reading UWP specific content. You'll find the UWP reference starts at the Windows Dev Center, and the API reference you need is at Develop UWP apps. When reading content taht is specifically for UWP, the URL path will contain uwp, and so will the path displayed at the top of the page, like this:

When using a search engine, appending "Windows app development" to your search string will more often than not lead you to UWP content.

Important Dev Center topics Here is a list of the key sections of content in the DevCenter. Design

Design guidelines for UWP apps.

Develop

Detailed info and coding examples for the many of the features available to your app.

Language reference

The programming languages available for UWP development.

Games

Developing games with DirectX.

Internet of Things

Building your own connected devices.

Porting

Leverage your Android and iOS skills to quickly make UWP apps.

Windows Bridges

Tools for updating older apps and iOS apps to UWP.

Xamarin

Use C# to write apps for iOS, Android and Windows 10.

Task snippets

Ready-to-use code that accomplish small but useful tasks.

How-to topics

Sample code covering specific UWP features.

Hardware

Hardware for developers from the Microsoft Store.

Get the Universal Windows Platform (UWP) samples from GitHub 3/6/2017 • 1 min to read • Edit on GitHub

The UWP app samples are available through repositories on GitHub. If this is your first time working with UWP, you'll want to start with the Microsoft/Windows-universal-samples repository, which contains samples that demonstrate all of the UWP features and their API usage patterns.

Additional samples can be found using the Samples section of the Dev Center.

Download the code To download the samples, go to the repository and select Clone or download, then Download ZIP. Or, just click here. The zip file will always have the latest samples. You don’t need a GitHub account to download it. When an SDK update is released or if you want to pick up any recent changes/additions, just check back for the latest zip file.

Note: The UWP samples require Visual Studio 2015 and the Windows SDK to open, build, and run. If you don’t have Visual Studio already installed, you can get a free copy of Visual Studio 2015 Community Edition with support for building UWP apps here. Also, be sure to unzip the entire archive, and not just individual samples. The samples all depend on the SharedContent folder in the archive. The UWP feature samples use Linked files in Visual Studio to reduce duplication of common files, including sample template files and image assets. These common files are stored in the SharedContent folder at the root of the repository, and are referred to in the project files using links. After you download the zip file, open the samples in Visual Studio: 1. Before you unzip the archive, right-click it, select Properties > Unblock > Apply. Then, unzip the archive to a local folder on your machine.

2. Within the samples folder, you’ll see a number of folders, each of which contains a UWP feature sample.

3. Select a sample, such as Altimeter, and you’ll see multiple folders indicating the languages supported.

4. Select the language you’d like to use, such as CS for C#, and you’ll see a Visual Studio solution file, which you can open in Visual Studio.

Give feedback, ask questions, and report issues If you have problems or questions, just use the Issues tab on the repository to create a new issue and we’ll do what we can to help.

Layout for UWP apps 3/6/2017 • 2 min to read • Edit on GitHub

App structure, page layout, and navigation are the foundation of your app's user experience. The articles in this section help you create an app that is easy to navigate and looks great on a variety of devices and screen sizes.

Intro Intro to app UI design When you design a UWP app, you create a user interface that suits a variety of devices with different display sizes. This article provides an overview of UI-related features and benefits of UWP apps and some tips & tricks for designing a responsive UI.

App layout and structure Check out these recommendations for structuring your app and using the three types of UI elements: navigation, command, and content. Navigation basics Navigation in UWP apps is based on a flexible model of navigation structures, navigation elements, and systemlevel features. This article introduces you to these components and shows you how to use them together to create a good navigation experience. Content basics The main purpose of any app is to provide access to content: in a photo-editing app, the photo is the content; in a travel app, maps and info about travel destinations is the content; and so on. This article provides content design recommendations for the three content scenarios: consumption, creation, and interaction. Command basics Command elements are the interactive UI elements that enable the user to perform actions, such as sending an email, deleting an item, or submitting a form. This article describes the command elements, such as buttons and check boxes, the interactions they support, and the command surfaces (such as command bars and context menus) for hosting them.

Page layout These articles help you create a flexible UI that looks great on different screen sizes, window sizes, resolutions, and orientations.

Screen sizes and breakpoints The number of device targets and screen sizes across the Windows 10 ecosystem is too great to worry about optimizing your UI for each one. Instead, we recommended designing for a few key widths (also called "breakpoints"): 360, 640, 1024 and 1366 epx. Define layouts with XAML How to use XAML properties and layout panels to make your app responsive and adaptive.

Layout panels Learn about each type of layout each panel and show how to use them to layout XAML UI elements. Alignment, margins, and padding In addition to dimension properties (width, height, and constraints) elements can also have alignment, margin, and padding properties that influence the layout behavior when an element goes through a layout pass and is rendered in a UI.

Introduction to UWP app design 3/6/2017 • 10 min to read • Edit on GitHub

A Universal Windows Platform (UWP) app can run on any Windows-based device, from your phone to your tablet or PC.

Designing an app that looks good on such a wide variety of devices can be a big challenge. So how do you go about designing an app that provides a great UX on devices with dramatically different screen sizes and input methods? Fortunately, the Universal Windows Platform (UWP) provides a set of built-in features and universal building blocks that help you do just that.

This articles describes the UI features and benefits of UWP apps and provides some high-level design guidance for creating your first UWP app. Let's start by taking a look at some of the features that you get when you create a UWP app.

UWP app features Effective pixels and scaling

UWP apps automatically adjust the size of controls, fonts, and other UI elements so that they are legible on all devices. When your app runs on a device, the system uses an algorithm to normalize the way UI elements display on the screen. This scaling algorithm takes into account viewing distance and screen density (pixels per inch) to optimize

for perceived size (rather than physical size). The scaling algorithm ensures that a 24 px font on Surface Hub 10 feet away is just as legible to the user as a 24 px font on 5' phone that's a few inches away.

Because of how the scaling system works, when you design your UWP app, you're designing in effective pixels, not actual physical pixels. So, how does that impact the way you design your app? You can ignore the pixel density and the actual screen resolution when designing. Instead, design for the effective resolution (the resolution in effective pixels) for a size class (for details, see the Screen sizes and breakpoints article). When the system scales your UI, it does so by multiples of 4. To ensure a crisp appearance, snap your designs to the 4x4 pixel grid: make margins, sizes and positions of UI elements, and the position (but not the size—text can be any size) of text a multiple of 4 effective pixels. This illustration shows design elements that map to the 4x4 pixel grid. The design element will always have crisp, sharp edges.

The next illustration shows design elements that don't map to the 4x4 grid. These design elements will have blurry, soft edges on some devices.

TIP When creating screen mockups in image editing programs, set the DPI to 72 and set the image dimensions to the effective resolution for the size class you're targeting. (For a list of size classes and effective resolutions, see the Recommendations for specific size classes section of this article.)

Universal input and smart interactions

Another built-in capability of the UWP is universal input enabled via smart interactions. Although you can design your apps for specific input modes and devices, you aren’t required to. That’s because Universal Windows apps by default rely on smart interactions. That means you can design around a click interaction without having to know or define whether the click comes from an actual mouse click or the tap of a finger. Universal controls and styles

The UWP also provides some useful building blocks that make it easier to design apps for multiple device families. Universal controls The UWP provides a set of universal controls that are guaranteed to work well on all Windows-powered devices. This set of universal controls includes everything from common form controls like radio button and text box to sophisticated controls like grid view and list view that can generate lists of items from a stream of data and a template. These controls are input-aware and deploy with the proper set of input affordances, event states, and overall functionality for each device family. For a complete list of these controls and the patterns you can make from them, see the Controls and patterns section. Universal styles Your UWP app automatically gets a default set of styles that gives you these features: A set of styles that automatically gives your app a light or dark theme (your choice) and can incorporate the user's accent color preference.

A Segoe-based type ramp that ensures that app text looks crisp on all devices. Default animations for interactions. Automatic support for high-contrast modes. Our styles were designed with high-contrast in mind, so when your app runs on a device in high-contrast mode, it will display properly. Automatic support for other languages. Our default styles automatically select the correct font for every language that Windows supports. You can even use multiple languages in the same app and they'll be displayed properly. Built-in support for RTL reading order. You can customize these default styles to give your app a personal touch, or you can completely replace them with your own to create a unique visual experience. For example, here's a design for a weather app with a unique visual style:

Now that we've described the building blocks of UWP apps, let's take a look at how to put them together to create

a UI.

The anatomy of a typical UWP app A modern user interface is a complex thing, made up of text, shapes, colors, and animations which are ultimately made up out of individual pixels of the screen of the device you're using. When you start designing a user interface, the sheer number of choices can be overwhelming. To make things simpler, let's define the anatomy of an app from a design perspective. Let's say that an app is made up of screens and pages. Each page has a user interface, made up of three types of UI elements: navigation, commanding, and content elements. Navigation elements Navigation elements help users choose the content they want to display. Examples of navigation elements include tabs and pivots, hyperlinks, and nav panes. Navigation elements are covered in detail in the Navigation design basics article. Command elements Command elements initiate actions, such as manipulating, saving, or sharing content. Examples of command elements include button and the command bar. Command elements can also include keyboard shortcuts that aren't actually visible on the screen. Command elements are covered in detail in the Command design basics article. Content elements Content elements display the app's content. For a painting app, the content might be a drawing; for a news app, the content might be a news article. Content elements are covered in detail in the Content design basics article.

At a minimum, an app has a splash screen and a home page that defines the user interface. A typical app will have multiple pages and screens, and navigation, command, and content elements might change from page to page. When deciding on the right UI elements for your app, you might also consider the devices and the screen sizes your app will run on.

Tailoring your app for specific devices and screen sizes. UWP apps use effective pixels to guarantee that your design elements will be legible and usable on all Windowspowered devices. So, why would you ever want to customize your app's UI for a specific device family? Note Before we go any further, Windows doesn't provide a way for your app to detect the specific device your app is running on. It can tell you the device family (mobile, desktop, etc) the app is running on, the effective resolution, and the amount of screen space available to the app (the size of the app's window). To make the most effective use of space and reduce the need to navigate If you design an app to look good on a device that has a small screen, such as a phone, the app will be usable on a PC with a much bigger display, but there will probably be some wasted space. You can

customize the app to display more content when the screen is above a certain size. For example, a shopping app might display one merchandise category at a time on a phone, but show multiple categories and products simultaneously on a PC or laptop. By putting more content on the screen, you reduce the amount of navigation that the user needs to perform. To take advantage of devices' capabilities Certain devices are more likely to have certain device capabilities. For example, phones are likely to have a location sensor and a camera, while a PC might not have either. Your app can detect which capabilities are available and enable features that use them. To optimize for input The universal control library works with all input types (touch, pen, keyboard, mouse), but you can still optimize for certain input types by re-arranging your UI elements. For example, if you place navigation elements at the bottom of the screen, they'll be easier for phone users to access—but most PC users expect to see navigation elements toward the top of the screen.

Responsive design techniques When you optimize your app's UI for specific screen widths, we say that you're creating a responsive design. Here are six responsive design techniques you can use to customize your app's UI. Reposition

You can alter the location and position of app UI elements to get the most out of each device. In this example, the portrait view on phone or phablet necessitates a scrolling UI because only one full frame is visible at a time. When the app translates to a device that allows two full on-screen frames, whether in portrait or landscape orientation, frame B can occupy a dedicated space. If you're using a grid for positioning, you can stick to the same grid when UI elements are repositioned.

In this example design for a photo app, the photo app repositions its content on larger screens.

Resize

You can optimize the frame size by adjusting the margins and size of UI elements. This could allow you, as the example here shows, to augment the reading experience on a larger screen by simply growing the content frame.

Reflow

By changing the flow of UI elements based on device and orientation, your app can offer an optimal display of content. For instance, when going to a larger screen, it might make sense to switch larger containers, add columns, and generate list items in a different way. This example shows how a single column of vertically scrolling content on phone or phablet can be reflowed on a larger screen to display two columns of text.

Reveal

You can reveal UI based on screen real estate, or when the device supports additional functionality, specific situations, or preferred screen orientations. In this example with tabs, the middle tab with the camera icon might be specific to the app on phone or phablet and not be applicable on larger devices, which is why it's revealed in the device on the right. Another common example of revealing or hiding UI applies to media player controls, where the button set is reduced on smaller devices and expanded on larger devices. The media player on PC, for instance, can handle far more on-screen functionality than it can on a phone.

Part of the reveal-or-hide technique includes choosing when to display more metadata. When real estate is at a premium, such as with a phone or phablet, it's best to show a minimal amount of metadata. With a laptop or desktop PC, a significant amount of metadata can be surfaced. Some examples of how to handle showing or hiding metadata include: In an email app, you can display the user's avatar. In a music app, you can display more info about an album or artist. In a video app, you can display more info about a film or a show, such as showing cast and crew details. In any app, you can break apart columns and reveal more details.

In any app, you can take something that's vertically stacked and lay it out horizontally. When going from phone or phablet to larger devices, stacked list items can change to reveal rows of list items and columns of metadata. Replace

This technique lets you switch the user interface for a specific device size-class or orientation. In this example, the nav pane and its compact, transient UI works well for a smaller device, but on a larger device tabs might be a better choice.

Re-architect

You can collapse or fork the architecture of your app to better target specific devices. In this example, going from the left device to the right device demonstrates the joining of pages.

Here's an example of this technique applied to the design for a smart home app.

Related articles What's a UWP app?

Navigation design basics for UWP apps 3/6/2017 • 6 min to read • Edit on GitHub

Navigation in Universal Windows Platform (UWP) apps is based on a flexible model of navigation structures, navigation elements, and system-level features. Together, they enable a variety of intuitive user experiences for moving between apps, pages, and content. In some cases, you might be able to fit all of your app's content and functionality onto a single page without requiring the user to do anything more than pan to navigate through that content. However, the majority of apps typically have multiple pages of content and functionality with which to explore, engage, and interact. When an app has more than one page, you need to provide the right navigation experience. To be successful and make sense to users, multi-page navigation experiences in UWP apps include (described in detail later): The right navigation structure Building a navigation structure that makes sense to the user is crucial to creating an intuitive navigation experience. Compatible navigation elements that support the chosen structure. Navigation elements can help the user get to the content they want and can also let users know where they are within the app. However, they also take up space that could be used for content or commanding elements, so it's important to use the navigation elements that are right for your app's structure. Appropriate responses to system-level navigation features (such as Back) To provide a consistent experience that feels intuitive, respond to system-level navigation features in predictable ways.

Build the right navigation structure Let's look at an app as a collection of groups of pages, with each page containing a unique set of content or functionality. For example, a photo app might have a page for taking photos, a page for image editing, and another page for managing your image library. The way you arrange these pages into groups defines the app's navigation structure. There are two common ways to arrange a group of pages: IN A HIERARCHY

AS PEERS

Pages are organized into a tree-like structure. Each child page has only one parent, but a parent can have one or more child pages. To reach a child page, you travel through the parent.

Pages exist side-by-side. You can go from one page to another in any order.

A typical app will use both arrangements, with some portions being arranged as peers and some portions being arranged into hierarchies.

So, when should you arrange pages into hierarchies and when you should arrange them as peers? To answer that question we must consider the number of pages in the group, whether the pages should be traversed in a particular order, and the relationship between the pages. In general, flatter structures are easier to understand and faster to navigate, but sometimes it's appropriate to have a deep hierarchy. We recommend using a hierarchical relationship when You expect the user to traverse the pages in a specific order. Arrange the hierarchy to enforce that order. There is a clear parent-child relationship between one of the pages and the other pages in the group. There are more than 7 pages in the group. When there are more than 7 pages in the group, it might be difficult for users to understand how the pages are unique or to understand their current location within the group. If you don't think that's an issue for your app, go ahead and make the pages peers. Otherwise, consider using a hierarchical structure to break the pages into two or more smaller groups. (A hub control can help you group pages into categories.) We recommend using a peer relationship when The pages can be viewed in any order. The pages are clearly distinct from each other and don't have an obvious parent/child relationship. There are fewer than 8 pages in the group. When there are more than 7 pages in the group, it might be difficult for users to understand how the pages are unique or to understand their current location within the group. If you don't think that's an issue for your app, go ahead and make the pages peers. Otherwise, consider using a hierarchical structure to break the pages into two or more smaller groups. (A hub control can help you group pages into categories.)

Use the right navigation elements Navigation elements can provide two services: they help the user get to the content they want, and some elements also let users know where they are within the app. However, they also take up space that the app could use for content or commanding elements, so it's important to use the navigation elements that are just right for your app's structure. Peer-to-peer navigation elements

Peer-to-peer navigation elements enable navigation between pages in the same level of the same subtree.

For peer-to-peer navigation, we recommend using tabs or a navigation pane.

NAVIGATION ELEMENT

DESCRIPTION

Tabs and pivot

Displays a persistent list of links to pages at the same level. Use tabs/pivots when: There are 2-5 pages. (You can use tabs/pivots when there are more than 5 pages, but it might be difficult to fit all the tabs/pivots on the screen.) You expect users to switch between pages frequently. This design for a restaurant-finding app uses tabs/pivots:

Nav pane

Displays a list of links to top-level pages. Use a navigation pane when: You don't expect users to switch between pages frequently. You want to conserve space at the expense of slowing down navigation operations. The pages exist at the top level. This design for a smart home app features a nav pane:

If your navigation structure has multiple levels, we recommend that peer-to-peer navigation elements only link to the peers within their current subtree. Consider the following illustration, which shows a navigation structure that has three levels:

For level 1, the peer-to-peer navigation element should provide access to pages A, B, C, and D. At level 2, the peer-to-peer navigation elements for the A2 pages should only link to the other A2 pages. They should not link to level 2 pages in the C subtree.

Hierarchical navigation elements

Hierarchical navigation elements provide navigation between a parent page and its child pages.

NAVIGATION ELEMENT

DESCRIPTION

Hub

A hub is a special type of navigation control that provides previews/summaries of its child pages. Unlike the navigation pane or tabs, it provides navigation to these child pages through links and section headers embedded in the page itself. Use a hub when: You expect that users would want to view some of the content of the child pages without having to navigate to each one. Hubs promote discovery and exploration, which makes them well suited for media, news-reader, and shopping apps.

Master/details

Displays a list (master view) of item summaries. Selecting an item displays its corresponding items page in the details section. Use the Master/details element when: You expect users to switch between child items frequently. You want to enable the user to perform high-level operations, such as deleting or sorting, on individual items or groups of items, and also want to enable the user to view or update the details for each item. Master/details elements are well suited for email inboxes, contact lists, and data entry. This design for a stock-tracking app makes use of a master/details pattern:

Historical navigation elements

NAVIGATION ELEMENT

DESCRIPTION

Back

Lets the user traverse the navigation history within an app and, depending on the device, from app to app. For more info, see the Navigation history and backwards navigation article.

Content-level navigation elements NAVIGATION ELEMENT

DESCRIPTION

Hyperlinks and buttons

Content-embedded navigation elements appear in a page's content. Unlike other navigation elements, which should be consistent across the page's group or subtree, contentembedded navigation elements are unique from page to page.

Combining navigation elements

You can combine navigation elements to create a navigation experience that's right for your app. For example, your app might use a nav pane to provide access to top-level pages and tabs to provide access to second-level pages.

Navigation history and backwards navigation for UWP apps 3/6/2017 • 7 min to read • Edit on GitHub

On the Web, individual web sites provide their own navigation systems, such as tables of contents, buttons, menus, simple lists of links, and so on. The navigation experience can vary wildly from website to website. However, there is one consistent navigation experience: back. Most browsers provide a back button that behaves the same way regardless of the website. For similar reasons, the Universal Windows Platform (UWP) provides a consistent back navigation system for traversing the user's navigation history within an app and, depending on the device, from app to app. The UI for the system back button is optimized for each form factor and input device type, but the navigation experience is global and consistent across devices and UWP apps. Here are the primary form factors with the back button UI:

Devices

Back button behavior

Phone

Always present. A software or hardware button at the bottom of the device. Global back navigation within the app and between apps.

Tablet

Always present in Tablet mode. Not available in Desktop mode. Title bar back button can be enabled, instead. See PC, Laptop, Tablet. Users can switch between running in Tablet mode and Desktop mode by going to Settings > System > Tablet mode and setting Make Windows more touch-friendly when using your device as a tablet. A software button in the navigation bar at the bottom of the device. Global back navigation within the app and between apps.

PC, Laptop, Tablet

Optional in Desktop mode. Not available in Tablet mode. See Tablet. Disabled by default. Must opt in to enable it. Users can switch between running in Tablet mode and Desktop mode by going to Settings > System > Tablet mode and setting Make Windows more touchfriendly when using your device as a tablet. A software button in the title bar of the app. Back navigation within the app only. Does not support app-toapp navigation.

Surface Hub

Optional. Disabled by default. Must opt in to enable it. A software button in the title bar of the app. Back navigation within the app only. Does not support app-toapp navigation.

Here are some alternative input types that don't rely on a back button UI, but still provide the exact same functionality. Input devices Keyboard

Windows key + Backspace

Cortana

Say, "Hey Cortana, go back"

When your app runs on a phone, tablet, or on a PC or laptop that has system back enabled, the system notifies your app when the back button is pressed. The user expects the back button to navigate to the previous location in the app's navigation history. It's up to you to decide which navigation actions to add to the navigation history and how to respond to the back button press.

How to enable system back navigation support Apps must enable back navigation for all hardware and software system back buttons. Do this by registering a listener for the BackRequested event and defining a corresponding handler. Here we register a global listener for the BackRequested event in the App.xaml code-behind file. You can register for this event in each page if you want to exclude specific pages from back navigation, or you want to execute page-level code before displaying the page.

Windows.UI.Core.SystemNavigationManager.GetForCurrentView().BackRequested += App_BackRequested;

Windows::UI::Core::SystemNavigationManager::GetForCurrentView()-> BackRequested += ref new Windows::Foundation::EventHandler< Windows::UI::Core::BackRequestedEventArgs^>( this, &App::App_BackRequested);

Here's the corresponding BackRequested event handler that calls GoBack on the root frame of the app. This handler is invoked on a global back event. If the in-app back stack is empty, the system might navigate to the previous app in the app stack or to the Start screen. There is no app back stack in Desktop mode and the user stays in the app even when the in-app back stack is depleted. private void App_BackRequested(object sender, Windows.UI.Core.BackRequestedEventArgs e) { Frame rootFrame = Window.Current.Content as Frame; if (rootFrame == null) return; // Navigate back if possible, and if the event has not // already been handled . if (rootFrame.CanGoBack && e.Handled == false) { e.Handled = true; rootFrame.GoBack(); } }

void App::App_BackRequested( Platform::Object^ sender, Windows::UI::Core::BackRequestedEventArgs^ e) { Frame^ rootFrame = dynamic_cast(Window::Current->Content); if (rootFrame == nullptr) return; // Navigate back if possible, and if the event has not // already been handled. if (rootFrame->CanGoBack && e->Handled == false) { e->Handled = true; rootFrame->GoBack(); } }

How to enable the title bar back button Devices that support Desktop mode (typically PCs and laptops, but also some tablets) and have the setting enabled (Settings > System > Tablet mode), do not provide a global navigation bar with the system back button. In Desktop mode, every app runs in a window with a title bar. You can provide an alternative back button for your app that is displayed in this title bar. The title bar back button is only available in apps running on devices in Desktop mode, and only supports in-app navigation history—it does not support app-to-app navigation history.

Important The title bar back button is not displayed by default. You must opt in.

Desktop mode, no back navigation.

Desktop mode, back navigation enabled.

Override the OnNavigatedTo event and set AppViewBackButtonVisibility to Visible in the code-behind file for each page that you want to enable the title bar back button. For this example, we list each page in the back stack and enable the back button if the CanGoBack property of the frame has a value of true. protected override void OnNavigatedTo(NavigationEventArgs e) { Frame rootFrame = Window.Current.Content as Frame; string myPages = ""; foreach (PageStackEntry page in rootFrame.BackStack) { myPages += page.SourcePageType.ToString() + "\n"; } stackCount.Text = myPages; if (rootFrame.CanGoBack) { // Show UI in title bar if opted-in and in-app backstack is not empty. SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Visible; } else { // Remove the UI from the title bar if in-app back stack is empty. SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Collapsed; } }

void StartPage::OnNavigatedTo(NavigationEventArgs^ e) { auto rootFrame = dynamic_cast(Window::Current->Content); Platform::String^ myPages = ""; if (rootFrame == nullptr) return; for each (PageStackEntry^ page in rootFrame->BackStack) { myPages += page->SourcePageType.ToString() + "\n"; } stackCount->Text = myPages; if (rootFrame->CanGoBack) { // If we have pages in our in-app backstack and have opted in to showing back, do so Windows::UI::Core::SystemNavigationManager::GetForCurrentView()->AppViewBackButtonVisibility = Windows::UI::Core::AppViewBackButtonVisibility::Visible; } else { // Remove the UI from the title bar if there are no pages in our in-app back stack Windows::UI::Core::SystemNavigationManager::GetForCurrentView()->AppViewBackButtonVisibility = Windows::UI::Core::AppViewBackButtonVisibility::Collapsed; } }

Guidelines for custom back navigation behavior

If you choose to provide your own back stack navigation, the experience should be consistent with other apps. We recommend that you follow the following patterns for navigation actions: NAVIGATION ACTION

ADD TO NAVIGATION HISTORY?

Page to page, different peer groups

Yes In this illustration, the user navigates from level 1 of the app to level 2, crossing peer groups, so the navigation is added to the navigation history.

In the next illustration, the user navigates between two peer groups at the same level, again crossing peer groups, so the navigation is added to the navigation history.

NAVIGATION ACTION

ADD TO NAVIGATION HISTORY?

Page to page, same peer group, no on-screen navigation element The user navigates from one page to another with the same peer group. There is no navigation element that is always present (such as tabs/pivots or a docked navigation pane) that provides direct navigation to both pages.

Yes In the following illustration, the user navigates between two pages in the same peer group. The pages don't use tabs or a docked navigation pane, so the navigation is added to the navigation history.

Page to page, same peer group, with an on-screen navigation element The user navigates from one page to another in the same peer group. Both pages are shown in the same navigation element. For example, both pages use the same tabs/pivots element, or both pages appear in a docked navigation pane.

No When the user presses back, go back to the last page before the user navigated to the current peer group.

Show a transient UI The app displays a pop-up or child window, such as a dialog, splash screen, or on-screen keyboard, or the app enters a special mode, such as multiple selection mode.

No When the user presses the back button, dismiss the transient UI (hide the on-screen keyboard, cancel the dialog, etc) and return to the page that spawned the transient UI.

NAVIGATION ACTION

ADD TO NAVIGATION HISTORY?

Enumerate items The app displays content for an on-screen item, such as the details for the selected item in master/details list.

No Enumerating items is similar to navigating within a peer group. When the user presses back, navigate to the page that preceded the current page that has the item enumeration.

Resuming

When the user switches to another app and returns to your app, we recommend returning to the last page in the navigation history.

Get the samples Back button sample Shows how to set up an event handler for the back button event and how to enable the title bar back button for when the app is in windowed Desktop mode.

Related articles Navigation basics

Peer-to-peer navigation between two pages 3/6/2017 • 7 min to read • Edit on GitHub

Learn how to navigate in a basic two page peer-to-peer Universal Windows Platform (UWP) app.

Important APIs Windows.UI.Xaml.Controls.Frame Windows.UI.Xaml.Controls.Page Windows.UI.Xaml.Navigation

Create the blank app 1. On the Microsoft Visual Studio menu, choose File > New Project. 2. In the left pane of the New Project dialog box, choose the Visual C# -> Windows -> Universal or the Visual C++ -> Windows -> Universal node. 3. In the center pane, choose Blank App. 4. In the Name box, enter NavApp1, and then choose the OK button. The solution is created and the project files appear in Solution Explorer. 5. To run the program, choose Debug > Start Debugging from the menu, or press F5. A blank page is displayed. 6. Press Shift+F5 to stop debugging and return to Visual Studio.

Add basic pages Next, add two content pages to the project. Do the following steps two times to add two pages to navigate between. 1. 2. 3. 4.

In Solution Explorer, right-click the BlankApp project node to open the shortcut menu. Choose Add > New Item from the shortcut menu. In the Add New Item dialog box, choose Blank Page in the middle pane. In the Name box, enter Page1 (or Page2) and press the Add button.

These files should now be listed as part of your NavApp1 project. C#

C++

Page1.xaml Page1.xaml.cs Page2.xaml Page2.xaml.cs

Page1.xaml Page1.xaml.cpp Page1.xaml.h Page2.xaml Page2.xaml.cpp Page2.xaml.h

Add the following content to the UI of Page1.xaml. Add a TextBlock element named Page 1 .

pageTitle

as a child element of the root Grid. Change the Text property to



Add the following HyperlinkButton element as a child element of the root Grid and after the TextBlock element.

pageTitle



Add the following code to the Page1 class in the Page1.xaml code-behind file to handle the HyperlinkButton you added previously. Here, we navigate to Page2.xaml.

Click

event of the

private void HyperlinkButton_Click(object sender, RoutedEventArgs e) { this.Frame.Navigate(typeof(Page2)); }

void Page1::HyperlinkButton_Click(Platform::Object^ sender, RoutedEventArgs^ e) { this->Frame->Navigate(Windows::UI::Xaml::Interop::TypeName(Page2::typeid)); }

Make the following changes to the UI of Page2.xaml. Add a TextBlock element named property to Page 2 .

pageTitle

as a child element of the root Grid. Change the value of the Text



Add the following HyperlinkButton element as a child element of the root Grid and after the TextBlock element.

pageTitle



Add the following code to the Page2 class in the Page2.xaml code-behind file to handle the HyperlinkButton you added previously. Here, we navigate to Page1.xaml.

Click

event of the

NOTE For C++ projects, you must add a #include directive in the header file of each page that references another page. For the inter-page navigation example presented here, page1.xaml.h file contains #include "Page2.xaml.h" , in turn, page2.xaml.h contains #include "Page1.xaml.h" .

private void HyperlinkButton_Click(object sender, RoutedEventArgs e) { this.Frame.Navigate(typeof(Page1)); }

void Page2::HyperlinkButton_Click(Platform::Object^ sender, RoutedEventArgs^ e) { this->Frame->Navigate(Windows::UI::Xaml::Interop::TypeName(Page1::typeid)); }

Now that we've prepared the content pages, we need to make Page1.xaml display when the app starts. Open the app.xaml code-behind file and change the Here, we specify

Page1

OnLaunched

handler.

in the call to Frame.Navigate instead of

MainPage

protected override void OnLaunched(LaunchActivatedEventArgs e) { Frame rootFrame = Window.Current.Content as Frame; // Do not repeat app initialization when the Window already has content, // just ensure that the window is active if (rootFrame == null) { // Create a Frame to act as the navigation context and navigate to the first page rootFrame = new Frame(); rootFrame.NavigationFailed += OnNavigationFailed; if (e.PreviousExecutionState == ApplicationExecutionState.Terminated) { //TODO: Load state from previously suspended application } // Place the frame in the current Window Window.Current.Content = rootFrame; } if (rootFrame.Content == null) { // When the navigation stack isn't restored navigate to the first page, // configuring the new page by passing required information as a navigation // parameter rootFrame.Navigate(typeof(Page1), e.Arguments); } // Ensure the current window is active Window.Current.Activate(); }

.

void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e) { auto rootFrame = dynamic_cast(Window::Current->Content); // Do not repeat app initialization when the Window already has content, // just ensure that the window is active if (rootFrame == nullptr) { // Create a Frame to act as the navigation context and associate it with // a SuspensionManager key rootFrame = ref new Frame(); rootFrame->NavigationFailed += ref new Windows::UI::Xaml::Navigation::NavigationFailedEventHandler( this, &App::OnNavigationFailed); if (e->PreviousExecutionState == ApplicationExecutionState::Terminated) { // TODO: Load state from previously suspended application } // Place the frame in the current Window Window::Current->Content = rootFrame; } if (rootFrame->Content == nullptr) { // When the navigation stack isn't restored navigate to the first page, // configuring the new page by passing required information as a navigation // parameter rootFrame->Navigate(Windows::UI::Xaml::Interop::TypeName(Page1::typeid), e->Arguments); } // Ensure the current window is active Window::Current->Activate(); }

Note The code here uses the return value of Navigate to throw an app exception if the navigation to the app's initial window frame fails. When Navigate returns true, the navigation happens. Now, build and run the app. Click the link that says "Click to go to page 2". The second page that says "Page 2" at the top should be loaded and displayed in the frame.

Frame and Page classes Before we add more functionality to our app, let's look at how the pages we added provide navigation support for the app. First, a Frame ( rootFrame ) is created for the app in the App.OnLaunched method of the App.xaml code-behind file. The Navigate method is used to display content in this Frame. Note The Frame class supports various navigation methods such as Navigate, GoBack, and GoForward, and properties such as BackStack, ForwardStack, and BackStackDepth. In our example, Page1 is passed to the Navigate method. This method sets the content of the app's current window to the Frame and loads the content of the page you specify into the Frame (Page1.xaml in our example, or MainPage.xaml, by default). is a subclass of the Page class. The Page class has a read-only Frame property that gets the Frame containing the Page. When the Click event handler of the HyperlinkButton calls Frame.Navigate(typeof(Page2)) , the Frame in the app's window displays the content of Page2.xaml. Page1

Whenever a page is loaded into the frame, that page is added as a PageStackEntry to the BackStack or ForwardStack of the Frame.

Pass information between pages Our app navigates between two pages, but it really doesn't do anything interesting yet. Often, when an app has multiple pages, the pages need to share information. Let's pass some information from the first page to the second page. In Page1.xaml, replace the the HyperlinkButton you added earlier with the following StackPanel. Here, we add a TextBlock label and a TextBox ( name ) for entering a text string.

In the HyperlinkButton_Click event handler of the Page1.xaml code-behind file, add a parameter referencing the property of the name TextBox to the Navigate method. private void HyperlinkButton_Click(object sender, RoutedEventArgs e) { this.Frame.Navigate(typeof(Page2), name.Text); }

void Page1::HyperlinkButton_Click(Platform::Object^ sender, RoutedEventArgs^ e) { this->Frame->Navigate(Windows::UI::Xaml::Interop::TypeName(Page2::typeid), name->Text); }

In the Page2.xaml code-behind file, override the

OnNavigatedTo

protected override void OnNavigatedTo(NavigationEventArgs e) { if (e.Parameter is string) { greeting.Text = "Hi, " + e.Parameter.ToString(); } else { greeting.Text = "Hi!"; } base.OnNavigatedTo(e); }

method with the following:

Text

void Page2::OnNavigatedTo(NavigationEventArgs^ e) { if (dynamic_cast(e->Parameter) != nullptr) { greeting->Text = "Hi," + e->Parameter->ToString(); } else { greeting->Text = "Hi!"; } ::Windows::UI::Xaml::Controls::Page::OnNavigatedTo(e); }

Run the app, type your name in the text box, and then click the link that says Click to go to page 2. When you called this.Frame.Navigate(typeof(Page2), tb1.Text) in the Click event of the HyperlinkButton, the name.Text property was passed to Page2 and the value from the event data is used for the message displayed on the page.

Cache a page Page content and state is not cached by default, you must enable it in each page of your app. In our basic peer-to-peer example, there is no back button (we demonstrate back navigation in Back button navigation), but if you did click a back button on Page2 , the TextBox (and any other field) on Page1 would be set to its default state. One way to work around this is to use the NavigationCacheMode property to specify that a page be added to the frame's page cache. In the constructor of Page1 , set NavigationCacheMode to Enabled. This retains all content and state values for the page until the page cache for the frame is exceeded. Set NavigationCacheMode to Required if you want to ignore cache size limits for the frame. However, cache size limits might be crucial, depending on the memory limits of a device. NOTE The CacheSize property specifies the number of pages in the navigation history that can be cached for the frame.

public Page1() { this.InitializeComponent(); this.NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Enabled; }

Page1::Page1() { this->InitializeComponent(); this->NavigationCacheMode = Windows::UI::Xaml::Navigation::NavigationCacheMode::Enabled; }

Related articles Navigation design basics for UWP apps Guidelines for tabs and pivots Guidelines for navigation panes

Show multiple views for an app 3/6/2017 • 5 min to read • Edit on GitHub

You can help your users be more productive by letting them view multiple independent parts of your app in separate windows. A typical example is an e-mail app where the main UI shows the list of emails and a preview of the selected e-mail. But users can also open messages in separate windows and view them side-by-side. Important APIs ApplicationViewSwitcher CreateNewView

When you create multiple windows for an app, each window behaves independently. The taskbar shows each window separately. Users can move, resize, show, and hide app windows independently and can switch between app windows as if they were separate apps. Each window operates in its own thread.

What is a view? An app view is the 1:1 pairing of a thread and a window that the app uses to display content. It's represented by a Windows.ApplicationModel.Core.CoreApplicationView object. Views are managed by the CoreApplication object. You call CoreApplication.CreateNewView to create aCoreApplicationView object. The CoreApplicationView brings together a CoreWindow and a CoreDispatcher (stored in the CoreWindow and Dispatcher properties). You can think of the CoreApplicationView as the object that the Windows Runtime uses to interact with the core Windows system. You typically don’t work directly with the CoreApplicationView. Instead, the Windows Runtime provides the ApplicationView class in the Windows.UI.ViewManagement namespace. This class provides properties, methods, and events that you use when your app interacts with the windowing system. To work with an ApplicationView, call the static ApplicationView.GetForCurrentView method, which gets an ApplicationView instance tied to the current CoreApplicationView’s thread. Likewise, the XAML framework wraps the CoreWindow object in a Windows.UI.XAML.Window object. In a XAML app, you typically interact with the Window object rather than working directly with the CoreWindow.

Show a new view Before we go further, let's look at the steps to create a new view. Here, the new view is launched in response to a button click.

private async void Button_Click(object sender, RoutedEventArgs e) { CoreApplicationView newView = CoreApplication.CreateNewView(); int newViewId = 0; await newView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { Frame frame = new Frame(); frame.Navigate(typeof(SecondaryPage), null); Window.Current.Content = frame; // You have to activate the window in order to show it later. Window.Current.Activate(); newViewId = ApplicationView.GetForCurrentView().Id; }); bool viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(newViewId); }

To show a new view 1. Call CoreApplication.CreateNewView to create a new window and thread for the view content. CoreApplicationView newView = CoreApplication.CreateNewView();

2. Track the Id of the new view. You use this to show the view later. You might want to consider building some infrastructure into your app to help with tracking the views you create. See the ViewLifetimeControl class in the MultipleViews sample for an example. int newViewId = 0;

3. On the new thread, populate the window. You use the CoreDispatcher.RunAsync method to schedule work on the UI thread for the new view. You use a lambda expression to pass a function as an argument to the RunAsync method. The work you do in the lambda function happens on the new view's thread. In XAML, you typically add a Frame to the Window's Content property, then navigate the Frame to a XAML Page where you've defined your app content. For more info, see Peer-to-peer navigation between two pages. After the new Window is populated, you must call the Window's Activate method in order to show the Window later. This work happens on the new view's thread, so the new Window is activated. Finally, get the new view's Id that you use to show the view later. Again, this work is on the new view's thread, so ApplicationView.GetForCurrentView gets the Id of the new view. await newView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { Frame frame = new Frame(); frame.Navigate(typeof(SecondaryPage), null); Window.Current.Content = frame; // You have to activate the window in order to show it later. Window.Current.Activate(); newViewId = ApplicationView.GetForCurrentView().Id; });

4. Show the new view by calling ApplicationViewSwitcher.TryShowAsStandaloneAsync.

After you create a new view, you can show it in a new window by calling the ApplicationViewSwitcher.TryShowAsStandaloneAsync method. The viewId parameter for this method is an integer that uniquely identifies each of the views in your app. You retrieve the view Id by using either the ApplicationView.Id property or the ApplicationView.GetApplicationViewIdForWindow method. bool viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(newViewId);

The main view The first view that’s created when your app starts is called the main view. This view is stored in the CoreApplication.MainView property, and its IsMain property is true. You don’t create this view; it’s created by the app. The main view's thread serves as the manager for the app, and all app activation events are delivered on this thread. If secondary views are open, the main view’s window can be hidden – for example, by clicking the close (x) button in the window title bar - but its thread remains active. Calling Close on the main view’s Window causes an InvalidOperationException to occur. (Use Application.Exit to close your app.) If the main view’s thread is terminated, the app closes.

Secondary views Other views, including all views that you create by calling CreateNewView in your app code, are secondary views. Both the main view and secondary views are stored in the CoreApplication.Views collection. Typically, you create secondary views in response to a user action. In some instances, the system creates secondary views for your app. NOTE You can use the Windows assigned access feature to run an app in kiosk mode. When you do this, the system creates a secondary view to present your app UI above the lock screen. App-created secondary views are not allowed, so if you try to show your own secondary view in kiosk mode, an exception is thrown.

Switch from one view to another You must provide a way for the user to navigate from a secondary window back to the main window. To do this, use the ApplicationViewSwitcher.SwitchAsync method. You call this method from the thread of the window you're switching from and pass the view ID of the window you're switching to. await ApplicationViewSwitcher.SwitchAsync(viewIdToShow);

When you use SwitchAsync, you can choose if you want to close the initial window and remove it from the taskbar by specifying the value of ApplicationViewSwitchingOptions.

Command design basics for UWP apps 3/6/2017 • 6 min to read • Edit on GitHub

In a Universal Windows Platform (UWP) app, command elements are the interactive UI elements that enable the user to perform actions, such as sending an email, deleting an item, or submitting a form. This article describes the command elements, such as buttons and check boxes, the interactions they support, and the command surfaces (such as command bars and context menus) for hosting them.

Provide the right type of interactions When designing a command interface, the most important decision is choosing what users should be able to do. For example, if you're creating a photo app, the user will need tools to edit their photos. However, if you're creating a social media app that happens to display photos, image editing might not be a priority and so editing tools can be omitted to save space. Decide what you want users to accomplish and provide the tools to help them do it. For recommendations about how to plan the right interactions for your app, see Plan your app.

Use the right command element for the interaction Using the right elements for the right interactions can mean the difference between an app that feels intuitive to use and one that seems difficult or confusing. The Universal Windows Platform (UWP) provides a large set of command elements, in the form of controls, that you can use in your app. Here's a list of some of the most common controls and a summary of the interactions they enable. CATEGORY

ELEMENTS

INTERACTION

Buttons

Button

Triggers an immediate action, such as sending an email, confirming an action in a dialog, submitting form data.

Date and time pickers

calendar date picker, calendar view, date picker, time picker

Enables the user to view and modify date and time info, such as when entering a credit card expiration date or setting an alarm.

Lists

drop-down list, list box, list view and grid view

Presents items in a interactive list or a grid. Use these elements to let users select a movie from a list of new releases or manage an inventory.

Predictive text entry

Auto-suggest box

Saves users time when entering data or performing queries by providing suggestions as they type.

Selection controls

check box, radio button, toggle switch

Lets the user choose between different options, such as when completing a survey or configuring app settings.

For a complete list, see Controls and UI elements

Place commands on the right surface

You can place command elements on a number of surfaces in your app, including the app canvas (the content area of your app) or special command elements that can act as command containers, such as command bars, menus, dialogs, and flyouts. Here are some general recommendations for placing commands: Whenever possible, let users directly manipulate the content on the app's canvas, rather than adding commands that act on the content. For example, in the travel app, let users rearrange their itinerary by dragging and dropping activities in a list on the canvas, rather than by selecting the activity and using Up or Down command buttons. Otherwise, place commands on one of these UI surfaces if users can't manipulate content directly: In the command bar: You should put most commands on the command bar, which helps to organize commands and makes them easy to access. On the app's canvas: If the user is on a page or view that has a single purpose, you can provide commands for that purpose directly on the canvas. There should be very few of these commands. In a context menu: You can use context menus for clipboard actions (such as cut, copy, and paste), or for commands that apply to content that cannot be selected (like adding a push pin to a location on a map). Here's a list of the command surfaces that Windows provides and recommendations for when to use them. SURFACE

DESCRIPTION

App canvas (content area)

If a command is critical and is constantly needed for the user to complete the core scenarios, put it on the canvas (the content area of your app). Because you can put commands near (or on) the objects they affect, putting commands on the canvas makes them easy and obvious to use. However, choose the commands you put on the canvas carefully. Too many commands on the app canvas takes up valuable screen space and can overwhelm the user. If the command won't be frequently used, consider putting it in another command surface, such as menu or the command bar's "More" area.

Command bar

Command bars provide users with easy access to actions. You can use a command bar to show commands or options that are specific to the user's context, such as a photo selection or drawing mode. Command bars can be placed at the top of the screen, at the bottom of the screen, or at both the top and bottom of the screen. This design of a photo editing app shows the content area and the command bar:

For more information about command bars, see the Guidelines for command bar article.

Menus and context menus

Sometimes it is more efficient to group multiple commands into a command menu. Menus let you present more options with less space. Menus can include interactive controls. Context menus can provide shortcuts to commonly-used actions and provide access to secondary commands that are only relevant in certain contexts. Context menus are for the following types of commands and command scenarios: Contextual actions on text selections, such as Copy, Cut, Paste, Check Spelling, and so on. Commands for an object that needs to be acted upon but that can't be selected or otherwise indicated. Showing clipboard commands. Custom commands. This example shows the design for a subway app that uses a context menu to modify the route, bookmark a route, or select another train.

For more info about context menus, see the Guidelines for context menu article.

Dialog controls

Dialogs are modal UI overlays that provide contextual app information. In most cases, dialogs block interactions with the app window until being explicitly dismissed, and often request some kind of action from the user. Dialogs can be disruptive and should only be used in certain situations. For more info, see the When to confirm or undo actions section.

Flyout

A lightweight contextual popup that displays UI related to what the user is doing. Use a flyout to: Show a menu. Show more detail about an item. Ask the user to confirm an action without blocking interaction with the app. Flyouts can be dismissed by tapping or clicking somewhere outside the flyout. For more info about flyout controls, see the Dialogs and flyouts article.

When to confirm or undo actions No matter how well-designed the user interface is and no matter how careful the user is, at some point, all users will perform an action they wish they hadn't. Your app can help in these situations by requiring the user to confirm an action, or by providing a way of undoing recent actions.

For actions that can't be undone and have major consequences, we recommend using a confirmation dialog. Examples of such actions include: Overwriting a file Not saving a file before closing Confirming permanent deletion of a file or data Making a purchase (unless the user opts out of requiring a confirmation) Submitting a form, such as signing up for something For actions that can be undone, offering a simple undo command is usually enough. Examples of such actions include: Deleting a file Deleting an email (not permanently) Modifying content or editing text Renaming a file TIP Be careful of how much your app uses confirmation dialogs; they can be very helpful when the user makes a mistake, but they are a hindrance whenever the user is trying to perform an action intentionally.

Optimize for specific input types See the Interaction primer for more detail on optimizing user experiences around a specific input type or device.

Active canvas layout pattern 3/6/2017 • 1 min to read • Edit on GitHub

An active canvas is a pattern with a content area and a command area. It's for single-view apps or modal experiences, such as photo viewers/editors, document viewers, maps, painting, or other apps that make use of a free-scrolling view. For taking actions, an active canvas can be paired with a command bar or just buttons, depending on the number and types of actions you need.

Examples This design of a photo editing app features an active canvas pattern, with a mobile example on the left, and a desktop example on the right. The image editing surface is a canvas, and the command bar at the bottom contains all of the contextual actions for the app.

This design of a subway map app makes use of an active canvas with a simple UI strip at the top that has only two actions and a search box. Contextual actions are shown in the context menu, as seen on the right image.

Implementing this pattern The active canvas pattern consists of a content area and a command area. Content area. The content area is usually a free-scrolling canvas. Multiple content areas can exist within an app. Command area. If you're placing a lot of commands, then a command bar, which responds based on screen size,

could be the way to go. If you're not placing that many commands and aren't as concerned with a responsive UI, space-saving buttons work well.

Related articles App bar and command bar

Content design basics for UWP apps 3/6/2017 • 3 min to read • Edit on GitHub

The main purpose of any app is to provide access to content: in a photo-editing app, the photo is the content; in a travel app, maps and info about travel destinations is the content; and so on. Navigation elements provide access to content; command elements enable the user to interact with content; content elements display the actual content. This article provides content design recommendations for the three content scenarios.

Design for the right content scenario There are three main content scenarios: Consumption: A primarily one-way experience where content is consumed. It includes tasks like reading, listening to music, watching videos, and photo and image viewing. Creation: A primarily one-way experience where the focus is creating new content. It can be broken down into making things from scratch, like shooting a photo or video, creating a new image in a painting app, or opening a fresh document. Interactive: A two-way content experience that includes consuming, creating, and revising content.

Consumption-focused apps Content elements receive the highest priority in a consumption-focused app, followed by the navigation elements needed to help users find the content they want. Examples of consumption-focused apps include movie players, reading apps, music apps, and photo viewers.

General recommendations for consumption-focused apps: Consider creating dedicated navigation pages and content-viewing pages, so that when users find the content they are looking for, they can view it on a dedicated page free of distractions. Consider creating a full-screen view option that expands the content to fill the entire screen and hides all other UI elements.

Creation-focused apps Content and command elements are the most import UI elements in a creation-focused app: command elements enable the user to create new content. Examples include painting apps, photo editing apps, video editing apps, and

word processing apps. As an example, here's a design for a photo app that uses command bars to provide access to tools and photo manipulation options. Because all the commands are in the command bar, the app can devote most of its screen space to its content, the photo being edited.

General recommendations for creation-focused apps: Minimize the use of navigation elements. Command elements are especially important in creation-focused apps. Since users will be executing a lot of commands, we recommend providing a command history/undo functionality.

Apps with interactive content In an app with interactive content, users create, view, and edit content; many apps fit into this category. Examples of these types of apps include line of business apps, inventory management apps, cooking apps that enable the user to create or modify recipes.

These sort of apps need to balance all three UI elements: Navigation elements help users find and view content. If viewing and finding content is the most important scenario, prioritize navigation elements, filtering and sorting, and search. Command elements let the user create, edit, and manipulate content. General recommendations for apps with interactive content: It can be difficult to balance navigation, content, and command elements when all three are important. If

possible, consider creating separate screens for browsing, creating, and editing content, or providing mode switches.

Commonly used content elements Here are some UI elements commonly used to display content. (For a complete list of UI elements, see Controls and UI elements.) CATEGORY

ELEMENTS

DESCRIPTION

Audio and video

Media playback and transport controls

Plays audio and video.

Image viewers

Flip view, image

Displays images. The flip view displays images in a collection, such as photos in an album or items in a product details page, one image at a time.

Lists

drop-down list, list box, list view and grid view

Presents items in an interactive list or a grid. Use these elements to let users select a movie from a list of new releases or manage an inventory.

Text and text input

Text block, text box, rich edit box

Displays text. Some elements enable the user to edit text. For more info, see Text controls

Screen sizes and break points for responsive design 3/6/2017 • 2 min to read • Edit on GitHub

The number of device targets and screen sizes across the Windows 10 ecosystem is too great to worry about optimizing your UI for each one. Instead, we recommended designing for a few key widths (also called "breakpoints"): 360, 640, 1024 and 1366 epx. TIP When designing for specific breakpoints, design for the amount of screen space available to your app (the app's window). When the app is running full-screen, the app window is the same size as the screen, but in other cases, it's smaller.

This table describes the different size classes and provides general recommendations for tailoring for those size classes.

SIZE CLASS

SMALL

MEDIUM

LARGE

Typical screen size (diagonal)

4" to 6"

7" to 12", or TVs

13" and larger

Typical devices

Phones

Phablets, tablets, TVs

PCs, laptops, Surface Hubs

Common window sizes in effective pixels

320x569, 360x640, 480x854

960x540, 1024x640

1366x768, 1920x1080

Window width breakpoints in effective pixels

640px or less

641px to 1007px

1008px or greater

SIZE CLASS

General recommendations

SMALL

Center tab elements. Set left and right window margins to 12px to create a visual separation between the left and right edges of the app window. Dock app bars to the bottom of the window for improved reachability Use one column/region at a time Use an icon to represent search (don't show a search box). Put the navigation pane in overlay mode to conserve screen space. If you're using the master details pattern, use the stacked presentation mode to save screen space.

MEDIUM

Make tab elements left-aligned. Set left and right window margins to 24px to create a visual separation between the left and right edges of the app window. Put command elements like app bars at the top of the app window. Up to two columns/regions Show the search box. Put the navigation pane into sliver mode so a narrow strip of icons always shows. Consider further tailoring for TV experiences.

LARGE

Make tab elements left-aligned. Set left and right window margins to 24px to create a visual separation between the left and right edges of the app window. Put command elements like app bars at the top of the app window. Up to three columns/regions Show the search box. Put the navigation pane into docked mode so that it always shows.

With Continuum for Phones, a new experience for compatible Windows 10 mobile devices, users can connect their phones to a monitor, mouse and keyboard to make their phones work like laptops. Keep this new capability in mind when designing for specific breakpoints - a mobile phone will not always stay in the small size class.

Define page layouts with XAML 3/6/2017 • 21 min to read • Edit on GitHub

XAML gives you a flexible layout system that lets you use automatic sizing, layout panels, visual states, and even separate UI definitions to create a responsive UI. With a flexible design, you can make your app look great on screens with different app window sizes, resolutions, pixel densities, and orientations. Here, we discuss how to use XAML properties and layout panels to make your app responsive and adaptive. We build on important info about responsive UI design and techniques found in Introduction to UWP app design. You should understand what effective pixels are and understand each of the responsive design techniques: Reposition, Resize, Reflow, Reveal, Replace, and Re-architect. NOTE Your app layout begins with the navigation model you choose, like whether to use a Pivot with the ‘tabs and pivot’ model or SplitView with the ‘nav pane’ model. For more info about that, see Navigation design basics for UWP apps. Here, we talk about techniques to make the layout of a single page or group of elements responsive. This info is applicable regardless of which navigation model you choose for your app.

The XAML framework provides several levels of optimization you can use to create a responsive UI. Fluid layout Use layout properties and panels to make your default UI fluid. The foundation of a responsive layout is the appropriate use of layout properties and panels to reposition, resize, and reflow content. You can set a fixed size on an element, or use automatic sizing to let the parent layout panel size it. The various Panel classes, such as Canvas, Grid, RelativePanel and StackPanel, provide different ways to size and position their children. Adaptive layout Use visual states to make significant alterations to your UI based on window size or other changes. When your app window grows or shrinks beyond a certain amount, you might want to alter layout properties to reposition, resize, reflow, reveal, or replace sections of your UI. You can define different visual states for your UI, and apply them when the window width or window height crosses a specified threshold. An AdaptiveTrigger provides an easy way to set the threshold (also called 'breakpoint') where a state is applied. Tailored layout A tailored layout is optimized for a specific device family or range of screen sizes. Within the device family, the layout should still respond and adapt to changes within the range of supported window sizes. Note With Continuum for Phones, users can connect their phones to a monitor, mouse, and keyboard. This capability blurs the lines between phone and desktop device families. Approaches to tailoring include Create custom trigger You can create a device family trigger and modify its setters, as for adaptive triggers. Use separate XAML files to define distinct views for each device family. You can use separate XAML files with the same code file to define per-device family views of the UI.

Use separate XAML and code to provide different implementations for each device family. You can provide different implementations of a page (XAML and code), then navigate to a particular implementation based on the device family, screen size, or other factors.

Layout properties and panels Layout is the process of sizing and positioning objects in your UI. To position visual objects, you must put them in a panel or other container object. The XAML framework provides various panel classes, such as Canvas, Grid, RelativePanel and StackPanel, which serve as containers and enable you to position and arrange the UI elements within them. The XAML layout system supports both static and fluid layouts. In a static layout, you give controls explicit pixel sizes and positions. When the user changes the resolution or orientation of their device, the UI doesn't change. Static layouts can become clipped across different form factors and display sizes. Fluid layouts shrink, grow, and reflow to respond to the visual space available on a device. To create a fluid layout, use automatic or proportional sizing for elements, alignment, margins, and padding, and let layout panels position their children as needed. You arrange child elements by specifying how they should be arranged in relationship to each other, and how they should be sized relative to their content and/or their parent. In practice, you use a combination of static and fluid elements to create your UI. You still use static elements and values in some places, but make sure that the overall UI is responsive and adapts to different resolutions, layouts, and views. Layout properties

To control the size and position of an element, you set its layout properties. Here are some common layout properties and their effect. Height and Width Set the Height and Width properties to specify the size of an element. You can use fixed values measured in effective pixels, or you can use auto or proportional sizing. To get the size of an element at runtime, use the ActualHeight and ActualWidth properties instead of Height and Width. You use auto sizing to let UI elements resize to fit their content or parent container. You can also use auto sizing with the rows and columns of a grid. To use auto sizing, set the Height and/or Width of UI elements to Auto. NOTE Whether an element resizes to its content or its container depends on the value of its HorizontalAlignment and VerticalAlignment properties, and how the parent container handles sizing of its children. For more info, see [Alignment]() and [Layout panels]() later in this article.

You use proportional sizing, also called star sizing, to distribute available space among the rows and columns of a grid by weighted proportions. In XAML, star values are expressed as * (or n* for weighted star sizing). For example, to specify that one column is 5 times wider than the second column in a 2-column layout, use "5*" and "*" for the Width properties in the ColumnDefinition elements. This example combines fixed, auto, and proportional sizing in a Grid with 4 columns.

Column_1

Auto

The column will size to fit its content.

Column_2

*

After the Auto columns are calculated, the column gets part of the remaining width. Column_2 will be one-half as wide as Column_4.

Column_3

44

The column will be 44 pixels wide.

Column_4

2*

After the Auto columns are calculated, the column gets part of the remaining width. Column_4 will be twice as wide as Column_2.

The default column width is "*", so you don't need to explicitly set this value for the second column.

In the Visual Studio XAML designer, the result looks like this.

Size constraints When you use auto sizing in your UI, you might still need to place constraints on the size of an element. You can set the MinWidth/MaxWidth and MinHeight/MaxHeight properties to specify values that constrain the size of an element while allowing fluid resizing. In a Grid, MinWidth/MaxWidth can also be used with column definitions, and MinHeight/MaxHeight can be used with row definitions. Alignment Use the HorizontalAlignment and VerticalAlignment properties to specify how an element should be positioned within its parent container. The values for HorizontalAlignment are Left, Center, Right, and Stretch. The values for VerticalAlignment are Top, Center, Bottom, and Stretch. With the Stretch alignment, elements fill all the space they're provided in the parent container. Stretch is the default for both alignment properties. However, some controls, like Button, override this value in their default style. Any element that can have child elements can treat the Stretch value for HorizontalAlignment and VerticalAlignment properties uniquely. For example, an element using the default Stretch values placed in a Grid stretches to fill the cell that contains it. The same element placed in a Canvas sizes to its content. For more info about how each panel handles the Stretch value, see the Layout panels article. For more info, see the Alignment, margin, and padding article, and the HorizontalAlignment and

VerticalAlignment reference pages. Controls also have HorizontalContentAlignment and VerticalContentAlignment properties that you use to specify how they position their content. Not all controls make use of these properties. They only affect layout behavior for a control when its template uses the properties as the source of a HorizontalAlignment/VerticalAlignment value for presenters or content areas within it. For TextBlock, TextBox, and RichTextBlock, use the TextAlignment property to control the alignment of text in the control. Margins and padding Set the Margin property to control the amount of empty space around an element. Margin does not add pixels to the ActualHeight and ActualWidth, and is also not considered part of the element for purposes of hit testing and sourcing input events. Set the Padding property to control the amount of space between the inner border of an element and its content. A positive Padding value decreases the content area of the element. This diagram shows how Margin and Padding are applied to an element.

The left, right, top, and bottom values for Margin and Padding do not need to be symmetrical, and they can be set to negative values. For more info, see Alignment, margin, and padding, and the Margin or Padding reference pages. Let's look at the effects of Margin and Padding on real controls. Here’s a TextBox inside of a Grid with the default Margin and Padding values of 0.

Here’s the same TextBox and Grid with Margin and Padding values on the TextBox as shown in this XAML.

Visibility

You can reveal or hide an element by setting its Visibility property to one of the Visibility enumeration values: Visible or Collapsed. When an element is Collapsed, it doesn't take up any space in the UI layout. You can change an element's Visibility property in code or in a visual state. When the Visibility of an element is changed, all of its child elements are also changed. You can replace sections of your UI by revealing one panel while collapsing another. Tip When you have elements in your UI that are Collapsed by default, the objects are still created at startup, even though they aren't visible. You can defer loading these elements until they are shown by setting the x:DeferLoadStrategy attribute to "Lazy". This can improve startup performance. For more info, see x:DeferLoadStrategy attribute. Style resources

You don't have to set each property value individually on a control. It's typically more efficient to group property values into a Style resource and apply the Style to a control. This is especially true when you need to apply the same property values to many controls. For more info about using styles, see Styling controls. Layout panels

Most app content can be organized into some form of groupings or hierarchies. You use layout panels to group and arrange UI elements in your app. The main thing to consider when choosing a layout panel is how the panel positions and sizes its child elements. You might also need to consider how overlapping child elements are layered on top of each other. Here's a comparison of the main features of the panel controls provided in the XAML framework. PANEL CONTROL

DESCRIPTION

Canvas

Canvas doesn’t support fluid UI; you control all aspects of positioning and sizing child elements. You typically use it for special cases like creating graphics or to define small static areas of a larger adaptive UI. You can use code or visual states to reposition elements at runtime. Elements are positioned absolutely using Canvas.Top and Canvas.Left attached properties. Layering can be explicitly specified using the Canvas.ZIndex attached property. Stretch values for HorizontalAlignment/VerticalAlignment are ignored. If an element's size is not set explicitly, it sizes to its content. Child content is not visually clipped if larger than the panel. Child content is not constrained by the bounds of the panel.

Grid

Grid supports fluid resizing of child elements. You can use code or visual states to reposition and reflow elements. Elements are arranged in rows and columns using Grid.Row and Grid.Column attached properties. Elements can span multiple rows and columns using Grid.RowSpan and Grid.ColumnSpan attached properties. Stretch values for HorizontalAlignment/VerticalAlignment are respected. If an element's size is not set explicitly, it stretches to fill the available space in the grid cell. Child content is visually clipped if larger than the panel. Content size is constrained by the bounds of the panel, so scrollable content shows scroll bars if needed.

PANEL CONTROL

DESCRIPTION

RelativePanel

Elements are arranged in relation to the edge or center of the panel, and in relation to each other. Elements are positioned using a variety of attached properties that control panel alignment, sibling alignment, and sibling position. Stretch values for HorizontalAlignment/VerticalAlignment are ignored unless RelativePanel attached properties for alignment cause stretching (for example, an element is aligned to both the right and left edges of the panel). If an element's size is not set explicitly and it's not stretched, it sizes to its content. Child content is visually clipped if larger than the panel. Content size is constrained by the bounds of the panel, so scrollable content shows scroll bars if needed.

StackPanel

Elements are stacked in a single line either vertically or horizontally. Stretch values for HorizontalAlignment/VerticalAlignment are respected in the direction opposite the Orientation property. If an element's size is not set explicitly, it stretches to fill the available width (or height if the Orientation is Horizontal). In the direction specified by the Orientation property, an element sizes to its content. Child content is visually clipped if larger than the panel. Content size is not constrained by the bounds of the panel in the direction specified by the Orientation property, so scrollable content stretches beyond the panel bounds and doesn't show scrollbars. You must explicitly constrain the height (or width) of the child content to make its scrollbars show.

VariableSizedWrapGrid

Elements are arranged in rows or columns that automatically wrap to a new row or column when the MaximumRowsOrColumns value is reached. Whether elements are arranged in rows or columns is specified by the Orientation property. Elements can span multiple rows and columns using VariableSizedWrapGrid.RowSpan and VariableSizedWrapGrid.ColumnSpan attached properties. Stretch values for HorizontalAlignment/VerticalAlignment are ignored. Elements are sized as specified by the ItemHeight and ItemWidth properties. If these properties are not set, the item in the first cell sizes to its content, and all other cells inherit this size. Child content is visually clipped if larger than the panel. Content size is constrained by the bounds of the panel, so scrollable content shows scroll bars if needed.

For detailed information and examples of these panels, see Layout panels. Also, see the Responsive techniques sample. Layout panels let you organize your UI into logical groups of controls. When you use them with appropriate property settings, you get some support for automatic resizing, repositioning, and reflowing of UI elements. However, most UI layouts need further modification when there are significant changes to the window size. For this, you can use visual states.

Visual states and state triggers Use visual states to reposition, resize, reflow, reveal, or replace sections of your UI based on screen size or other

factors. A VisualState defines property values that are applied to an element when it’s in a particular state. You group visual states in a VisualStateManager that applies the appropriate VisualState when the specified conditions are met. Set visual states in code

To apply a visual state from code, you call the VisualStateManager.GoToState method. For example, to apply a state when the app window is a particular size, handle the SizeChanged event and call GoToState to apply the appropriate state. Here, a VisualStateGroup contains 2 VisualState definitions. The first, DefaultState , is empty. When it's applied, the values defined in the XAML page are applied. The second, WideState , changes the DisplayMode property of the SplitView to Inline and opens the pane. This state is applied in the SizeChanged event handler if the window width is 720 effective pixels or greater. Inline

private void CurrentWindow_SizeChanged(object sender, Windows.UI.Core.WindowSizeChangedEventArgs e) { if (e.Size.Width >= 720) VisualStateManager.GoToState(this, "WideState", false); else VisualStateManager.GoToState(this, "DefaultState", false); }

Set visual states in XAML markup

Prior to Windows 10, VisualState definitions required Storyboard objects for property changes, and you had to call GoToState in code to apply the state. This is shown in the previous example. You will still see many examples that use this syntax, or you might have existing code that uses it. Starting in Windows 10, you can use the simplified Setter syntax shown here, and you can use a StateTrigger in your XAML markup to apply the state. You use state triggers to create simple rules that automatically trigger visual state changes in response to an app event. This example does the same thing as the previous example, but uses the simplified Setter syntax instead of a Storyboard to define property changes. And instead of calling GoToState, it uses the built in AdaptiveTrigger state trigger to apply the state. When you use state triggers, you don't need to define an empty DefaultState . The default settings are reapplied automatically when the conditions of the state trigger are no longer met.

Important In the previous example, the VisualStateManager.VisualStateGroups attached property is set on the Grid element. When you use StateTriggers, always ensure that VisualStateGroups is attached to the first child of the root in order for the triggers to take effect automatically. (Here, Grid is the first child of the root Page element.) Attached property syntax

In a VisualState, you typically set a value for a control property, or for one of the attached properties of the panel that contains the control. When you set an attached property, use parentheses around the attached property name. This example shows how to set the RelativePanel.AlignHorizontalCenterWithPanel attached property on a TextBox named myTextBox . The first XAML uses ObjectAnimationUsingKeyFrames syntax and the second uses Setter syntax.



Custom state triggers

You can extend the StateTrigger class to create custom triggers for a wide range of scenarios. For example, you can create a StateTrigger to trigger different states based on input type, then increase the margins around a control when the input type is touch. Or create a StateTrigger to apply different states based on the device family the app is run on. For examples of how to build custom triggers and use them to create optimized UI experiences from within a single XAML view, see the State triggers sample. Visual states and styles

You can use Style resources in visual states to apply a set of property changes to multiple controls. For more info about using styles, see Styling controls. In this simplified XAML from the State triggers sample, a Style resource is applied to a Button to adjust the size and margins for mouse or touch input. For the complete code and the definition of the custom state trigger, see the State triggers sample.



Tailored layouts

When you make significant changes to your UI layout on different devices, you might find it more convenient to define a separate UI file with a layout tailored to the device, rather than adapting a single UI. If the functionality is the same across devices, you can define separate XAML views that share the same code file. If both the view and the functionality differ significantly across devices, you can define separate Pages, and choose which Page to navigate to when the app is loaded. Separate XAML views per device family

Use XAML views to create different UI definitions that share the same code-behind. You can provide a unique UI definition for each device family. Follow these steps to add a XAML view to your app. To add a XAML view to an app 1. Select Project > Add New Item. The Add New Item dialog box opens. > Tip Make sure a folder or the project, and not the solution, is selected in Solution Explorer. 2. Under Visual C# or Visual Basic in the left pane, pick the XAML template type. 3. In the center pane, pick XAML View. 4. Enter the name for the view. The view must be named correctly. For more info on naming, see the remainder of this section. 5. Click Add. The file is added to the project. The previous steps create only a XAML file, but not an associated code-behind file. Instead, the XAML view is associated with an existing code-behind file using a "DeviceName" qualifier that's part of the file or folder name. This qualifier name can be mapped to a string value that represents the device family of the device that your app is currently running on, such as, "Desktop", "Mobile", and the names of the other device families (see ResourceContext.QualifierValues). You can add the qualifier to the file name, or add the file to a folder that has the qualifier name. Use file name To use the qualifier name with the file, use this format: [pageName].DeviceFamily-[qualifierString].xaml. Let's look at an example for a file named MainPage.xaml. To create a view for mobile devices, name the XAML view MainPage.DeviceFamily-Mobile.xaml. To create a view for PC devices, name the view MainPage.DeviceFamilyDesktop.xaml. Here's what the solution looks like in Microsoft Visual Studio.

Use folder name To organize the views in your Visual Studio project using folders, you can use the qualifier name with the folder. To do so, name your folder like this: DeviceFamily-[qualifierString]. In this case, each XAML view file has the same name. Don't include the qualifier in the file name. Here's an example, again for a file named MainPage.xaml. To create a view for mobile devices, create a folder named "DeviceFamily-Mobile", and place a XAML view named MainPage.xaml into it. To create a view for PC devices, create a folder named "DeviceFamily-Desktop", and place another XAML view named MainPage.xaml into it. Here's what the solution looks like in Visual Studio.

In both cases, a unique view is used for mobile and PC devices. The default MainPage.xaml file is used if the device it's running on doesn't match any of the device family specific views. Separate XAML pages per device family

To provide unique views and functionality, you can create separate Page files (XAML and code), and then navigate to the appropriate page when the page is needed. To add a XAML page to an app 1. Select Project > Add New Item. The Add New Item dialog box opens. > Tip Make sure the project, and not the solution, is selected in Solution Explorer. 2. Under Visual C# or Visual Basic in the left pane, pick the XAML template type. 3. In the center pane, pick Blank page. 4. Enter the name for the page. For example, "MainPage_Mobile". Both a MainPage_Mobile.xaml and MainPage_Mobile.xaml.cs/vb/cpp code file are created. 5. Click Add. The file is added to the project. At runtime, check the device family that the app is running on, and navigate to the correct page like this. if (Windows.System.Profile.AnalyticsInfo.VersionInfo.DeviceFamily == "Windows.Mobile") { rootFrame.Navigate(typeof(MainPage_Mobile), e.Arguments); } else { rootFrame.Navigate(typeof(MainPage), e.Arguments); }

You can also use different criteria to determine which page to navigate to. For more examples, see the Tailored multiple views sample, which uses the GetIntegratedDisplaySize function to check the physical size of an integrated display.

Sample code XAML UI basics sample See all of the XAML controls in an interactive format.

Layout panels 3/6/2017 • 7 min to read • Edit on GitHub

You use layout panels to arrange and group UI elements in your app. The built-in XAML layout panels include RelativePanel, StackPanel, Grid, VariableSizedWrapGrid, and Canvas. Here, we describe each panel and show how to use it to layout XAML UI elements. There are several things to consider when choosing a layout panel: How the panel positions its child elements. How the panel sizes its child elements. How overlapping child elements are layered on top of each other (z-order). The number and complexity of nested panel elements needed to create your desired layout. Panel attached properties Most XAML layout panels use attached properties to let their child elements inform the parent panel about how they should be positioned in the UI. Attached properties use the syntax AttachedPropertyProvider.PropertyName. If you have panels that are nested inside other panels, attached properties on UI elements that specify layout characteristics to a parent are interpreted by the most immediate parent panel only. Here is an example of how you can set the Canvas.Left attached property on a Button control in XAML. This informs the parent Canvas that the Button should be positioned 50 effective pixels from the left edge of the Canvas. Hello

For more info about attached properties, see Attached properties overview. Note An attached property is a XAML concept that requires special syntax to get or set from code. To use attached properties in code, see the Attached properties in code section of the Attached properties overview article. Panel borders The RelativePanel, StackPanel, and Grid panels define border properties that let you draw a border around the panel without wrapping them in an additional Border element. The border properties are BorderBrush, BorderThickness, CornerRadius, and Padding. Here’s an example of how to set border properties on a Grid.

Using the built-in border properties reduces the XAML element count, which can improve the UI performance of your app. For more info about layout panels and UI performance, see Optimize your XAML layout.

RelativePanel RelativePanel lets you layout UI elements by specifying where they go in relation to other elements and in relation to the panel. By default, an element is positioned in the upper left corner of the panel. You can use RelativePanel with a VisualStateManager and AdaptiveTriggers to rearrange your UI for different window sizes. This table shows the attached properties you can use to align an element with the edge or center of the panel, and align and position it in relation to other elements. PANEL ALIGNMENT

SIBLING ALIGNMENT

SIBLING POSITION

AlignTopWithPanel

AlignTopWith

Above

AlignBottomWithPanel

AlignBottomWith

Below

AlignLeftWithPanel

AlignLeftWith

LeftOf

AlignRightWithPanel

AlignRightWith

RightOf

AlignHorizontalCenterWithPanel

AlignHorizontalCenterWith

AlignVerticalCenterWithPanel

AlignVerticalCenterWith

This XAML shows how to arrange elements in a RelativePanel.

The result looks like this.

Here are a few thing to note about the sizing of the rectangles. The red rectangle is given an explicit size of 44x44. It's placed in the upper left corner of the panel, which is the default position. The green rectangle is given an explicit height of 44. Its left side is aligned with the red rectangle, and its right side is aligned with the blue rectangle, which determines its width. The yellow rectangle isn't given an explicit size. Its left side is aligned with the blue rectangle. Its right and bottom edges are aligned with the edge of the panel. Its size is determined by these alignments and it will resize as the panel resizes.

StackPanel StackPanel is a simple layout panel that arranges its child elements into a single line that can be oriented horizontally or vertically. StackPanel controls are typically used in scenarios where you want to arrange a small subsection of the UI on your page. You can use the Orientation property to specify the direction of the child elements. The default orientation is Vertical. The following XAML shows how to create a vertical StackPanel of items.

The result looks like this.

In a StackPanel, if a child element's size is not set explicitly, it stretches to fill the available width (or height if the Orientation is Horizontal). In this example, the width of the rectangles is not set. The rectangles expand to fill the entire width of the StackPanel.

Grid The Grid panel supports arranging controls in multi-row and multi-column layouts. You can specify a Grid panel's

rows and columns by using the RowDefinitions and ColumnDefinitions properties. In XAML, use property element syntax to declare the rows and columns within the Grid element. You can distribute space within a column or a row by using Auto or star sizing. You position objects in specific cells of the Grid by using the Grid.Column and Grid.Row attached properties. You can make content span across multiple rows and columns by using the Grid.RowSpan and Grid.ColumnSpan attached properties. This XAML example shows how to create a Grid with two rows and two columns.

The result looks like this.

In this example, the sizing works like this: The second row has an explicit height of 44 effective pixels. By default, the height of the first row fills whatever space is left over. The width of the first column is set to Auto, so it's as wide as needed for its children. In this case, it's 44 effective pixels wide to accommodate the width of the red rectangle. There are no other size constraints on the rectangles, so each one stretches to fill the grid cell it's in.

VariableSizedWrapGrid VariableSizedWrapGrid provides a grid-style layout panel where elements are arranged in rows or columns that automatically wrap to a new row or column when the MaximumRowsOrColumns value is reached. The Orientation property specifies whether the grid adds its items in rows or columns before wrapping. The default orientation is Vertical, which means the grid adds items from top to bottom until a column is full, then wraps to a new column. When the value is Horizontal, the grid adds items from left to right, then wraps to a new row. Cell dimensions are specified by the ItemHeight and ItemWidth. Each cell is the same size. If ItemHeight or ItemWidth is not specified, then the first cell sizes to fit its content, and every other cell is the size of the first cell. You can use the VariableSizedWrapGrid.ColumnSpan and VariableSizedWrapGrid.RowSpan attached

properties to specify how many adjacent cells a child element should fill. Here's how to use a VariableSizedWrapGrid in XAML.

The result looks like this.

In this example, the maximum number of rows in each column is 3. The first column contains only 2 items (the red and blue rectangles) because the blue rectangle spans 2 rows. The green rectangle then wraps to the top of the next column.

Canvas The Canvas panel positions its child elements using fixed coordinate points. You specify the points on individual child elements by setting the Canvas.Left and Canvas.Top attached properties on each element. During layout, the parent Canvas reads these attached property values from its children and uses these values during the Arrange pass of layout. Objects in a Canvas can overlap, where one object is drawn on top of another object. By default, the Canvas renders child objects in the order in which they’re declared, so the last child is rendered on top (each element has a default z-index of 0). This is the same as other built-in panels. However, Canvas also supports the Canvas.ZIndex attached property that you can set on each of the child elements. You can set this property in code to change the draw order of elements during run time. The element with the highest Canvas.ZIndex value draws last and therefore draws over any other elements that share the same space or overlap in any way. Note that alpha value (transparency) is respected, so even if elements overlap, the contents shown in overlap areas might be blended if the top one has a non-maximum alpha value. The Canvas does not do any sizing of its children. Each element must specify its size. Here's an example of a Canvas in XAML.

The result looks like this.

Use the Canvas panel with discretion. While it's convenient to be able to precisely control positions of elements in UI for some scenarios, a fixed positioned layout panel causes that area of your UI to be less adaptive to overall app window size changes. App window resize might come from device orientation changes, split app windows, changing monitors, and a number of other user scenarios.

Panels for ItemsControl There are several special-purpose panels that can be used only as an ItemsPanel to display items in an ItemsControl. These are ItemsStackPanel, ItemsWrapGrid, VirtualizingStackPanel, and WrapGrid. You can't use these panels for general UI layout.

XAML custom panels overview 3/6/2017 • 18 min to read • Edit on GitHub

A panel is an object that provides a layout behavior for child elements it contains, when the Extensible Application Markup Language (XAML) layout system runs and your app UI is rendered. Important APIs Panel ArrangeOverride MeasureOverride

You can define custom panels for XAML layout by deriving a custom class from the Panel class. You provide behavior for your panel by overriding the MeasureOverride and ArrangeOverride, supplying logic that measures and arranges the child elements.

The Panel base class To define a custom panel class, you can either derive from the Panel class directly, or derive from one of the practical panel classes that aren't sealed, such as Grid or StackPanel. It's easier to derive from Panel, because it can be difficult to work around the existing layout logic of a panel that already has layout behavior. Also, a panel with behavior might have existing properties that aren't relevant for your panel's layout features. From Panel, your custom panel inherits these APIs: The Children property. The Background, ChildrenTransitions and IsItemsHost properties, and the dependency property identifiers. None of these properties are virtual, so you don't typically override or replace them. You don't typically need these properties for custom panel scenarios, not even for reading values. The layout override methods MeasureOverride and ArrangeOverride. These were originally defined by FrameworkElement. The base Panel class doesn't override these, but practical panels like Grid do have override implementations that are implemented as native code and are run by the system. Providing new (or additive) implementations for ArrangeOverride and MeasureOverride is the bulk of the effort you need to define a custom panel. All the other APIs of FrameworkElement, UIElement and DependencyObject, such as Height, Visibility and so on. You sometimes reference values of these properties in your layout overrides, but they aren't virtual so you don't typically override or replace them. This focus here is to describe XAML layout concepts, so you can consider all the possibilities for how a custom panel can and should behave in layout. If you'd rather jump right in and see an example custom panel implementation, see BoxPanel, an example custom panel.

The Children property The Children property is relevant to a custom panel because all classes derived from Panel use the Children property as the place to store their contained child elements in a collection. Children is designated as the XAML content property for the Panel class, and all classes derived from Panel can inherit the XAML content property behavior. If a property is designated the XAML content property, that means that XAML markup can omit a property element when specifying that property in markup, and the values are set as immediate markup children (the "content"). For example, if you derive a class named CustomPanel from Panel that defines no new behavior, you

can still use this markup:

When a XAML parser reads this markup, Children is known to be the XAML content property for all Panel derived types, so the parser will add the two Button elements to the UIElementCollection value of the Children property. The XAML content property facilitates a streamlined parent-child relationship in the XAML markup for a UI definition. For more info about XAML content properties, and how collection properties are populated when XAML is parsed, see the XAML syntax guide. The collection type that's maintaining the value of the Children property is the UIElementCollection class. UIElementCollection is a strongly typed collection that uses UIElement as its enforced item type. UIElement is a base type that's inherited by hundreds of practical UI element types, so the type enforcement here is deliberately loose. But it does enforce that you couldn't have a Brush as a direct child of a Panel, and it generally means that only elements that are expected to be visible in UI and participate in layout will be found as child elements in a Panel. Typically, a custom panel accepts any UIElement child element by a XAML definition, by simply using the characteristics of the Children property as-is. As an advanced scenario, you could support further type checking of child elements, when you iterate over the collection in your layout overrides. Besides looping through the Children collection in the overrides, your panel logic might also be influenced by Children.Count . You might have logic that is allocating space at least partly based on the number of items, rather than desired sizes and the other characteristics of individual items.

Overriding the layout methods The basic model for the layout override methods (MeasureOverride and ArrangeOverride) is that they should iterate through all the children and call each child element's specific layout method. The first layout cycle starts when the XAML layout system sets the visual for the root window. Because each parent invokes layout on its children, this propagates a call to layout methods to every possible UI element that is supposed to be part of a layout. In XAML layout, there are two stages: measure, then arrange. You don't get any built-in layout method behavior for MeasureOverride and ArrangeOverride from the base Panel class. Items in Children won't automatically render as part of the XAML visual tree. It is up to you to make the items known to the layout process, by invoking layout methods on each of the items you find in Children through a layout pass within your MeasureOverride and ArrangeOverride implementations. There's no reason to call base implementations in layout overrides unless you have your own inheritance. The native methods for layout behavior (if they exist) run regardless, and not calling base implementation from overrides won't prevent the native behavior from happening. During the measure pass, your layout logic queries each child element for its desired size, by calling the Measure method on that child element. Calling the Measure method establishes the value for the DesiredSize property. The MeasureOverride return value is the desired size for the panel itself. During the arrange pass, the positions and sizes of child elements are determined in x-y space and the layout composition is prepared for rendering. Your code must call Arrange on each child element in Children so that the layout system detects that the element belongs in the layout. The Arrange call is a precursor to composition and rendering; it informs the layout system where that element goes, when the composition is submitted for rendering. Many properties and values contribute to how the layout logic will work at runtime. A way to think about the layout process is that the elements with no children (generally the most deeply nested element in the UI) are the ones that

can finalize measurements first. They don't have any dependencies on child elements that influence their desired size. They might have their own desired sizes, and these are size suggestions until the layout actually takes place. Then, the measure pass continues walking up the visual tree until the root element has its measurements and all the measurements can be finalized. The candidate layout must fit within the current app window or else parts of the UI will be clipped. Panels often are the place where the clipping logic is determined. Panel logic can determine what size is available from within the MeasureOverride implementation, and may have to push the size restrictions onto the children and divide space amongst children so that everything fits as best it can. The result of layout is ideally something that uses various properties of all parts of the layout but still fits within the app window. That requires both a good implementation for layout logic of the panels, and also a judicious UI design on the part of any app code that builds a UI using that panel. No panel design is going to look good if the overall UI design includes more child elements than can possibly fit in the app. A large part of what makes the layout system work is that any element that's based on FrameworkElement already has some of its own inherent behavior when acting as a child in a container. For example, there are several APIs of FrameworkElement that either inform layout behavior or are needed to make layout work at all. These include: DesiredSize (actually a UIElement property) ActualHeight and ActualWidth Height and Width Margin LayoutUpdated event HorizontalAlignment and VerticalAlignment ArrangeOverride and MeasureOverride methods Arrange and Measure methods: these have native implementations defined at the FrameworkElement level, which handle the element-level layout action

MeasureOverride The MeasureOverride method has a return value that's used by the layout system as the starting DesiredSize for the panel itself, when the Measure method is called on the panel by its parent in layout. The logic choices within the method are just as important as what it returns, and the logic often influences what value is returned. All MeasureOverride implementations should loop through Children, and call the Measure method on each child element. Calling the Measure method establishes the value for the DesiredSize property. This might inform how much space the panel itself needs, as well as how that space is divided among elements or sized for a particular child element. Here's a very basic skeleton of a MeasureOverride method: protected override Size MeasureOverride(Size availableSize) { Size returnSize; //TODO might return availableSize, might do something else //loop through each Child, call Measure on each foreach (UIElement child in Children) { child.Measure(new Size()); // TODO determine how much space the panel allots for this child, that's what you pass to Measure Size childDesiredSize = child.DesiredSize; //TODO determine how the returned Size is influenced by each child's DesiredSize //TODO, logic if passed-in Size and net DesiredSize are different, does that matter? } return returnSize; }

Elements often have a natural size by the time they're ready for layout. After the measure pass, the DesiredSize might indicate that natural size, if the availableSize you passed for Measure was smaller. If the natural size is larger than availableSize you passed for Measure, the DesiredSize is constrained to availableSize. That's how Measure's internal implementation behaves, and your layout overrides should take that behavior into account. Some elements don't have a natural size because they have Auto values for Height and Width. These elements use the full availableSize, because that's what an Auto value represents: size the element to the maximum available size, which the immediate layout parent communicates by calling Measure with availableSize. In practice, there's always some measurement that a UI is sized to (even if that's the top level window.) Eventually, the measure pass resolves all the Auto values to parent constraints and all Auto value elements get real measurements (which you can get by checking ActualWidth and ActualHeight, after layout completes). It's legal to pass a size to Measure that has at least one infinite dimension, to indicate that the panel can attempt to size itself to fit measurements of its content. Each child element being measured sets its DesiredSize value using its natural size. Then, during the arrange pass, the panel typically arranges using that size. Text elements such as TextBlock have a calculated ActualWidth and ActualHeight based on their text string and text properties even if no Height or Width value is set, and these dimensions should be respected by your panel logic. Clipping text is a particularly bad UI experience. Even if your implementation doesn't use the desired size measurements, it's best to call the Measure method on each child element, because there are internal and native behaviors that are triggered by Measure being called. For an element to participate in layout, each child element must have Measure called on it during the measure pass and the Arrange method called on it during the arrange pass. Calling these methods sets internal flags on the object and populates values (such as the DesiredSize property) that the system's layout logic needs when it builds the visual tree and renders the UI. The MeasureOverride return value is based on the panel's logic interpreting the DesiredSize or other size considerations for each of the child elements in Children when Measure is called on them. What to do with DesiredSize values from children and how the MeasureOverride return value should use them is up to your own logic's interpretation. You don't typically add up the values without modification, because the input of MeasureOverride is often a fixed available size that's being suggested by the panel's parent. If you exceed that size, the panel itself might get clipped. You'd typically compare the total size of children to the panel's available size and make adjustments if necessary. Tips and guidance

Ideally, a custom panel should be suitable for being the first true visual in a UI composition, perhaps at a level immediately under Page, UserControl or another element that is the XAML page root. In MeasureOverride implementations, don't routinely return the input Size without examining the values. If the return Size has an Infinity value in it, this can throw exceptions in runtime layout logic. An Infinity value can come from the main app window, which is scrollable and therefore doesn't have a maximum height. Other scrollable content might have the same behavior. Another common mistake in MeasureOverride implementations is to return a new default Size (values for height and width are 0). You might start with that value, and it might even be the correct value if your panel determines that none of the children should be rendered. But, a default Size results in your panel not being sized correctly by its host. It requests no space in the UI, and therefore gets no space and doesn't render. All your panel code otherwise might be functioning fine, but you still won't see your panel or contents thereof if it's being composed with zero height, zero width. Within the overrides, avoid the temptation to cast child elements to FrameworkElement and use properties that are calculated as a result of layout, particularly ActualWidth and ActualHeight. For most common scenarios, you can base the logic on the child's DesiredSize value and you won't need any of the Height or Width related properties of a child element. For specialized cases, where you know the type of element and have additional information, for example the natural size of an image file, you can use your element's specialized information because it's not a value that is actively being altered by layout systems. Including layout-

calculated properties as part of layout logic substantially increases the risk of defining an unintentional layout loop. These loops cause a condition where a valid layout can't be created and the system can throw a LayoutCycleException if the loop is not recoverable. Panels typically divide their available space between multiple child elements, although exactly how space is divided varies. For example, Grid implements layout logic that uses its RowDefinition and ColumnDefinition values to divide the space into the Grid cells, supporting both star-sizing and pixel values. If they're pixel values, the size available for each child is already known, so that's what is passed as input size for a grid-style Measure. Panels themselves can introduce reserved space for padding between items. If you do this, make sure to expose the measurements as a property that's distinct from Margin or any Padding property. Elements might have values for their ActualWidth and ActualHeight properties based on a previous layout pass. If values change, app UI code can put handlers for LayoutUpdated on elements if there's special logic to run, but panel logic typically doesn't need to check for changes with event handling. The layout system is already making the determinations of when to re-run layout because a layout-relevant property changed value, and a panel's MeasureOverride or ArrangeOverride are called automatically in the appropriate circumstances.

ArrangeOverride The ArrangeOverride method has a Size return value that's used by the layout system when rendering the panel itself, when the Arrange method is called on the panel by its parent in layout. It's typical that the input finalSize and the ArrangeOverride returned Size are the same. If they aren't, that means the panel is attempting to make itself a different size than what the other participants in layout claim is available. The final size was based on having previously run the measure pass of layout through your panel code, so that's why returning a different size isn't typical: it means you are deliberately ignoring measure logic. Don't return a Size with an Infinity component. Trying to use such a Size throws an exception from internal layout. All ArrangeOverride implementations should loop through Children, and call the Arrange method on each child element. Like Measure, Arrange doesn't have a return value. Unlike Measure, no calculated property gets set as a result (however, the element in question typically fires a LayoutUpdated event). Here's a very basic skeleton of an ArrangeOverride method: protected override Size ArrangeOverride(Size finalSize) { //loop through each Child, call Arrange on each foreach (UIElement child in Children) { Point anchorPoint = new Point(); //TODO more logic for topleft corner placement in your panel // for this child, and based on finalSize or other internal state of your panel child.Arrange(new Rect(anchorPoint, child.DesiredSize)); //OR, set a different Size } return finalSize; //OR, return a different Size, but that's rare }

The arrange pass of layout might happen without being preceded by a measure pass. However, this only happens when the layout system has determined no properties have changed that would have affected the previous measurements. For example, if an alignment changes, there's no need to re-measure that particular element because its DesiredSize would not change when its alignment choice changes. On the other hand, if ActualHeight changes on any element in a layout, a new measure pass is needed. The layout system automatically detects true measure changes and invokes the measure pass again, and then runs another arrange pass. The input for Arrange takes a Rect value. The most common way to construct this Rect is to use the constructor that has a Point input and a Size input. The Point is the point where the top left corner of the bounding box for the element should be placed. The Size is the dimensions used to render that particular element. You often use the

DesiredSize for that element as this Size value, because establishing the DesiredSize for all elements involved in layout was the purpose of the measure pass of layout. (The measure pass determines all-up sizing of the elements in an iterative way so that the layout system can optimize how elements are placed once it gets to the arrange pass.) What typically varies between ArrangeOverride implementations is the logic by which the panel determines the Point component of how it arranges each child. An absolute positioning panel such as Canvas uses the explicit placement info that it gets from each element through Canvas.Left and Canvas.Top values. A space-dividing panel such as Grid would have mathematical operations that divided the available space into cells and each cell would have an x-y value for where its content should be placed and arranged. An adaptive panel such as StackPanel might be expanding itself to fit content in its orientation dimension. There are still additional positioning influences on elements in layout, beyond what you directly control and pass to Arrange. These come from the internal native implementation of Arrange that's common to all FrameworkElement derived types and augmented by some other types such as text elements. For example, elements can have margin and alignment, and some can have padding. These properties often interact. For more info, see Alignment, margin, and padding.

Panels and controls Avoid putting functionality into a custom panel that should instead be built as a custom control. The role of a panel is to present any child element content that exists within it, as a function of layout that happens automatically. The panel might add decorations to content (similar to how a Border adds the border around the element it presents), or perform other layout-related adjustments like padding. But that's about as far as you should go when extending the visual tree output beyond reporting and using information from the children. If there's any interaction that's accessible to the user, you should write a custom control, not a panel. For example, a panel shouldn't add scrolling viewports to content it presents, even if the goal is to prevent clipping, because the scrollbars, thumbs and so on are interactive control parts. (Content might have scrollbars after all, but you should leave that up to the child's logic. Don't force it by adding scrolling as a layout operation.) You might create a control and also write a custom panel that plays an important role in that control's visual tree, when it comes to presenting content in that control. But the control and the panel should be distinct code objects. One reason the distinction between control and panel is important is because of Microsoft UI Automation and accessibility. Panels provide a visual layout behavior, not a logical behavior. How a UI element appears visually is not an aspect of UI that is typically important to accessibility scenarios. Accessibility is about exposing the parts of an app that are logically important to understanding a UI. When interaction is required, controls should expose the interaction possibilities to the UI Automation infrastructure. For more info, see Custom automation peers.

Other layout API There are some other APIs that are part of the layout system, but aren't declared by Panel. You might use these in a panel implementation or in a custom control that uses panels. UpdateLayout, InvalidateMeasure, and InvalidateArrange are methods that initiate a layout pass. InvalidateArrange might not trigger a measure pass, but the other two do. Never call these methods from within a layout method override, because they're almost sure to cause a layout loop. Control code doesn't typically need to call them either. Most aspects of layout are triggered automatically by detecting changes to the framework-defined layout properties such as Width and so on. LayoutUpdated is an event that fires when some aspect of layout of the element has changed. This isn't specific to panels; the event is defined by FrameworkElement. SizeChanged is an event that fires only after layout passes are finalized, and indicates that ActualHeight or ActualWidth have changed as a result. This is another FrameworkElement event. There are cases where LayoutUpdated fires, but SizeChanged does not. For example the internal contents might be rearranged, but

the element's size didn't change.

Related topics Reference FrameworkElement.ArrangeOverride FrameworkElement.MeasureOverride Panel Concepts Alignment, margin, and padding

BoxPanel, an example custom panel 3/6/2017 • 13 min to read • Edit on GitHub

Learn to write code for a custom Panel class, implementing ArrangeOverride and MeasureOverride methods, and using the Children property. Important APIs Panel ArrangeOverride MeasureOverride

The example code shows a custom panel implementation, but we don't devote a lot of time explaining the layout concepts that influence how you can customize a panel for different layout scenarios. If you want more info about these layout concepts and how they might apply to your particular layout scenario, see XAML custom panels overview. A panel is an object that provides a layout behavior for child elements it contains, when the XAML layout system runs and your app UI is rendered. You can define custom panels for XAML layout by deriving a custom class from the Panel class. You provide behavior for your panel by overriding the ArrangeOverride and MeasureOverride methods, supplying logic that measures and arranges the child elements. This example derives from Panel. When you start from Panel, ArrangeOverride and MeasureOverride methods don't have a starting behavior. Your code is providing the gateway by which child elements become known to the XAML layout system and get rendered in the UI. So, it's really important that your code accounts for all child elements and follows the patterns the layout system expects.

Your layout scenario When you define a custom panel, you're defining a layout scenario. A layout scenario is expressed through: What the panel will do when it has child elements When the panel has constraints on its own space How the logic of the panel determines all the measurements, placement, positions, and sizings that eventually result in a rendered UI layout of children With that in mind, the BoxPanel shown here is for a particular scenario. In the interest of keeping the code foremost in this example, we won't explain the scenario in detail yet, and instead concentrate on the steps needed and the coding patterns. If you want to know more about the scenario first, skip ahead to "The scenario for BoxPanel ", and then come back to the code.

Start by deriving from Panel Start by deriving a custom class from Panel. Probably the easiest way to do this is to define a separate code file for this class, using the Add | New Item | Class context menu options for a project from the Solution Explorer in Microsoft Visual Studio. Name the class (and file) BoxPanel . The template file for a class doesn't start with many using statements because it's not specifically for Universal Windows Platform (UWP) apps. So first, add using statements. The template file also starts with a few using

statements that you probably don't need, and can be deleted. Here's a suggested list of using statements that can resolve types you'll need for typical custom panel code: using System; using System.Collections.Generic; // if you need to cast IEnumerable for iteration, or define your own collection properties using Windows.Foundation; // Point, Size, and Rect using Windows.UI.Xaml; // DependencyObject, UIElement, and FrameworkElement using Windows.UI.Xaml.Controls; // Panel using Windows.UI.Xaml.Media; // if you need Brushes or other utilities

Now that you can resolve Panel, make it the base class of

BoxPanel

. Also, make

BoxPanel

public:

public class BoxPanel : Panel { }

At the class level, define some int and double values that will be shared by several of your logic functions, but which won't need to be exposed as public API. In the example, these are named: maxrc , rowcount , colcount , cellwidth , cellheight , maxcellheight , aspectratio . After you've done this, the complete code file looks like this (removing comments on using, now that you know why we have them): using System; using System.Collections.Generic; using Windows.Foundation; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Media; public class BoxPanel : Panel { int maxrc, rowcount, colcount; double cellwidth, cellheight, maxcellheight, aspectratio; }

From here on out, we'll be showing you one member definition at a time, be that a method override or something supporting such as a dependency property. You can add these to the skeleton above in any order, and we won't be showing the using statements or the definition of the class scope again in the snippets until we show the final code.

MeasureOverride

protected override Size MeasureOverride(Size availableSize) { Size returnSize; // Determine the square that can contain this number of items. maxrc = (int)Math.Ceiling(Math.Sqrt(Children.Count)); // Get an aspect ratio from availableSize, decides whether to trim row or column. aspectratio = availableSize.Width / availableSize.Height; // Now trim this square down to a rect, many times an entire row or column can be omitted. if (aspectratio > 1) { rowcount = maxrc; colcount = (maxrc > 2 && Children.Count < maxrc * (maxrc - 1)) ? maxrc - 1 : maxrc; } else { rowcount = (maxrc > 2 && Children.Count < maxrc * (maxrc - 1)) ? maxrc - 1 : maxrc; colcount = maxrc; } // Now that we have a column count, divide available horizontal, that's our cell width. cellwidth = (int)Math.Floor(availableSize.Width / colcount); // Next get a cell height, same logic of dividing available vertical by rowcount. cellheight = Double.IsInfinity(availableSize.Height) ? Double.PositiveInfinity : availableSize.Height / rowcount; foreach (UIElement child in Children) { child.Measure(new Size(cellwidth, cellheight)); maxcellheight = (child.DesiredSize.Height > maxcellheight) ? child.DesiredSize.Height : maxcellheight; } return LimitUnboundedSize(availableSize); }

The necessary pattern of a MeasureOverride implementation is the loop through each element in Panel.Children. Always call the Measure method on each of these elements. Measure has a parameter of type Size. What you're passing here is the size that your panel is committing to have available for that particular child element. So, before you can do the loop and start calling Measure, you need to know how much space each cell can devote. From the MeasureOverride method itself, you have the availableSize value. That is the size that the panel's parent used when it called Measure, which was the trigger for this MeasureOverride being called in the first place. So a typical logic is to devise a scheme whereby each child element divides the space of the panel's overall availableSize. You then pass each division of size to Measure of each child element. How BoxPanel divides size is fairly simple: it divides its space into a number of boxes that's largely controlled by the number of items. Boxes are sized based on row and column count and the available size. Sometimes one row or column from a square isn't needed, so it's dropped and the panel becomes a rectangle rather than square in terms of its row : column ratio. For more info about how this logic was arrived at, skip ahead to "The scenario for BoxPanel". So what does the measure pass do? It sets a value for the read-only DesiredSize property on each element where Measure was called. Having a DesiredSize value is possibly important once you get to the arrange pass, because the DesiredSize communicates what the size can or should be when arranging and in the final rendering. Even if you don't use DesiredSize in your own logic, the system still needs it. It's possible for this panel to be used when the height component of availableSize is unbounded. If that's true, the panel doesn't have a known height to divide. In this case, the logic for the measure pass informs each child that it doesn't have a bounded height, yet. It does so by passing a Size to the Measure call for children where Size.Height is infinite. That's legal. When Measure is called, the logic is that the DesiredSize is set as the minimum of these: what was passed to Measure, or that element's natural size from factors such as explicitly-set Height and Width.

NOTE The internal logic of StackPanel also has this behavior: StackPanel passes an infinite dimension value to Measure on children, indicating that there is no constraint on children in the orientation dimension. StackPanel typically sizes itself dynamically, to accommodate all children in a stack that grows in that dimension.

However, the panel itself can't return a Size with an infinite value from MeasureOverride; that throws an exception during layout. So, part of the logic is to find out the maximum height that any child requests, and use that height as the cell height in case that isn't coming from the panel's own size constraints already. Here's the helper function LimitUnboundedSize that was referenced in previous code, which then takes that maximum cell height and uses it to give the panel a finite height to return, as well as assuring that cellheight is a finite number before the arrange pass is initiated: // This method is called only if one of the availableSize dimensions of measure is infinite. // That can happen to height if the panel is close to the root of main app window. // In this case, base the height of a cell on the max height from desired size // and base the height of the panel on that number times the #rows. Size LimitUnboundedSize(Size input) { if (Double.IsInfinity(input.Height)) { input.Height = maxcellheight * colcount; cellheight = maxcellheight; } return input; }

ArrangeOverride protected override Size ArrangeOverride(Size finalSize) { int count = 1 double x, y; foreach (UIElement child in Children) { x = (count - 1) % colcount * cellwidth; y = ((int)(count - 1) / colcount) * cellheight; Point anchorPoint = new Point(x, y); child.Arrange(new Rect(anchorPoint, child.DesiredSize)); count++; } return finalSize; }

The necessary pattern of an ArrangeOverride implementation is the loop through each element in Panel.Children. Always call the Arrange method on each of these elements. Note how there aren't as many calculations as in MeasureOverride; that's typical. The size of children is already known from the panel's own MeasureOverride logic, or from the DesiredSize value of each child set during the measure pass. However, we still need to decide the location within the panel where each child will appear. In a typical panel, each child should render at a different position. A panel that creates overlapping elements isn't desirable for typical scenarios (although it's not out of the question to create panels that have purposeful overlaps, if that's really your intended scenario). This panel arranges by the concept of rows and columns. The number of rows and columns was already calculated (it was necessary for measurement). So now the shape of the rows and columns plus the known sizes of each cell

contribute to the logic of defining a rendering position (the anchorPoint ) for each element that this panel contains. That Point, along with the Size already known from measure, are used as the two components that construct a Rect. Rect is the input type for Arrange. Panels sometimes need to clip their content. If they do, the clipped size is the size that's present in DesiredSize, because the Measure logic sets it as the minimum of what was passed to Measure, or other natural size factors. So you don't typically need to specifically check for clipping during Arrange; the clipping just happens based on passing the DesiredSize through to each Arrange call. You don't always need a count while going through the loop if all the info you need for defining the rendering position is known by other means. For example, in Canvas layout logic, the position in the Children collection doesn't matter. All the info needed to position each element in a Canvas is known by reading Canvas.Left and Canvas.Top values of children as part of the arrange logic. The BoxPanel logic happens to need a count to compare to the colcount so it's known when to begin a new row and offset the y value. It's typical that the input finalSize and the Size you return from a ArrangeOverride implementation are the same. For more info about why, see "ArrangeOverride" section of XAML custom panels overview.

A refinement: controlling the row vs. column count You could compile and use this panel just as it is now. However, we'll add one more refinement. In the code just shown, the logic puts the extra row or column on the side that's longest in aspect ratio. But for greater control over the shapes of cells, it might be desirable to choose a 4x3 set of cells instead of 3x4 even if the panel's own aspect ratio is "portrait." So we'll add an optional dependency property that the panel consumer can set to control that behavior. Here's the dependency property definition, which is very basic: public static readonly DependencyProperty UseOppositeRCRatioProperty = DependencyProperty.Register("UseOppositeRCRatio", typeof(bool), typeof(BoxPanel), null); public bool UseSquareCells { get { return (bool)GetValue(UseOppositeRCRatioProperty); } set { SetValue(UseOppositeRCRatioProperty, value); } }

And here's how using UseOppositeRCRatio impacts the measure logic. Really all it's doing is changing how rowcount and colcount are derived from maxrc and the true aspect ratio, and there are corresponding size differences for each cell because of that. When UseOppositeRCRatio is true, it inverts the value of the true aspect ratio before using it for row and column counts. if (UseOppositeRCRatio) { aspectratio = 1 / aspectratio;}

The scenario for BoxPanel The particular scenario for BoxPanel is that it's a panel where one of the main determinants of how to divide space is by knowing the number of child items, and dividing the known available space for the panel. Panels are innately rectangle shapes. Many panels operate by dividing that rectangle space into further rectangles; that's what Grid does for its cells. In Grid's case, the size of the cells is set by ColumnDefinition and RowDefinition values, and elements declare the exact cell they go into with Grid.Row and Grid.Column attached properties. Getting good layout from a Grid usually requires knowing the number of child elements beforehand, so that there are enough cells and each child element sets its attached properties to fit into its own cell. But what if the number of children is dynamic? That's certainly possible; your app code can add items to collections, in response to any dynamic run-time condition you consider to be important enough to be worth updating your UI.

If you're using data binding to backing collections/business objects, getting such updates and updating the UI is handled automatically, so that's often the preferred technique (see Data binding in depth). But not all app scenarios lend themselves to data binding. Sometimes, you need to create new UI elements at runtime and make them visible. BoxPanel is for this scenario. A changing number of child items is no problem for BoxPanel because it's using the child count in calculations, and adjusts both the existing and new child elements into a new layout so they all fit. An advanced scenario for extending BoxPanel further (not shown here) could both accommodate dynamic children and use a child's DesiredSize as a stronger factor for the sizing of individual cells. This scenario might use varying row or column sizes or non-grid shapes so that there's less "wasted" space. This requires a strategy for how multiple rectangles of various sizes and aspect ratios can all fit into a containing rectangle both for aesthetics and smallest size. BoxPanel doesn't do that; it's using a simpler technique for dividing space. BoxPanel 's technique is to determine the least square number that's greater than the child count. For example, 9 items would fit in a 3x3 square. 10 items require a 4x4 square. However, you can often fit items while still removing one row or column of the starting square, to save space. In the count=10 example, that fits in a 4x3 or 3x4 rectangle. You might wonder why the panel wouldn't instead choose 5x2 for 10 items, because that fits the item number neatly. However, in practice, panels are sized as rectangles that seldom have a strongly oriented aspect ratio. The least-squares technique is a way to bias the sizing logic to work well with typical layout shapes and not encourage sizing where the cell shapes get odd aspect ratios. NOTE This article is for Windows 10 developers writing Universal Windows Platform (UWP) apps. If you're developing for Windows 8.x or Windows Phone 8.x, see the archived documentation.

Related topics Reference FrameworkElement.ArrangeOverride FrameworkElement.MeasureOverride Panel Concepts Alignment, margin, and padding

Alignment, margin, and padding 3/6/2017 • 8 min to read • Edit on GitHub

In addition to dimension properties (width, height, and constraints), elements can also have alignment, margin, and padding properties that influence the layout behavior when an element goes through a layout pass and is rendered in a UI. There are relationships between alignment, margin, padding and dimension properties that have a typical logic flow when a FrameworkElement object is positioned, such that values are sometimes used and sometimes ignored depending on the circumstances.

Alignment properties The HorizontalAlignment and VerticalAlignment properties describe how a child element should be positioned within a parent element's allocated layout space. By using these properties together, layout logic for a container can position child elements within the container (either a panel or a control). Alignment properties are intended to hint the desired layout to an adaptive layout container, so basically they're set on FrameworkElement children and interpreted by another FrameworkElement container parent. Alignment values can specify whether elements align to one of the two edges of an orientation, or to the center. However, the default value for both alignment properties is Stretch. With Stretch alignment, elements fill the space they're provided in layout. Stretch is the default so that it's easier to use adaptive layout techniques in the cases where there is no explicit measurement or no DesiredSize value that came from the measure pass of layout. With this default, there's no risk of an explicit height/width not fitting within the container and being clipped until you size each container. NOTE As a general layout principle, it's best to only apply measurements to certain key elements and use the adaptive layout behavior for the other elements. This provides flexible layout behavior for when the user sizes the top app window, which typically is possible to do at any time.

If there are either Height and Width values or clipping within an adaptive container, even if Stretch is set as an alignment value, the layout is controlled by the behavior of its container. In panels, a Stretch value that's been obviated by Height and Width acts as if the value is Center. If there are no natural or calculated height and width values, these dimension values are mathematically NaN (Not A Number). The elements are waiting for their layout container to give them dimensions. After layout is run, there will be values for ActualHeight and ActualWidth properties for elements where a Stretch alignment was used. The NaN values remain in Height and Width for the child elements so that the adaptive behavior can run again, for example, if layout-related changes such as app window sizing causes another layout cycle. Text elements such as TextBlock don't usually have an explicitly declared width, but they do have a calculated width that you can query with ActualWidth, and that width also cancels out a Stretch alignment. (The FontSize property and other text properties, as well as the text itself, are already hinting the intended layout size. You don't typically want your text to be stretched.) Text used as content within a control has the same effect; the presence of text that needs presenting causes an ActualWidth to be calculated, and this also commutes a desired width and size to the containing control. Text elements also have an ActualHeight based on font size per line, line breaks, and other text properties. A panel such as Grid already has other logic for layout (row and column definitions, and attached properties such as Grid.Row set on elements to indicate which cell to be drawn in). In that case, the alignment properties influence how the content is aligned within the area of that cell, but the cell structure and sizing is controlled by

settings on the Grid. Item controls sometimes display items where the base types of the items are data. This involves an ItemsPresenter. Although the data itself is not a FrameworkElement derived type, ItemsPresenter is, so you can set HorizontalAlignment and VerticalAlignment for the presenter and that alignment applies to the data items when presented in the items control. Alignment properties are only relevant for cases when there's extra space available in a dimension of the parent layout container. If a layout container is already clipping content, alignment can affect the area of the element where the clipping will apply. For example, if you set HorizontalAlignment="Left" , the right size of the element gets clipped.

Margin The Margin property describes the distance between an element and its peers in a layout situation, and also the distance between an element and the content area of a container that contains the element. If you think of elements as bounding boxes or rectangles where the dimensions are the ActualHeight and ActualWidth, the Margin layout applies to the outside of that rectangle and does not add pixels to the ActualHeight and ActualWidth. The margin is also not considered part of the element for purposes of hit testing and sourcing input events. In general layout behavior, components of a Margin value are constrained last, and are constrained only after Height and Width are already constrained all the way to 0. So, be careful with margins when the container is already clipping or constraining the element; otherwise, your margin could be the cause of an element not appearing to render (because one of its dimensions has been constrained to 0 after the margin was applied). Margin values can be uniform, by using syntax like Margin="20" . With this syntax, a uniform margin of 20 pixels would be applied to the element, with a 20-pixel margin on the left, top, right, and bottom sides. Margin values can also take the form of four distinct values, each value describing a distinct margin to apply to the left, top, right, and bottom (in that order). For example, Margin="0,10,5,25" . The underlying type for the Margin property is a Thickness structure, which has properties that hold the Left, Top, Right, and Bottom values as separate Double values. Margins are additive. For example, if two elements each specify a uniform margin of 10 pixels and they are adjacent peers in any orientation, the distance between the elements is 20 pixels. Negative margins are permitted. However, using a negative margin can often cause clipping, or overdraws of peers, so it's not a common technique to use negative margins. Proper use of the Margin property enables very fine control of an element's rendering position and the rendering position of its neighbor elements and children. When you use element dragging to position elements within the XAML designer in Visual Studio, you'll see that the modified XAML typically has values for Margin of that element that were used to serialize your positioning changes back into the XAML. The Block class, which is a base class for Paragraph, also has a Margin property. It has an analogous effect on how that Paragraph is positioned within its parent container, which is typically a RichTextBlock or RichEditBox object, and also how more than one paragraph is positioned relative to other Block peers from the RichTextBlock.Blocks collection.

Padding A Padding property describes the distance between an element and any child elements or content that it contains. Content is treated as a single bounding box that encloses all the content, if it's an element that permits more than one child. For example, if there's an ItemsControl that contains two items, the Padding is applied around the bounding box that contains the items. Padding subtracts from the available size when it comes to the measure and arrange pass calculations for that container and are part of the desired size values when the

container itself goes through the layout pass for whatever contains it. Unlike Margin, Padding is not a property of FrameworkElement, and in fact there are several classes which each define their own Padding property: Control.Padding: inherits to all Control derived classes. Not all controls have content, so for some controls (for example AppBarSeparator) setting the property does nothing. If the control has a border (see Control.BorderThickness), the padding applies inside that border. Border.Padding: defines space between the rectangle line created by BorderThickness/BorderBrush and the Child element. ItemsPresenter.Padding: contributes to appearance of the generated visuals for items in item controls, placing the specified padding around each item. TextBlock.Padding and RichTextBlock.Padding: expands the bounding box around the text of the text element. These text elements don't have a Background, so it can be visually difficult to see what's the text's padding versus other layout behavior applied by the text element's container. For that reason, text element padding is seldom used and it's more typical to use Margin settings on contained Block containers (for the RichTextBlock case). In each of these cases, the same element also has a Margin property. If both margin and padding are applied, they are additive in the sense that the apparent distance between an outer container and any inner content will be margin plus padding. If there are different background values applied to content, element or container, the point at which margin ends and padding begins is potentially visible in the rendering.

Dimensions (Height, Width) The Height and Width properties of a FrameworkElement often influence how the alignment, margin, and padding properties behave when a layout pass happens. In particular, real-number Height and Width value cancels Stretch alignments, and is also promoted as a possible component of the DesiredSize value that's established during the measure pass of the layout. Height and Width have constraint properties: the Height value can be constrained with MinHeight and MaxHeight, the Width value can be constrained with MinWidth and MaxWidth. Also, ActualWidth and ActualHeight are calculated, read-only properties that only contain valid values after a layout pass has completed. For more info about how the dimensions and constraints or calculated properties interrelate, see Remarks in FrameworkElement.Height and FrameworkElement.Width.

Related topics Reference FrameworkElement.Height FrameworkElement.Width FrameworkElement.HorizontalAlignment FrameworkElement.VerticalAlignment FrameworkElement.Margin Control.Padding

Create a simple weather app by using Grid and StackPanel 3/6/2017 • 4 min to read • Edit on GitHub

Use XAML to create the layout for a simple weather app using the Grid and StackPanel elements. With these tools you can make great looking apps that work on any device running Windows 10. This tutorial takes 10-20 minutes.

Prerequisites Windows 10 and Microsoft Visual Studio 2015. Click here to learn how to get set up with Visual Studio. Knowledge of how to create a basic "Hello World" app by using XAML and C#. If you don't have that yet, click here to learn how to create a "Hello World" app.

Step 1: Create a blank app 1. In Visual Studio menu, select File > New Project. 2. In the left pane of the New Project dialog box, select Visual C# > Windows > Universal or Visual C++ > Windows > Universal. 3. In the center pane, select Blank App. 4. In the Name box, enter WeatherPanel, and select OK. 5. To run the program, select Debug > Start Debugging from the menu, or select F5.

Step 2: Define a Grid In XAML a Grid is made up of a series of rows and columns. By specifying the row and column of an element within a Grid, you can place and space other elements within a user interface. Rows and columns are defined with the RowDefinition and ColumnDefinition elements. To start creating a layout, open MainPage.xaml by using the Solution Explorer, and replace the automatically generated Grid element with this code.

The new Grid creates a set of two rows and columns, which defines the layout of the app interface. The first column has a Width of "3*", while the second has "5*", dividing the horizontal space between the two columns at a ratio of 3:5. In the same way, the two rows have a Height of "3*" and "*" respectively, so the Grid allocates three times as much space for the first row as for the second ("*" is the same as "1*"). These ratios are maintained even if the window is resized or the device is changed. To learn about other methods of sizing rows and columns, see Define layouts with XAML. If you run the application now you won't see anything except a blank page, because none of the Grid areas have

any content. To show the Grid let's give it some color.

Step 3: Color the Grid To color the Grid we add three Border elements, each with a different background color. Each is also assigned to a row and column in the parent Grid by using the Grid.Row and Grid.Column attributes. The values of these attributes default to 0, so you don't need to assign them to the first Border. Add the following code to the Grid element after the row and column definitions.

Notice that for the third Border we use an extra attribute, Grid.ColumnSpan, which causes this Border to span both columns in the lower row. You can use Grid.RowSpan in the same way, and together these attributes let you span an element over any number of rows and columns. The upper-left corner of such a span is always the Grid.Column and Grid.Row specified in the element attributes. If you run the app, the result looks something like this.

Step 4: Organize content by using StackPanel elements StackPanel is the second UI element we'll use to create our weather app. The StackPanel is a fundamental part of many basic app layouts, allowing you to stack elements vertically or horizontally. In the following code, we create two StackPanel elements and fill each with three TextBlocks. Add these StackPanel elements to the Grid below the Border elements from Step 3. This causes the TextBlock elements to render on top of the colored Grid we created earlier.

In the first Stackpanel, each TextBlock stacks vertically below the next. This is the default behavior of a StackPanel, so we don't need to set the Orientation attribute. In the second StackPanel, we want the child elements to stack horizontally from left to right, so we set the Orientation attribute to "Horizontal". We must also set the Grid.ColumnSpan attribute to "2", so that the text is centered over the lower Border. If you run the app now, you'll see something like this.

Step 5: Add an image icon Finally, let's fill the empty section in our Grid with an image that represents today's weather—something that says "partially cloudy." Download the image below and save it as a PNG named "partially-cloudy".

In the Solution Explorer, right click the Assets folder, and select Add -> Existing Item... Find partiallycloudy.png in the browser that pops up, select it, and click Add. Next, in MainPage.xaml, add the following Image element below the StackPanels from Step 4.

Because we want the Image in the first row and column, we don't need to set its Grid.Row or Grid.Column attributes, allowing them to default to "0". And that's it! You've successfully created the layout for a simple weather application. If you run the application by pressing F5, you should see something like this:

If you like, try experimenting with the layout above, and explore different ways you might represent weather data.

Related articles For an introduction to designing UWP app layouts, see Introduction to UWP app design To learn about creating responsive layouts that adapt to different screen sizes, see Define Page Layouts with XAML

UWP style guide 3/6/2017 • 1 min to read • Edit on GitHub

Design guidance and code examples that teach you how to define your UWP app’s personality through color, typography, and motion.

Color Color provides intuitive wayfinding through an app's various levels of information and serves as a crucial tool for reinforcing the interaction model. Icons Good icons harmonize with typography and with the rest of the design language. They don’t mix metaphors, and they communicate only what’s needed, as speedily and simply as possible.

Motion Purposeful, well-designed animations bring apps to life and make the experience feel crafted and polished. Help users understand context changes, and tie experiences together with visual transitions. Sound Sound helps complete an application's user experience, and gives them that extra audio edge they need to match the feel of Windows across all platforms.

Typography As the visual representation of language, typography’s main task is to be clear. Its style should never get in the way of that goal. But typography also has an important role as a layout component—with a powerful effect on the density and complexity of the design—and on the user’s experience of that design. Fonts Segoe MDL2 icons Styling controls You can customize the appearance of your apps in many ways by using the XAML framework. Styles let you set control properties and reuse those settings for a consistent appearance across multiple controls.

Color 3/6/2017 • 3 min to read • Edit on GitHub

Color provides intuitive way of finding through an app's various levels of information and serves as a crucial tool for reinforcing the interaction model. In Windows, color is also personal. Users can choose a color and a light or dark theme to be reflected throughout their experience.

Accent color The user can pick a single color called the accent from Settings > Personalization > Colors. They have their choice from a curated set of 48 color swatches, except on Xbox which has a palette of 21 TV-safe colors. Default accent colors

FFB900

E74856

0078D7

0099BC

7A7574

767676

FF8C00

E81123

0063B1

2D7D9A

5D5A58

4C4A48

F7630C

EA005E

8E8CD8

00B7C3

68768A

69797E

CA5010

C30052

6B69D6

038387

515C6B

4A5459

DA3B01

E3008C

8764B8

00B294

567C73

647C64

EF6950

BF0077

744DA9

018574

486860

525E54

D13438

C239B3

B146C2

00CC6A

498205

847545

FF4343

9A0089

881798

10893E

107C10

7E735F

ED5588

1073D6

148282

107C10

4C4A4B

Xbox accent colors

EB8C10

EB4910

BF1077

193E91

54A81B

737373

7E715C

E31123

B144C0

1081CA

547A72

677488

724F2F

A21025

744DA9

108272

When users choose an accent color, it appears as part of their system theme. The areas affected are Start, Taskbar, window chrome, selected interaction states and hyperlinks within common controls. Each app can further incorporate the accent color through their typography, backgrounds, and interactions—or override it to preserve their specific branding.

Color palette building blocks Once an accent color is selected, light and dark shades of the accent color are created based on HSB values of color luminosity. Apps can use shade variations to create visual hierarchy and to provide an indication of interaction. By default, hyperlinks will use the user's accent color. If the page background is a similar color, you can choose to assign a lighter (or darker) shade of accent to the hyperlinks for better contrast.

The various light/dark shades of the default accent color.

An example of how color logic gets applied to a design spec.

NOTE In XAML, the primary accent color is exposed as a theme resource named SystemAccentColor . The shades are available as SystemAccentColorLight3 , SystemAccentColorLight2 , SystemAccentColorLight1 , SystemAccentColorDark1 , SystemAccentColorDark2 , and SystemAccentColorDark3 . Also available programmatically via UISettings.GetColorValue and the UIColorType enum.

Color theming The user may also choose between a light or dark theme for the system. Some apps choose to change their theme based on the user’s preference, while others opt out. Apps using light theme are for scenarios involving productivity apps. Examples would be the suite of apps available with Microsoft Office. Light theme affords the ease of reading long lengths of text in conjunction with prolonged periods of time-at-task. Dark theme allows more visible contrast of content for apps that are media centric or scenarios where users are presented with an abundance of videos or imagery. In these scenarios, reading is not necessarily the primary task, though a movie watching experience might be, and shown under low-light ambient conditions. If your app doesn’t quite fit either of these descriptions, consider following the system theme to let the user decide what's right for them. To make designing for themes easier, Windows provides an additional color palette that automatically adapts to the theme. Light theme Base

Alt

List

Chrome

Dark theme Base

Alt

List

Chrome

Changing the theme You can change themes easily by changing the RequestedTheme property in your App.xaml:

Removing the RequestedTheme means that your application will honor the user’s app mode settings, and they will be able to choose to view your app in either the dark or light theme. Make sure that you take the theme into consideration when creating your app, as the theme has a big impact on the look of your app.

Accessibility Our palette is optimized for screen usage. We recommend maintaining a contrast ratio for text of 4.5:1 against the

background for optimal readability. There are many free tools available to test whether or not your colors pass, like Contrast Ratio.

Related articles XAML Styles XAML Theme Resources

Icons for UWP apps 3/6/2017 • 2 min to read • Edit on GitHub

Good icons harmonize with typography and with the rest of the design language. They don’t mix metaphors, and they communicate only what’s needed, as speedily and simply as possible.

Linear scaling size ramps 16px x 16px

24px x 24px

32px x 32px

48px x 48px

Common shapes Icons should generally maximize their given space with little padding. These shapes provide starting points for sizing basic shapes.

Use the shape that corresponds to the icon's orientation and compose around these basic parameters. Icons don't necessarily need to fill or fit completely inside the shape and may be adjusted as needed to ensure optimal balance.

Circle

Square

Horizontal rectangle

Vertical rectangle

Triangle

Angles In addition to using the same grid and line weight, icons are constructed with common elements. Using only these angles in building shapes creates consistency across all our icons, and ensures the icons render correctly. These lines can be combined, joined, rotated, and reflected in creating icons.

1:1 45°

Here are some examples:

1:2 26.57° (vertical) 63.43° (horizontal)

1:3 18.43° (vertical) 71.57° (horizontal)

1:4 14.04° (vertical) 75.96° (horizontal)

Curves Curved lines are constructed from sections of a whole circle and should not be skewed unless needed to snap to the pixel grid.

1/4 circle

1/8 circle

Geometric construction We recommend using only pure geometric shapes when constructing icons.

Filled shapes Icons can contain filled shapes when needed, but they should not be more than 4px at 32px × 32px. Filled circles should not be larger than 6px × 6px.

Badges A "badge" is a generic term used to describe an element added to an icon that's not meant to be integrated with the base icon element. These usually convey other pieces of information about the icon like status or action. Other commons terms include: overlay, annotation, or modifier.

Status badges utilize a filled, colored object that is on top of the icon, whereas action badges are integrated into the icon in the same monochrome style and line weight. Common status badges

Common action badges

Badge color

Color badging should only be used to convey the state of an icon. The colors used in status badging convey specific emotional messages to the user. Green - #128B44

Blue - #2C71B9

Yellow - #FDC214

Positive: done, completed

Neutral: help, notification

Cautionary: alert, warning

Badge position

The default position for any status or action is the bottom right. Only use the other positions when the design will not allow it. Badge sizing

Badges should be sized to 10–18 px on a 32 px × 32 px grid.

Related articles Guidelines for tile and icon assets

Motion for UWP apps 3/6/2017 • 2 min to read • Edit on GitHub

Purposeful, well-designed animations bring apps to life and make the experience feel crafted and polished. Help users understand context changes, and tie experiences together with visual transitions.

Benefits of animation Animation is more than making things move. Animation is a tool for creating a physical ecosystem for the user to live inside and manipulate through touch. The quality of the experience depends on how well the app responds to the user, and what kind of personality the UI communicates. Make sure animation serves a purpose in your app. The best Universal Windows Platform (UWP) apps use animation to bring the UI to life. Animation should: Give feedback based on the user's behavior. Teach the user how to interact with the UI. Indicate how to navigate to previous or succeeding views. As a user spends more time inside your app, or as tasks in your app become more sophisticated, high-quality animation becomes increasingly important: it can be used to change how the user perceives their cognitive load and your app's ease of use. Animation has many other direct benefits: Animation adds hints towards interaction. Animation is directional: it moves forward and backward, in and out of content, leaving minimal "breadcrumb" clues as to how the user arrived at the present view. Animation can give the impression of enhanced performance. When network speeds lag or the system pauses to work, animations can make the user's wait feel shorter. Animation adds personality. The well-considered Windows Phone UI uses motion to create the impression that an app is concerned with the here and now, and helps counteract the sensation that the user is burrowing into nested hierarchies. Animation adds consistency. Transitions can help users learn how to operate new applications by drawing analogies to tasks that the user is already familiar with. Animation adds elegance. Animations can be used to let the user know that the phone is processing, not frozen, and it can passively surface new information that the user may be interested in.

In this section

ANIMATION TYPE

DESCRIPTION

Add and delete

List animations let you insert or remove single or multiple items from a collection, such as a photo album or a list of search results.

Drag and drop

Use drag-and-drop animations when users move objects, such as moving an item within a list, or dropping an item on top of another.

Edge

Edge-based animations show or hide UI that originates from the edge of the screen. The show and hide actions can be initiated either by the user or by the app. The UI can either overlay the app or be part of the main app surface. If the UI is part of the app surface, the rest of the app might need to be resized to accommodate it.

Fade

Use fade animations to bring items into a view or to take items out of a view. The two common fade animations are fade-in and fade-out.

Pointer

Pointer animations provide users with visual feedback when the user taps on an item. The pointer down animation slightly shrinks and tilts the pressed item, and plays when an item is first tapped. The pointer up animation, which restores the item to its original position, is played when the user releases the pointer.

Pop-up animations

Use pop-up animations to show and hide pop-up UI for flyouts or custom pop-up UI elements. Pop-up elements are containers that appear over the app's content and are dismissed if the user taps or clicks outside of the pop-up element.

Reposition

Move elements into a new position.

Sound 3/6/2017 • 4 min to read • Edit on GitHub

There are many ways to use sound to enhance your app. You can use to sound to supplement other UI elements, enabling users to recognize events audibly. Sound can be an effective user interface element for people with visual disabilities. You can use sound to create an atmosphere that immerses the user; for example, you might play a whimsical soundtrack in the background of puzzle game, or use ominous sound effects for a horror/survival game.

Sound Global API UWP provides an easily accessible sound system that allows you to simply "flip a switch" and get an immersive audio experience across your entire app. The ElementSoundPlayer is an integrated sound system within XAML, and when turned on all default controls will play sounds automatically. ElementSoundPlayer.State = ElementSoundPlayerState.On;

The ElementSoundPlayer has three different states: On Off and Auto. If set to Off, no matter where your app is run, sound will never play. If set to On sounds for your app will play on every platform. Sound for TV and Xbox

Sound is a key part of the 10-foot experience, and by default, the ElementSoundPlayer's state is Auto, meaning that you will only get sound when your app is running on Xbox. To understand more about designing for Xbox and TV, please see Designing for Xbox and TV.

Sound Volume Override All sounds within the app can be dimmed with the Volume control. However, sounds within the app cannot get louder than the system volume. To set the app volume level, call: ElementSoundPlayer.Volume = 0.5f;

Where maximum volume (relative to system volume) is 1.0, and minimum is 0.0 (essentially silent).

Control Level State If a control's default sound is not desired, it can be disabled. This is done through the ElementSoundMode on the control. The ElementSoundMode has two states: Off and Default. When not set, it is Default. If set to Off, every sound that control plays will be muted except for focus.

ButtonName.ElementSoundState = ElementSoundMode.Off;

Is This The Right Sound? When creating a custom control, or changing an existing control's sound, it is important to understand the usages of all the sounds the system provides. Each sound relates to a certain basic user interaction, and although sounds can be customized to play on any interaction, this section serves to illustrate the scenarios where sounds should be used to maintain a consistent experience across all UWP apps. Invoking an Element

The most common control-triggered sound in our system today is the Invoke sound. This sound plays when a user invokes a control through a tap/click/enter/space or press of the 'A' button on a gamepad. Typically, this sound is only played when a user explicitly targets a simple control or control part through an input device. To play this sound from any control event, simply call the Play method from ElementSoundPlayer and pass in ElementSound.Invoke: ElementSoundPlayer.Play(ElementSoundKind.Invoke);

Showing & Hiding Content

There are many flyouts, dialogs and dismissible UIs in XAML, and any action that triggers one of these overlays should call a Show or Hide sound. When an overlay content window is brought into view, the Show sound should be called: ElementSoundPlayer.Play(ElementSoundKind.Show);

Conversely when an overlay content window is closed (or is light dismissed), the Hide sound should be called: ElementSoundPlayer.Play(ElementSoundKind.Hide);

Navigation Within a Page

When navigating between panels or views within an app's page (see Hub or Tabs and Pivots), there is typically bidirectional movement. Meaning you can move to the next view/panel or the previous one, without leaving the current app page you're on. The audio experience around this navigation concept is encompassed by the MovePrevious and MoveNext sounds. When moving to a view/panel that is considered the next item in a list, call: ElementSoundPlayer.Play(ElementSoundKind.MoveNext);

And when moving to a previous view/panel in a list considered the previous item, call: ElementSoundPlayer.Play(ElementSoundKind.MovePrevious);

Back Navigation

When navigating from the current page to the previous page within an app the GoBack sound should be called: ElementSoundPlayer.Play(ElementSoundKind.GoBack);

Focusing on an Element

The Focus sound is the only implicit sound in our system. Meaning a user isn't directly interacting with anything, but is still hearing a sound. Focusing happens when a user navigates through an app, this can be with the gamepad/keyboard/remote or kinect. Typically the Focus sound does not play on PointerEntered or mouse hover events. To set up a control to play the Focus sound when your control receives focus, call: ElementSoundPlayer.Play(ElementSoundKind.Focus);

Cycling Focus Sounds

As an added feature to calling ElementSound.Focus, the sound system will, by default, cycle through 4 different sounds on each navigation trigger. Meaning that no two exact focus sounds will play right after the other. The purpose behind this cycling feature is to keep the focus sounds from becoming monotonous and from being noticeable by the user; focus sounds will be played most often and therefore should be the most subtle.

Related articles Designing for Xbox and TV

Typography 3/6/2017 • 6 min to read • Edit on GitHub

As the visual representation of language, typography’s main task is to be clear. Its style should never get in the way of that goal. But typography also has an important role as a layout component—with a powerful effect on the density and complexity of the design—and on the user’s experience of that design.

Typeface We’ve selected Segoe UI for use on all Microsoft digital designs. Segoe UI provides a wide range of characters and is designed to maintain optimal legibility across sizes and pixel densities. It offers a clean, light, and open aesthetic that complements the content of the system.

Weights We approach typography with an eye to simplicity and efficiency. We choose to use one typeface, a minimum of weights and sizes, and a clear hierarchy. Positioning and alignment follow the default style for the given language. In English the sequence runs left to right, top to bottom. Relationships between text and images are clear and straightforward.

Line spacing

Line spacing should be calculated at 125% of the font size, rounding to the closest multiple of four when necessary. For example with 15px Segoe UI, 125% of 15px is 18.75px. We recommend rounding up and setting line height to 20px to stay on the 4px grid. This ensures a good reading experience and adequate space for diacritical marks. See

the Type ramp section below for specific examples. When stacking larger type on top of smaller type, the distance from the last baseline of the larger type to the first baseline of the smaller type should be equal to the larger type's line height.

In XAML, this is accomplished by stacking two TextBlocks and setting the appropriate margin.

Kerning and tracking Segoe is a humanist typeface, with a soft, friendly appearance, it has organic, open forms based on handwritten text. To ensure optimum legibility and maintain it’s humanist integrity, the kerning and tracking settings must have specific values. Kerning should be set to “metrics” and tracking should be set to “0”.

Word and letter spacing Similar to kerning and tracking, word spacing and letter spacing use specific settings to ensure optimum legibility and humanist integrity. Word spacing by default is always 100% and letter spacing should be set to “0”.

NOTE In a XAML text control use Typogrphy.Kerning to control kerning and FontStretch to control tracking. By default Typography.Kerning is set to “true” and FontStretch is set to “Normal”, which are the recommended values.

Alignment Generally, we recommend that visual elements and columns of type be left-aligned. In most instances, this flushleft and ragged-right approach provides consistent anchoring of the content and a uniform layout.

Line endings When typography is not positioned as flush left and ragged right, try to ensure even line endings and avoid hyphenation.

Paragraphs To provide aligned column edges, paragraphs should be indicated by skipping a line without indentation.

Character count If a line is too short, the eye will have to travel left and right too often, breaking the reader’s rhythm. If possible, 50– 60 letters per line is best for ease of reading. Segoe provides a wide range of characters and is designed to maintain optimal legibility in both small and large sizes as well as low and high pixel densities. Using the optimal number of letters in a text column line ensures good legibility in an application. Lines that are too long will strain the eye and may disorient the user. Lines that are too short force the reader’s eye to travel too much and can cause fatigue.

Hanging text alignment The horizontal alignment of icons with text can be handled in a number of ways depending on the size of the icon and the amount of text. When the text, either single or multiple lines, fits within the height of the icon, the text should be vertically centered.

Once the height of the text extends beyond the height of the icon, the first line of text should align vertically and the additional text should flow on naturally below. When using characters with larger cap, ascender and descender heights, care should be taken to observe the same alignment guidance.

NOTE XAML's TextBlock.TextLineBounds property provides access to the cap height and baseline font metrics. It can be used to visually vertically center or top-align type.

Clipping and ellipses Clip by default—assume that text will wrap unless the redline specifies otherwise. When using non-wrapping text, we recommend clipping rather than using ellipses. Clipping can occur at the edge of the container, at the edge of the device, at the edge of a scrollbar, etc. Exceptions—for containers which are not well-defined (e.g. no differentiating background color), then nonwrapping text can be redlined to use the ellipse ”…”.

Type ramp The type ramp establishes a crucial design relationship from headlines to body text and ensures a clear and understandable hierarchy between the different levels. This hierarchy builds a structure which enables users to easily navigate through written communication.

All sizes are in effective pixels. For more details, see Intro to UWP app design.

NOTE Most levels of the ramp are available as XAML static resources that follow the HeaderTextBlockStyle ).

*TextBlockStyle

naming convention (ex:

Primary and secondary text To create additional hierarchy beyond the type ramp, set secondary text to 60% opacity. In the theming color palette, you would use BaseMedium. Primary text should always be at 100% opacity, or BaseHigh.

All caps titles Certain page titles should be in ALL CAPS to add yet another dimension of hierarchy. These titles should use BaseAlt with the character spacing set to 75 thousandths of an em. This treatment may also be used to help with app navigation. However, proper names change their meaning when capitalized in certain languages, so any page titles based on names or user input should not be converted to all caps.

Do's and don'ts Use Body for most text Use Base for titles when space is constrained Incorporate SubtitleAlt to create contrast and hierarchy by emphasizing top level content Don't use Caption for long strings or any primary action Don't use Header or Subheader if text needs to wrap Don't combine Subtitle and SubtitleAlt on the same page

Related articles Text controls Fonts Segoe MDL2 icons

Fonts for UWP apps 3/6/2017 • 3 min to read • Edit on GitHub

This article lists the recommended fonts for UWP apps. These fonts are guaranteed to be available in all Windows 10 editions that support UWP apps. Important APIs FontFamily property

The UWP typography guide recommends that apps use the Segoe UI font, and although Segoe UI is a great choice for most apps, you don't have to use it for everything. You might use other fonts for certain scenarios, such as reading, or when displaying text in certain non-English languages.

Sans-serif fonts Sans-serif fonts are a great choice for headings and UI elements. FONT-FAMILY

STYLES

NOTES

Arial

Regular, Italic, Bold, Bold Italic, Black

Supports European and Middle Eastern scripts (Latin, Greek, Cyrillic, Arabic, Armenian, and Hebrew) Black weight supports European scripts only.

Calibri

Regular, Italic, Bold, Bold Italic, Light, Light Italic

Supports European and Middle Eastern scripts (Latin, Greek, Cyrillic, Arabic and Hebrew). Arabic available in the uprights only.

Consolas

Regular, Italic, Bold, Bold Italic

Fixed width font that supports European scripts (Latin, Greek and Cyrillic).

Segoe UI

Regular, Italic, Light Italic, Black Italic, Bold, Bold Italic, Light, Semilight, Semibold, Black

User-interface font for European and Middle East scripts (Arabic, Armenian, Cyrillic, Georgian, Greek, Hebrew, Latin), and also Lisu script.

Segoe UI Historic

Regular

Fallback font for historic scripts

Selawik

Regular, Semilight, Light, Bold, Semibold

An open-source font that's metrically compatible with Segoe UI, intended for apps on other platforms that don’t want to bundle Segoe UI. Get Selawik on GitHub.

Verdana

Regular, Italic, Bold, Bold Italic

Supports European scripts (Latin, Greek, Cyrillic and Armenian).

Serif fonts

Serif fonts are good for presenting large amounts of text. FONT-FAMILY

STYLES

NOTES

Cambria

Regular

Serif font that supports European scripts (Latin, Greek, Cyrillic).

Courier New

Regular, Italic, Bold, Bold Italic

Serif fixed width font supports European and Middle Eastern scripts (Latin, Greek, Cyrillic, Arabic, Armenian, and Hebrew).

Georgia

Regular, Italic, Bold, Bold Italic

Supports European scripts (Latin, Greek and Cyrillic).

Times New Roman

Regular, Italic, Bold, Bold Italic

Legacy font that supports European scripts (Latin, Greek, Cyrillic, Arabic, Armenian, Hebrew).

FONT-FAMILY

STYLES

NOTES

Segoe MDL2 Assets

Regular

User-interface font for app icons. For more info, see the Segoe MDL2 assets article.

Segoe UI Emoji

Regular

Segoe UI Symbol

Regular

Symbols and icons

Fallback font for symbols

Fonts for non-Latin languages Although many of these fonts provide Latin characters. FONT-FAMILY

STYLES

NOTES

Ebrima

Regular, Bold

User-interface font for African scripts (Ethiopic, N'Ko, Osmanya, Tifinagh, Vai).

Gadugi

Regular, Bold

User-interface font for North American scripts (Canadian Syllabics, Cherokee).

Javanese Text Regular Fallback font for Javanese script

Regular

Fallback font for Javanese script

Leelawadee UI

Regular, Semilight, Bold

User-interface font for Southeast Asian scripts (Buginese, Lao, Khmer, Thai).

Malgun Gothic

Regular

User-interface font for Korean.

Microsoft Himalaya

Regular

Fallback font for Tibetan script.

Microsoft JhengHei UI

Regular, Bold, Light

User-interface font for Traditional Chinese.

FONT-FAMILY

STYLES

NOTES

Microsoft New Tai Lue

Regular

Fallback font for New Tai Lue script.

Microsoft PhagsPa

Regular

Fallback font for Phags-pa script.

Microsoft Tai Le

Regular

Fallback font for Tai Le script.

Microsoft YaHei UI

Regular, Bold, Light

User-interface font for Simplified Chinese.

Microsoft Yi Baiti

Regular

Fallback font for Yi script.

Mongolian Baiti

Regular

Fallback font for Mongolian script.

MV Boli

Regular

Fallback font for Thaana script.

Myanmar Text

Regular

Fallback font for Myanmar script.

Nirmala UI

Regular, Semilight, Bold

User-interface font for South Asian scripts (Bangla, Devanagari, Gujarati, Gurmukhi, Kannada, Malayalam, Odia, Ol Chiki, Sinhala, Sora Sompeng, Tamil, Telugu)

SimSun

Regular

A legacy Chinese UI font.

Yu Gothic

Medium

Yu Gothic UI

Regular

User-interface font for Japanese.

Globalizing/localizing fonts Use the LanguageFont font-mapping APIs for programmatic access to the recommended font family, size, weight, and style for a particular language. The LanguageFont object provides access to the correct font info for various categories of content including UI headers, notifications, body text, and user-editable document body fonts. For more info, see Adjusting layout and fonts to support globalization.

Get the samples Downloadable fonts sample UI basics sample Line spacing with DirectWrite sample

Related articles Adjusting layout and fonts to support globalization Segoe MDL2 Text controls) XAML theme resources

Segoe MDL2 icons 3/8/2017 • 15 min to read • Edit on GitHub

This article lists the icons provided by the Segoe MDL2 Assets font. Important APIs Symbol enumeration (XAML)

About Segoe MDL2 Assets With the release Windows 10, the Segoe MDL2 Assets font replaced the Windows 8/8.1 Segoe UI Symbol icon font. ( Segoe UI Symbol will still be available as a "legacy" resource, but we recommend updating your app to use the new Segoe MDL2 Assets.) Most of the icons and UI controls included in the Segoe MDL2 Assets font are mapped to the Private Use Area of Unicode (PUA). The PUA allows font developers to assign private Unicode values to glyphs that don’t map to existing code points. This is useful when creating a symbol font, but it creates an interoperability problem. If the font is not available, the glyphs won’t show up. Only use these glyphs when you can specify the Segoe MDL2 Assets font. Use these glyphs only when you can explicitly specify the Segoe MDL2 Assets font. If you are working with tiles, you can't use these glyphs because you can't specify the tile font and PUA glyphs are not available via fontfallback. Unlike with Segoe UI Symbol, the icons in the Segoe MDL2 Assets font are not intended for use in-line with text. This means that some older "tricks" like the progressive disclosure arrows no longer apply. Likewise, since all of the new icons are sized and positioned the same, they do not have to be made with zero width; we have just made sure they work as a set. Ideally, you can overlay two icons that were designed as a set and they will fall into place. We may do this to allow colorization in the code. For example, U+EA3A and U+EA3B were created for the Start tile Badge status. Because these are already centered the circle fill can be colored for different states.

Layering and mirroring All glyphs in Segoe MDL2 Assets have the same fixed width with a consistent height and left origin point, so layering and colorization effects can be achieved by drawing glyphs directly on top of each other. This example show a black outline drawn on top of the zero-width red heart.

Many of the icons also have mirrored forms available for use in languages that use right-to-left text directionality such as Arabic, Farsi, and Hebrew.

Symbol enumeration If you are developing an app in C#/VB/C++ and XAML, you can use the Symbol enumeration to use icons from the Segoe MDL2 Assets font.

How do I get this font?

To obtain Segoe MDL2 Assets, you must install Windows 10.

Icon list Symbol

Unicode point

Description

E001

CheckMarkLegacy

E002

CheckboxFillLegacy

E003

CheckboxLegacy

E004

CheckboxIndeterminateLegacy

E005

CheckboxCompositeReversedLegacy

E006

HeartLegacy

E007

HeartBrokenLegacy

E008

CheckMarkZeroWidthLegacy

E009

CheckboxFillZeroWidthLegacy

E00A

RatingStarFillZeroWidthLegacy

E00B

HeartFillZeroWidthLegacy

E00C

HeartBrokenZeroWidthLegacy

E00E

ScrollChevronLeftLegacy

E00F

ScrollChevronRightLegacy

E010

ScrollChevronUpLegacy

E011

ScrollChevronDownLegacy

E012

ChevronLeft3Legacy

E013

ChevronRight3Legacy

E014

ChevronUp3Legacy

E015

ChevronDown3Legacy

E016

ScrollChevronLeftBoldLegacy

E017

ScrollChevronRightBoldLegacy

E018

ScrollChevronUpBoldLegacy

E019

ScrollChevronDownBoldLegacy

E052

RevealPasswordLegacy

E07F

EaseOfAccessLegacy

E081

CheckmarkListviewLegacy

E082

RatingStarFillReducedPaddingHTMLLeg acy

E087

KeyboardStandardLegacy

E08F

KeyboardSplitLegacy

E094

SearchboxLegacy

E096

ChevronLeft1Legacy

E097

ChevronRight1Legacy

E098

ChevronUp1Legacy

E099

ChevronDown1Legacy

E09A

ChevronLeft2Legacy

E09B

ChevronRight2Legacy

E09C

ChevronUp2Legacy

E09D

ChevronDown2Legacy

E09E

ChevronLeft4Legacy

E09F

ChevronRight4Legacy

E0A0

ChevronUp4Legacy

E0A1

ChevronDown4Legacy

E0A2

CheckboxCompositeLegacy

E0A5

HeartFillLegacy

E0A6

BackBttnArrow42Legacy

E0AB

BackBttnMirroredArrow42Legacy

E0AD

BackBttnMirroredArrow20Legacy

E0AE

ArrowHTMLLegacyMirrored

E0B4

RatingStarFillLegacy

E0B5

RatingStarFillSmallLegacy

E0B8

SemanticZoomLegacy

E0C4

BackBttnArrow20Legacy

E0D5

ArrowHTMLLegacy

E0E2

ChevronFlipLeftLegacy

E0E3

ChevronFlipRightLegacy

E0E4

ChevronFlipUpLegacy

E0E5

ChevronFlipDownLegacy

E0E7

CheckmarkMenuLegacy

E100

PreviousLegacy

E101

NextLegacy

E102

PlayLegacy

E103

PauseLegacy

E104

EditLegacy

E105

SaveLegacy

E106

ClearLegacy

E107

DeleteLegacy

E108

RemoveLegacy

E109

AddLegacy

E10A

CancelLegacy

E10B

AcceptLegacy

E10C

MoreLegacy

E10D

RedoLegacy

E10E

UndoLegacy

E10F

HomeLegacy

E110

UpLegacy

E111

ForwardLegacy

E112

BackLegacy

E113

FavoriteLegacy

E114

CameraLegacy

E115

SettingsLegacy

E116

VideoLegacy

E117

SyncLegacy

E118

DownloadLegacy

E119

MailLegacy

E11A

FindLegacy

E11B

HelpLegacy

E11C

UploadLegacy

E11D

EmojiLegacy

E11E

TwoPageLegacy

E11F

LeaveChatLegacy

E120

MailForwardLegacy

E121

ClockLegacy

E122

SendLegacy

E123

CropLegacy

E124

RotateCameraLegacy

E125

PeopleLegacy

E126

ClosePaneLegacy

E127

OpenPaneLegacy

E128

WorldLegacy

E129

FlagLegacy

E12A

PreviewLinkLegacy

E12B

GlobeLegacy

E12C

TrimLegacy

E12D

AttachCameraLegacy

E12E

ZoomInLegacy

E12F

BookmarksLegacy

E130

DocumentLegacy

E131

ProtectedDocumentLegacy

E132

PageFillLegacy

E133

MultiSelectLegacy

E134

CommentLegacy

E135

MailFillLegacy

E136

ContactInfoLegacy

E137

HangUpLegacy

E138

ViewAllLegacy

E139

MapPinLegacy

E13A

PhoneLegacy

E13B

VideoChatLegacy

E13C

SwitchLegacy

E13D

ContactLegacy

E13E

RenameLegacy

E13F

ExpandTileLegacy

E140

ReduceTileLegacy

E141

PinLegacy

E142

MusicInfoLegacy

E143

GoLegacy

E144

KeyBoardLegacy

E145

DockLeftLegacy

E146

DockRightLegacy

E147

DockBottomLegacy

E148

RemoteLegacy

E149

RefreshLegacy

E14A

RotateLegacy

E14B

ShuffleLegacy

E14C

ListLegacy

E14D

ShopLegacy

E14E

SelectAllLegacy

E14F

OrientationLegacy

E150

ImportLegacy

E151

ImportAllLegacy

E152

ShowAllFiles3Legacy

E153

ShowAllFiles1Legacy

E154

ShowAllFilesLegacy

E155

BrowsePhotosLegacy

E156

WebcamLegacy

E158

PictureLegacy

E159

SaveLocalLegacy

E15A

CaptionLegacy

E15B

StopLegacy

E15C

ShowResultsLegacy

E15D

VolumeLegacy

E15E

RepairLegacy

E15F

MessageLegacy

E160

PageLegacy

E161

CalendarDayLegacy

E162

CalendarWeekLegacy

E163

CalendarLegacy

E164

CharactersLegacy

E165

MailReplyAllLegacy

E166

ReadLegacy

E167

LinkLegacy

E168

AccountsLegacy

E169

ShowBccLegacy

E16A

HideBccLegacy

E16B

CutLegacy

E16C

AttachLegacy

E16D

PasteLegacy

E16E

FilterLegacy

E16F

CopyLegacy

E170

Emoji2Legacy

E171

ImportantLegacy

E172

MailReplyLegacy

E173

SlideshowLegacy

E174

SortLegacy

E175

ListLegacyMirrored

E176

ExpandTileLegacyMirrored

E177

ReduceTileLegacyMirrored

E178

ManageLegacy

E179

AllAppsLegacy

E17A

DisconnectDriveLegacy

E17B

MapDriveLegacy

E17C

NewWindowLegacy

E17D

OpenWithLegacy

E181

ContactPresenceLegacy

E182

PriorityLegacy

E183

UploadSkyDriveLegacy

E184

GotoTodayLegacy

E185

FontLegacy

E186

FontColorLegacy

E187

Contact2Legacy

E188

FolderLegacy

E189

AudioLegacy

E18A

PlaceFolderLegacy

E18B

ViewLegacy

E18C

SetlockScreenLegacy

E18D

SetTileLegacy

E18E

CCJapanLegacy

E18F

CCEuroLegacy

E190

CCLegacy

E191

StopSlideshowLegacy

E192

PermissionsLegacy

E193

HighlightLegacy

E194

DisableUpdatesLegacy

E195

UnfavoriteLegacy

E196

UnpinLegacy

E197

OpenLocalLegacy

E198

MuteLegacy

E199

ItalicLegacy

E19A

UnderlineLegacy

E19B

BoldLegacy

E19C

MoveToFolderLegacy

E19D

LikeDislikeLegacy

E19E

DislikeLegacy

E19F

LikeLegacy

E1A0

AlignRightLegacy

E1A1

AlignCenterLegacy

E1A2

AlignLeftLegacy

E1A3

ZoomLegacy

E1A4

ZoomOutLegacy

E1A5

OpenFileLegacy

E1A6

OtherUserLegacy

E1A7

AdminLegacy

E1A8

MailForwardLegacyMirrored

E1AA

GoLegacyMirrored

E1AB

DockLeftLegacyMirrored

E1AC

DockRightLegacyMirrored

E1AD

ImportLegacyMirrored

E1AE

ImportAllLegacyMirrored

E1AF

MailReplyLegacyMirrored

E1B0

ItalicCLegacy

E1B1

BoldGLegacy

E1B2

UnderlineSLegacy

E1B3

BoldFLegacy

E1B4

ItalicKLegacy

E1B5

UnderlineULegacy

E1B6

ItalicILegacy

E1B7

BoldNLegacy

E1B8

UnderlineRussianLegacy

E1B9

BoldRussionLegacy

E1BA

FontStyleKoreanLegacy

E1BB

UnderlineLKoreanLegacy

E1BC

ItalicKoreanLegacy

E1BD

BoldKoreanLegacy

E1BE

FontColorKoreanLegacy

E1BF

ClosePaneLegacyMirrored

E1C0

OpenPaneLegacyMirrored

E1C2

EditLegacyMirrored

E1C3

StreetLegacy

E1C4

MapLegacy

E1C5

ClearSelectionLegacy

E1C6

FontDecreaseLegacy

E1C7

FontIncreaseLegacy

E1C8

FontSizeLegacy

E1C9

CellPhoneLegacy

E1CA

ReshareLegacy

E1CB

TagLegacy

E1CC

RepeatOneLegacy

E1CD

RepeatAllLegacy

E1CE

OutlineStarLegacy

E1CF

SolidStarLegacy

E1D0

CalculatorLegacy

E1D1

DirectionsLegacy

E1D2

LocationLegacy

E1D3

LibraryLegacy

E1D4

PhoneBookLegacy

E1D5

MemoLegacy

E1D6

MicrophoneLegacy

E1D7

PostUpdateLegacy

E1D8

BackToWindowLegacy

E1D9

FullScreenLegacy

E1DA

NewFolderLegacy

E1DB

CalendarReplyLegacy

E1DC

CalendarLegacyMirrored

E1DD

UnsyncFolderLegacy

E1DE

ReportHackedLegacy

E1DF

SyncFolderLegacy

E1E0

BlockContactLegacy

E1E1

SwitchAppsLegacy

E1E2

AddFriendLegacy

E1E3

TouchPointerLegacy

E1E4

GoToStartLegacy

E1E5

ZeroBarsLegacy

E1E6

OneBarLegacy

E1E7

TwoBarsLegacy

E1E8

ThreeBarsLegacy

E1E9

FourBarsLegacy

E1EA

ItalicRussianLegacy

E1EC

AllAppsLegacyMirrored

E1ED

OpenWithLegacyMirrored

E1EE

BookmarksLegacyMirrored

E1EF

MultiSelectLegacyMirrored

E1F1

ShowResultsLegacyMirrored

E1F2

MailReplyAllLegacyMirrored

E1F3

HelpLegacyMirrored

E1F4

ClearSelectionLegacyMirrored

E1F5

RecordLegacy

E1F6

LockLegacy

E1F7

UnlockLegacy

E1FD

DownLegacy

E206

CommentInlineLegacy

E208

FavoriteInlineLegacy

E209

LikeInlineLegacy

E20A

VideoInlineLegacy

E20B

MailMessageLegacy

E211

PC1Legacy

E212

DevicesLegacy

E224

RatingStarLegacy

E228

ChevronDownSmLegacy

E248

ReplyLegacy

E249

Favorite2Legacy

E24A

Unfavorite2Legacy

E25A

MobileContactLegacy

E25B

BlockedLegacy

E25C

TypingIndicatorLegacy

E25D

PresenceChickletVideoLegacy

E25E

PresenceChickletLegacy

E26B

ChevronRightSmLegacy

E26C

ChevronLeftSmLegacy

E28F

SaveAsLegacy

E290

DecreaseIndentLegacy

E291

IncreaseIndentLegacy

E292

BulletedListLegacy

E294

ScanLegacy

E295

PreviewLegacy

E297

DecreaseIndentLegacyMirrored

E298

IncreaseIndentLegacyMirrored

E299

BulletedListLegacyMirrored

E29B

PlayOnLegacy

E2AC

ResolutionLegacy

E2AD

LengthLegacy

E2AE

LayoutLegacy

E2AF

Contact3Legacy

E2B0

TypeLegacy

E2B1

ColorLegacy

E2B2

SizeLegacy

E2B3

ReturnToWindowLegacy

E2B4

OpenInNewWindowLegacy

E2F6

PrintLegacy

E2F7

Printer3DLegacy

E700

GlobalNavButton

E701

Wifi

E702

Bluetooth

E703

Connect

E704

InternetSharing

E705

VPN

E706

Brightness

E707

MapPin

E708

QuietHours

E709

Airplane

E70A

Tablet

E70B

QuickNote

E70C

RememberedDevice

E70D

ChevronDown

E70E

ChevronUp

E70F

Edit

E710

Add

E711

Cancel

E712

More

E713

Settings

E714

Video

E715

Mail

E716

People

E717

Phone

E718

Pin

E719

Shop

E71A

Stop

E71B

Link

E71C

Filter

E71D

AllApps

E71E

Zoom

E71F

ZoomOut

E720

Microphone

E721

Search

E722

Camera

E723

Attach

E724

Send

E725

SendFill

E726

WalkSolid

E727

InPrivate

E728

FavoriteList

E729

PageSolid

E72A

Forward

E72B

Back

E72C

Refresh

E72D

Share

E72E

Lock

E730

ReportHacked

E734

FavoriteStar

E735

FavoriteStarFill

E738

Remove

E739

Checkbox

E73A

CheckboxComposite

E73B

CheckboxFill

E73C

CheckboxIndeterminate

E73D

CheckboxCompositeReversed

E73E

CheckMark

E73F

BackToWindow

E740

FullScreen

E741

ResizeTouchLarger

E742

ResizeTouchSmaller

E743

ResizeMouseSmall

E744

ResizeMouseMedium

E745

ResizeMouseWide

E746

ResizeMouseTall

E747

ResizeMouseLarge

E748

SwitchUser

E749

Print

E74A

Up

E74B

Down

E74C

OEM

E74D

Delete

E74E

Save

E74F

Mute

E750

BackSpaceQWERTY

E751

ReturnKey

E752

UpArrowShiftKey

E753

Cloud

E754

Flashlight

E755

RotationLock

E756

CommandPrompt

E759

SIPMove

E75A

SIPUndock

E75B

SIPRedock

E75C

EraseTool

E75D

UnderscoreSpace

E75E

GripperTool

E75F

Dialpad

E760

PageLeft

E761

PageRight

E762

MultiSelect

E763

KeyboardLeftHanded

E764

KeyboardRightHanded

E765

KeyboardClassic

E766

KeyboardSplit

E767

Volume

E768

Play

E769

Pause

E76B

ChevronLeft

E76C

ChevronRight

E76D

InkingTool

E76E

Emoji2

E76F

GripperBarHorizontal

E770

System

E771

Personalize

E772

Devices

E773

SearchAndApps

E774

Globe

E775

TimeLanguage

E776

EaseOfAccess

E777

UpdateRestore

E778

HangUp

E779

ContactInfo

E77A

Unpin

E77B

Contact

E77C

Memo

E77F

Paste

E780

PhoneBook

E781

LEDLight

E783

Error

E784

GripperBarVertical

E785

Unlock

E786

Slideshow

E787

Calendar

E788

GripperResize

E789

Megaphone

E78A

Trim

E78B

NewWindow

E78C

SaveLocal

E790

Color

E791

DataSense

E792

SaveAs

E793

Light

E799

AspectRatio

E7A5

DataSenseBar

E7A6

Redo

E7A7

Undo

E7A8

Crop

E7AC

OpenWith

E7AD

Rotate

E7B5

SetlockScreen

E7B7

MapPin2

E7B8

Package

E7BA

Warning

E7BC

ReadingList

E7BE

Education

E7BF

ShoppingCart

E7C0

Train

E7C1

Flag

E7C3

Page

E7C4

Multitask

E7C5

BrowsePhotos

E7C6

HalfStarLeft

E7C7

HalfStarRight

E7C8

Record

E7C9

TouchPointer

E7DE

LangJPN

E7E3

Ferry

E7E6

Highlight

E7E7

ActionCenterNotification

E7E8

PowerButton

E7EA

ResizeTouchNarrower

E7EB

ResizeTouchShorter

E7EC

DrivingMode

E7ED

RingerSilent

E7EE

OtherUser

E7EF

Admin

E7F0

CC

E7F1

SDCard

E7F2

CallForwarding

E7F3

SettingsDisplaySound

E7F4

TVMonitor

E7F5

Speakers

E7F6

Headphone

E7F7

DeviceLaptopPic

E7F8

DeviceLaptopNoPic

E7F9

DeviceMonitorRightPic

E7FA

DeviceMonitorLeftPic

E7FB

DeviceMonitorNoPic

E7FC

Game

E7FD

HorizontalTabKey

E802

StreetsideSplitMinimize

E803

StreetsideSplitExpand

E804

Car

E805

Walk

E806

Bus

E809

TiltUp

E80A

TiltDown

E80C

RotateMapRight

E80D

RotateMapLeft

E80F

Home

E811

ParkingLocation

E812

MapCompassTop

E813

MapCompassBottom

E814

IncidentTriangle

E815

Touch

E816

MapDirections

E819

StartPoint

E81A

StopPoint

E81B

EndPoint

E81C

History

E81D

Location

E81E

MapLayers

E81F

Accident

E821

Work

E822

Construction

E823

Recent

E825

Bank

E826

DownloadMap

E829

InkingToolFill2

E82A

HighlightFill2

E82B

EraseToolFill

E82C

EraseToolFill2

E82D

Dictionary

E82E

DictionaryAdd

E82F

ToolTip

E830

ChromeBack

E835

ProvisioningPackage

E836

AddRemoteDevice

E839

Ethernet

E83A

ShareBroadband

E83B

DirectAccess

E83C

DialUp

E83D

DefenderApp

E83E

BatteryCharging9

E83F

Battery10

E840

Pinned

E841

PinFill

E842

PinnedFill

E843

PeriodKey

E844

PuncKey

E845

RevToggleKey

E846

RightArrowKeyTime1

E847

RightArrowKeyTime2

E848

LeftQuote

E849

RightQuote

E84A

DownShiftKey

E84B

UpShiftKey

E84C

PuncKey0

E84D

PuncKeyLeftBottom

E84E

RightArrowKeyTime3

E84F

RightArrowKeyTime4

E850

Battery0

E851

Battery1

E852

Battery2

E853

Battery3

E854

Battery4

E855

Battery5

E856

Battery6

E857

Battery7

E858

Battery8

E859

Battery9

E85A

BatteryCharging0

E85B

BatteryCharging1

E85C

BatteryCharging2

E85D

BatteryCharging3

E85E

BatteryCharging4

E85F

BatteryCharging5

E860

BatteryCharging6

E861

BatteryCharging7

E862

BatteryCharging8

E863

BatterySaver0

E864

BatterySaver1

E865

BatterySaver2

E866

BatterySaver3

E867

BatterySaver4

E868

BatterySaver5

E869

BatterySaver6

E86A

BatterySaver7

E86B

BatterySaver8

E86C

SignalBars1

E86D

SignalBars2

E86E

SignalBars3

E86F

SignalBars4

E870

SignalBars5

E871

SignalNotConnected

E872

Wifi1

E873

Wifi2

E874

Wifi3

E875

SIMLock

E876

SIMMissing

E877

Vibrate

E878

RoamingInternational

E879

RoamingDomestic

E87A

CallForwardInternational

E87B

CallForwardRoaming

E87C

JpnRomanji

E87D

JpnRomanjiLock

E87E

JpnRomanjiShift

E87F

JpnRomanjiShiftLock

E880

StatusDataTransfer

E881

StatusDataTransferVPN

E882

StatusDualSIM2

E883

StatusDualSIM2VPN

E884

StatusDualSIM1

E885

StatusDualSIM1VPN

E886

StatusSGLTE

E887

StatusSGLTECell

E888

StatusSGLTEDataVPN

E889

StatusVPN

E88A

WifiHotspot

E88B

LanguageKor

E88C

LanguageCht

E88D

LanguageChs

E88E

USB

E88F

InkingToolFill

E890

View

E891

HighlightFill

E892

Previous

E893

Next

E894

Clear

E895

Sync

E896

Download

E897

Help

E898

Upload

E899

Emoji

E89A

TwoPage

E89B

LeaveChat

E89C

MailForward

E89E

RotateCamera

E89F

ClosePane

E8A0

OpenPane

E8A1

PreviewLink

E8A2

AttachCamera

E8A3

ZoomIn

E8A4

Bookmarks

E8A5

Document

E8A6

ProtectedDocument

E8A7

OpenInNewWindow

E8A8

MailFill

E8A9

ViewAll

E8AA

VideoChat

E8AB

Switch

E8AC

Rename

E8AD

Go

E8AE

SurfaceHub

E8AF

Remote

E8B0

Click

E8B1

Shuffle

E8B2

Movies

E8B3

SelectAll

E8B4

Orientation

E8B5

Import

E8B6

ImportAll

E8B7

Folder

E8B8

Webcam

E8B9

Picture

E8BA

Caption

E8BB

ChromeClose

E8BC

ShowResults

E8BD

Message

E8BE

Leaf

E8BF

CalendarDay

E8C0

CalendarWeek

E8C1

Characters

E8C2

MailReplyAll

E8C3

Read

E8C4

ShowBcc

E8C5

HideBcc

E8C6

Cut

E8C8

Copy

E8C9

Important

E8CA

MailReply

E8CB

Sort

E8CC

MobileTablet

E8CD

DisconnectDrive

E8CE

MapDrive

E8CF

ContactPresence

E8D0

Priority

E8D1

GotoToday

E8D2

Font

E8D3

FontColor

E8D4

Contact2

E8D5

FolderFill

E8D6

Audio

E8D7

Permissions

E8D8

DisableUpdates

E8D9

Unfavorite

E8DA

OpenLocal

E8DB

Italic

E8DC

Underline

E8DD

Bold

E8DE

MoveToFolder

E8DF

LikeDislike

E8E0

Dislike

E8E1

Like

E8E2

AlignRight

E8E3

AlignCenter

E8E4

AlignLeft

E8E5

OpenFile

E8E6

ClearSelection

E8E7

FontDecrease

E8E8

FontIncrease

E8E9

FontSize

E8EA

CellPhone

E8EB

Reshare

E8EC

Tag

E8ED

RepeatOne

E8EE

RepeatAll

E8EF

Calculator

E8F0

Directions

E8F1

Library

E8F2

ChatBubbles

E8F3

PostUpdate

E8F4

NewFolder

E8F5

CalendarReply

E8F6

UnsyncFolder

E8F7

SyncFolder

E8F8

BlockContact

E8F9

SwitchApps

E8FA

AddFriend

E8FB

Accept

E8FC

GoToStart

E8FD

BulletedList

E8FE

Scan

E8FF

Preview

E904

ZeroBars

E905

OneBar

E906

TwoBars

E907

ThreeBars

E908

FourBars

E909

World

E90A

Comment

E90B

MusicInfo

E90C

DockLeft

E90D

DockRight

E90E

DockBottom

E90F

Repair

E910

Accounts

E911

DullSound

E912

Manage

E913

Street

E914

Printer3D

E915

RadioBullet

E916

Stopwatch

E91B

Photo

E91C

ActionCenter

E91F

FullCircleMask

E921

ChromeMinimize

E922

ChromeMaximize

E923

ChromeRestore

E924

Annotation

E925

BackSpaceQWERTYSm

E926

BackSpaceQWERTYMd

E927

Swipe

E928

Fingerprint

E929

Handwriting

E92C

ChromeBackToWindow

E92D

ChromeFullScreen

E92E

KeyboardStandard

E92F

KeyboardDismiss

E930

Completed

E931

ChromeAnnotate

E932

Label

E933

IBeam

E934

IBeamOutline

E935

FlickDown

E936

FlickUp

E937

FlickLeft

E938

FlickRight

E939

FeedbackApp

E93C

MusicAlbum

E93E

Streaming

E943

Code

E944

ReturnToWindow

E945

LightningBolt

E946

Info

E947

CalculatorMultiply

E948

CalculatorAddition

E949

CalculatorSubtract

E94A

CalculatorDivide

E94B

CalculatorSquareroot

E94C

CalculatorPercentage

E94D

CalculatorNegate

E94E

CalculatorEqualTo

E94F

CalculatorBackspace

E950

Component

E951

DMC

E952

Dock

E953

MultimediaDMS

E954

MultimediaDVR

E955

MultimediaPMP

E956

PrintfaxPrinterFile

E957

Sensor

E958

StorageOptical

E95A

Communications

E95B

Headset

E95D

Projector

E95E

Health

E960

Webcam2

E961

Input

E962

Mouse

E963

Smartcard

E964

SmartcardVirtual

E965

MediaStorageTower

E966

ReturnKeySm

E967

GameConsole

E968

Network

E969

StorageNetworkWireless

E96A

StorageTape

E96D

ChevronUpSmall

E96E

ChevronDownSmall

E96F

ChevronLeftSmall

E970

ChevronRightSmall

E971

ChevronUpMed

E972

ChevronDownMed

E973

ChevronLeftMed

E974

ChevronRightMed

E975

Devices2

E976

ExpandTile

E977

PC1

E978

PresenceChicklet

E979

PresenceChickletVideo

E97A

Reply

E97B

SetTile

E97C

Type

E97D

Korean

E97E

HalfAlpha

E97F

FullAlpha

E980

Key12On

E981

ChineseChangjie

E982

QWERTYOn

E983

QWERTYOff

E984

ChineseQuick

E985

Japanese

E986

FullHiragana

E987

FullKatakana

E988

HalfKatakana

E989

ChineseBoPoMoFo

E98A

ChinesePinyin

E98F

ConstructionCone

E990

XboxOneConsole

E992

Volume0

E993

Volume1

E994

Volume2

E995

Volume3

E996

BatteryUnknown

E998

WifiAttentionOverlay

E99A

Robot

E9A1

TapAndSend

E9A8

PasswordKeyShow

E9A9

PasswordKeyHide

E9AA

BidiLtr

E9AB

BidiRtl

E9AC

ForwardSm

E9AD

CommaKey

E9AE

DashKey

E9AF

DullSoundKey

E9B0

HalfDullSound

E9B1

RightDoubleQuote

E9B2

LeftDoubleQuote

E9B3

PuncKeyRightBottom

E9B4

PuncKey1

E9B5

PuncKey2

E9B6

PuncKey3

E9B7

PuncKey4

E9B8

PuncKey5

E9B9

PuncKey6

E9BA

PuncKey9

E9BB

PuncKey7

E9BC

PuncKey8

E9CA

Frigid

E9D9

Diagnostic

E9F3

Process

EA14

DisconnectDisplay

EA1F

Info2

EA21

ActionCenterAsterisk

EA24

Beta

EA35

SaveCopy

EA37

List

EA38

Asterisk

EA39

ErrorBadge

EA3A

CircleRing

EA3B

CircleFill

EA40

AllAppsMirrored

EA41

BookmarksMirrored

EA42

BulletedListMirrored

EA43

CallForwardInternationalMirrored

EA44

CallForwardRoamingMirrored

EA47

ChromeBackMirrored

EA48

ClearSelectionMirrored

EA49

ClosePaneMirrored

EA4A

ContactInfoMirrored

EA4B

DockRightMirrored

EA4C

DockLeftMirrored

EA4E

ExpandTileMirrored

EA4F

GoMirrored

EA50

GripperResizeMirrored

EA51

HelpMirrored

EA52

ImportMirrored

EA53

ImportAllMirrored

EA54

LeaveChatMirrored

EA55

ListMirrored

EA56

MailForwardMirrored

EA57

MailReplyMirrored

EA58

MailReplyAllMirrored

EA5B

OpenPaneMirrored

EA5C

OpenWithMirrored

EA5E

ParkingLocationMirrored

EA5F

ResizeMouseMediumMirrored

EA60

ResizeMouseSmallMirrored

EA61

ResizeMouseTallMirrored

EA62

ResizeTouchNarrowerMirrored

EA63

SendMirrored

EA64

SendFillMirrored

EA65

ShowResultsMirrored

EA69

Media

EA6A

SyncError

EA6C

Devices3

EA80

Lightbulb

EA81

StatusCircle

EA82

StatusTriangle

EA83

StatusError

EA84

StatusWarning

EA86

Puzzle

EA89

CalendarSolid

EA8A

HomeSolid

EA8B

ParkingLocationSolid

EA8C

ContactSolid

EA8D

ConstructionSolid

EA8E

AccidentSolid

EA8F

Ringer

EA91

ThoughtBubble

EA92

HeartBroken

EA93

BatteryCharging10

EA94

BatterySaver9

EA95

BatterySaver10

EA97

CallForwardingMirrored

EA98

MultiSelectMirrored

EA99

Broom

EADF

Trackers

EB05

PieSingle

EB0F

StockDown

EB11

StockUp

EB42

Drop

EB47

BusSolid

EB48

FerrySolid

EB49

StartPointSolid

EB4A

StopPointSolid

EB4B

EndPointSolid

EB4C

AirplaneSolid

EB4D

TrainSolid

EB4E

WorkSolid

EB4F

ReminderFill

EB50

Reminder

EB51

Heart

EB52

HeartFill

EB55

EthernetError

EB56

EthernetWarning

EB57

StatusConnecting1

EB58

StatusConnecting2

EB59

StatusUnsecure

EB5A

WifiError0

EB5B

WifiError1

EB5C

WifiError2

EB5D

WifiError3

EB5E

WifiError4

EB5F

WifiWarning0

EB60

WifiWarning1

EB61

WifiWarning2

EB62

WifiWarning3

EB63

WifiWarning4

EB66

Devices4

EB67

NUIIris

EB68

NUIFace

EB7E

EditMirrored

EB82

NUIFPStartSlideHand

EB83

NUIFPStartSlideAction

EB84

NUIFPContinueSlideHand

EB85

NUIFPContinueSlideAction

EB86

NUIFPRollRightHand

EB87

NUIFPRollRightHandAction

EB88

NUIFPRollLeftHand

EB89

NUIFPRollLeftAction

EB8A

NUIFPPressHand

EB8B

NUIFPPressAction

EB8C

NUIFPPressRepeatHand

EB8D

NUIFPPressRepeatAction

EB90

StatusErrorFull

EB91

MultitaskExpanded

EB95

Certificate

EB96

BackSpaceQWERTYLg

EB97

ReturnKeyLg

EB9D

FastForward

EB9E

Rewind

EB9F

Photo2

EBA0

MobBattery0

EBA1

MobBattery1

EBA2

MobBattery2

EBA3

MobBattery3

EBA4

MobBattery4

EBA5

MobBattery5

EBA6

MobBattery6

EBA7

MobBattery7

EBA8

MobBattery8

EBA9

MobBattery9

EBAA

MobBattery10

EBAB

MobBatteryCharging0

EBAC

MobBatteryCharging1

EBAD

MobBatteryCharging2

EBAE

MobBatteryCharging3

EBAF

MobBatteryCharging4

EBB0

MobBatteryCharging5

EBB1

MobBatteryCharging6

EBB2

MobBatteryCharging7

EBB3

MobBatteryCharging8

EBB4

MobBatteryCharging9

EBB5

MobBatteryCharging10

EBB6

MobBatterySaver0

EBB7

MobBatterySaver1

EBB8

MobBatterySaver2

EBB9

MobBatterySaver3

EBBA

MobBatterySaver4

EBBB

MobBatterySaver5

EBBC

MobBatterySaver6

EBBD

MobBatterySaver7

EBBE

MobBatterySaver8

EBBF

MobBatterySaver9

EBC0

MobBatterySaver10

EBC3

DictionaryCloud

EBC4

ResetDrive

EBC5

VolumeBars

EBC6

Project

EBD2

AdjustHologram

EBD4

WifiCallBars

EBD5

WifiCall0

EBD6

WifiCall1

EBD7

WifiCall2

EBD8

WifiCall3

EBD9

WifiCall4

EBDE

DeviceDiscovery

EBE6

WindDirection

EBE7

RightArrowKeyTime0

EBFC

TabletMode

EBFD

StatusCircleLeft

EBFE

StatusTriangleLeft

EBFF

StatusErrorLeft

EC00

StatusWarningLeft

EC02

MobBatteryUnknown

EC05

NetworkTower

EC06

CityNext

EC07

CityNext2

EC08

Courthouse

EC09

Groceries

EC0A

Sustainable

EC0B

BuildingEnergy

EC11

ToggleFilled

EC12

ToggleBorder

EC13

SliderThumb

EC14

ToggleThumb

EC15

MiracastLogoSmall

EC16

MiracastLogoLarge

EC19

PLAP

EC1B

Badge

EC1E

SignalRoaming

EC20

MobileLocked

EC24

InsiderHubApp

EC25

PersonalFolder

EC26

HomeGroup

EC27

MyNetwork

EC31

KeyboardFull

EC37

MobSignal1

EC38

MobSignal2

EC39

MobSignal3

EC3A

MobSignal4

EC3B

MobSignal5

EC3C

MobWifi1

EC3D

MobWifi2

EC3E

MobWifi3

EC3F

MobWifi4

EC40

MobAirplane

EC41

MobBluetooth

EC42

MobActionCenter

EC43

MobLocation

EC44

MobWifiHotspot

EC45

LanguageJpn

EC46

MobQuietHours

EC47

MobDrivingMode

EC48

SpeedOff

EC49

SpeedMedium

EC4A

SpeedHigh

EC4E

ThisPC

EC4F

MusicNote

EC50

FileExplorer

EC51

FileExplorerApp

EC52

LeftArrowKeyTime0

EC54

MicOff

EC55

MicSleep

EC56

MicError

EC57

PlaybackRate1x

EC58

PlaybackRateOther

EC59

CashDrawer

EC5A

BarcodeScanner

EC5B

ReceiptPrinter

EC5C

MagStripeReader

EC61

CompletedSolid

EC64

CompanionApp

EC6D

SwipeRevealArt

EC71

MicOn

EC72

MicClipping

EC74

TabletSelected

EC75

MobileSelected

EC76

LaptopSelected

EC77

TVMonitorSelected

EC7A

DeveloperTools

EC7E

MobCallForwarding

EC7F

MobCallForwardingMirrored

EC80

BodyCam

EC81

PoliceCar

EC87

Draw

EC88

DrawSolid

EC8A

LowerBrightness

EC8F

ScrollUpDown

EC92

DateTime

ECA5

Tiles

ECA7

PartyLeader

ECAA

AppIconDefault

ECC4

AddSurfaceHub

ECC5

DevUpdate

ECC6

Unit

ECC8

AddTo

ECC9

RemoveFrom

ECCA

RadioBtnOff

ECCB

RadioBtnOn

ECCC

RadioBullet2

ECCD

ExploreContent

ECE7

ScrollMode

ECE8

ZoomMode

ECE9

PanMode

ECF0

WiredUSB

ECF1

WirelessUSB

ECF3

USBSafeConnect

ED0C

ActionCenterNotificationMirrored

ED0D

ActionCenterMirrored

ED10

ResetDevice

ED15

Feedback

ED1E

Subtitles

ED1F

SubtitlesAudio

ED28

CalendarMirrored

ED2A

eSIM

ED2B

eSIMNoProfile

ED2C

eSIMLocked

ED2D

eSIMBusy

ED2E

SignalError

ED2F

StreamingEnterprise

ED30

Headphone0

ED31

Headphone1

ED32

Headphone2

ED33

Headphone3

ED39

KeyboardBrightness

ED3A

KeyboardLowerBrightness

ED3C

SkipBack10

ED3D

SkipForward30

ED41

TreeFolderFolder

ED42

TreeFolderFolderFill

ED43

TreeFolderFolderOpen

ED44

TreeFolderFolderOpenFill

ED47

MultimediaDMP

ED4C

KeyboardOneHanded

ED4D

Narrator

ED53

EmojiTabPeople

ED54

EmojiTabSmilesAnimals

ED55

EmojiTabCelebrationObjects

ED56

EmojiTabFoodPlants

ED57

EmojiTabTransitPlaces

ED58

EmojiTabSymbols

ED59

EmojiTabTextSmiles

ED5A

EmojiTabFavorites

ED5B

EmojiSwatch

ED5C

ConnectApp

ED5D

CompanionDeviceFramework

ED5E

Ruler

ED5F

FingerInking

ED60

StrokeErase

ED61

PointErase

ED62

ClearAllInk

ED63

Pencil

ED64

Marker

ED65

InkingCaret

ED66

InkingColorOutline

ED67

InkingColorFill

EDA2

HardDrive

EDA3

NetworkAdapter

EDA4

Touchscreen

EDA5

NetworkPrinter

EDA6

CloudPrinter

EDA7

KeyboardShortcut

EDA8

BrushSize

EDA9

NarratorForward

EDAA

NarratorForwardMirrored

EDAB

SyncBadge12

EDAC

RingerBadge12

EDAD

AsteriskBadge12

EDAE

ErrorBadge12

EDAF

CircleRingBadge12

EDB0

CircleFillBadge12

EDB1

ImportantBadge12

EDB3

MailBadge12

EDB4

PauseBadge12

EDB5

PlayBadge12

EDC6

PenWorkspace

EDE1

Export

EDE2

ExportMirrored

EDFB

CaligraphyPen

EE35

ReplyMirrored

EE3F

LockscreenDesktop

EE40

Multitask16

EE4A

Play36

EE56

PenPalette

EE57

GuestUser

EE63

SettingsBattery

EE64

TaskbarPhone

Related articles Guidelines for fonts Symbol enumeration

EE65

LockScreenGlance

EE71

ImageExport

EE77

WifiEthernet

EE79

ActionCenterQuiet

EE7A

ActionCenterQuietNotification

EE92

TrackersMirrored

EE93

DateTimeMirrored

EE94

Wheel

EF15

PenWorkspaceMirrored

EF16

PenPaletteMirrored

EF17

StrokeEraseMirrored

EF18

PointEraseMirrored

EF19

ClearAllInkMirrored

EF1F

BackgroundToggle

EF20

Marquee

Styling controls 3/6/2017 • 5 min to read • Edit on GitHub

You can customize the appearance of your apps in many ways by using the XAML framework. Styles let you set control properties and reuse those settings for a consistent appearance across multiple controls.

Style basics Use styles to extract visual property settings into reusable resources. Here's an example that shows 3 buttons with a style that sets the BorderBrush, BorderThickness and Foreground properties. By applying a style, you can make the controls appear the same without having to set these properties on each control separately.

You can define a style inline in the XAML for a control, or as a reusable resource. Define resources in an individual page's XAML file, in the App.xaml file, or in a separate resource dictionary XAML file. A resource dictionary XAML file can be shared across apps, and more than one resource dictionary can be merged in a single app. Where the resource is defined determines the scope in which it can be used. Page-level resources are available only in the page where they are defined. If resources with the same key are defined in both App.xaml and in a page, the resource in the page overrides the resource in App.xaml. If a resource is defined in a separate resource dictionary file, it's scope is determined by where the resource dictionary is referenced. In the Style definition, you need a TargetType attribute and a collection of one or more Setter elements. The TargetType attribute is a string that specifies a FrameworkElement type to apply the style to. The TargetType value must specify a FrameworkElement-derived type that's defined by the Windows Runtime or a custom type that's available in a referenced assembly. If you try to apply a style to a control and the control's type doesn't match the TargetType attribute of the style you're trying to apply, an exception occurs. Each Setter element requires a Property and a Value. These property settings indicate what control property the setting applies to, and the value to set for that property. You can set the Setter.Value with either attribute or property element syntax. The XAML here shows the style applied to the buttons shown previously. In this XAML, the first two Setter elements use attribute syntax, but the last Setter, for the BorderBrush property, uses property element syntax. The example doesn't use the x:Key attribute attribute, so the style is implicitly applied to the buttons. Applying styles implicitly or explicitly is explained in the next section.



Apply an implicit or explicit style If you define a style as a resource, there are two ways to apply it to your controls: Implicitly, by specifying only a TargetType for the Style. Explicitly, by specifying a TargetType and an x:Key attribute attribute for the Style and then by setting the target control's Style property with a {StaticResource} markup extension reference that uses the explicit key. If a style contains the x:Key attribute, you can only apply it to a control by setting the Style property of the control to the keyed style. In contrast, a style without an x:Key attribute is automatically applied to every control of its target type, that doesn't otherwise have an explicit style setting. Here are two buttons that demonstrate implicit and explicit styles.

In this example, the first style has an x:Key attribute and its target type is Button. The first button's Style property is set to this key, so this style is applied explicitly. The second style is applied implicitly to the second button because its target type is Button and the style doesn't have an x:Key attribute.



Use based-on styles To make styles easier to maintain and to optimize style reuse, you can create styles that inherit from other styles. You use the BasedOn property to create inherited styles. Styles that inherit from other styles must target the same type of control or a control that derives from the type targeted by the base style. For example, if a base style targets ContentControl, styles that are based on this style can target ContentControl or types that derive from ContentControl such as Button and ScrollViewer. If a value is not set in the based-on style, it's inherited from the base style. To change a value from the base style, the based-on style overrides that value. The next example shows a Button and a CheckBox with styles that inherit from the same base style.

The base style targets ContentControl, and sets the Height, and Width properties. The styles based on this style target CheckBox and Button, which derive from ContentControl. The based-on styles set different colors for the BorderBrush and Foreground properties. (You don't typically put a border around a CheckBox. We do it here to show the effects of the style.)



Use tools to work with styles easily A fast way to apply styles to your controls is to right-click on a control on the Microsoft Visual Studio XAML design surface and select Edit Style or Edit Template (depending on the control you are right-clicking on). You can then apply an existing style by selecting Apply Resource or define a new style by selecting Create Empty. If you create an empty style, you are given the option to define it in the page, in the App.xaml file, or in a separate resource dictionary.

Modify the default system styles You should use the styles that come from the Windows Runtime default XAML resources when you can. When you have to define your own styles, try to base your styles on the default ones when possible (using based-on styles as explained earlier, or start by editing a copy of the original default style).

The Template property A style setter can be used for the Template property of a Control, and in fact this makes up the majority of a typical XAML style and an app's XAML resources. This is discussed in more detail in the topic Control templates.

Control templates 3/6/2017 • 7 min to read • Edit on GitHub

You can customize a control's visual structure and visual behavior by creating a control template in the XAML framework. Controls have many properties, such as Background, Foreground, and FontFamily, that you can set to specify different aspects of the control's appearance. But the changes that you can make by setting these properties are limited. You can specify additional customizations by creating a template using the ControlTemplate class. Here, we show you how to create a ControlTemplate to customize the appearance of a CheckBox control. Important APIs ControlTemplate class Control.Template property

Custom control template example By default, a CheckBox control puts its content (the string or object next to the CheckBox) to the right of the selection box, and a check mark indicates that a user selected the CheckBox. These characteristics represent the visual structure and visual behavior of the CheckBox. Here's a CheckBox using the default ControlTemplate shown in the

Unchecked

,

Checked

, and

Indeterminate

states.

You can change these characteristics by creating a ControlTemplate for the CheckBox. For example, if you want the content of the check box to be below the selection box, and you want to use an X to indicate that a user selected the check box. You specify these characteristics in the ControlTemplate of the CheckBox. To use a custom template with a control, assign the ControlTemplate to the Template property of the control. Here's a CheckBox using a ControlTemplate called CheckBoxTemplate1 . We show the Extensible Application Markup Language (XAML) for the ControlTemplate in the next section.

Here's how this CheckBox looks in the

Unchecked

,

Checked

, and

Indeterminate

states after we apply our template.

Specify the visual structure of a control When you create a ControlTemplate, you combine FrameworkElement objects to build a single control. A ControlTemplate must have only one FrameworkElement as its root element. The root element usually contains other FrameworkElement objects. The combination of objects makes up the control's visual structure. This XAML creates a ControlTemplate for a CheckBox that specifies that the content of the control is below the

selection box. The root element is a Border. The example specifies a Path to create an X that indicates that a user selected the CheckBox, and an Ellipse that indicates an indeterminate state. Note that the Opacity is set to 0 on the Path and the Ellipse so that by default, neither appear.

Specify the visual behavior of a control A visual behavior specifies the appearance of a control when it is in a certain state. The CheckBox control has 3 check states: Checked , Unchecked , and Indeterminate . The value of the IsChecked property determines the state of the CheckBox, and its state determines what appears in the box. This table lists the possible values of IsChecked, the corresponding states of the CheckBox, and the appearance of the CheckBox.

IsChecked value

CheckBox state

CheckBox appearance

true

Checked

Contains an "X".

false

Unchecked

Empty.

null

Indeterminate

Contains a circle.

You specify the appearance of a control when it is in a certain state by using VisualState objects. A VisualState contains a Setter or Storyboard that changes the appearance of the elements in the ControlTemplate. When the control enters the state that the VisualState.Name property specifies, the property changes in the Setter or Storyboard are applied. When the control exits the state, the changes are removed. You add VisualState objects to VisualStateGroup objects. You add VisualStateGroup objects to the

VisualStateManager.VisualStateGroups attached property, which you set on the root FrameworkElement of the ControlTemplate. This XAML shows the VisualState objects for the Checked , Unchecked , and Indeterminate states. The example sets the VisualStateManager.VisualStateGroups attached property on the Border, which is the root element of the ControlTemplate. The Checked VisualState specifies that the Opacity of the Path named CheckGlyph (which we show in the previous example) is 1. The Indeterminate VisualState specifies that the Opacity of the Ellipse named IndeterminateGlyph is 1. The Unchecked VisualState has no Setter or Storyboard, so the CheckBox returns to its default appearance.



To better understand how VisualState objects work, consider what happens when the CheckBox goes from the Unchecked state to the Checked state, then to the Indeterminate state, and then back to the Unchecked state. Here are the transitions.

State transition

From

Unchecked

From

Checked

From

Indeterminate

to

to

Checked

.

Indeterminate

to

.

Unchecked

.

What happens

CheckBox appearance when the transition completes

The Setter value of the Checked VisualState is applied, so the Opacity of CheckGlyph is 1.

An X is displayed.

The Setter value of the Indeterminate VisualState is applied, so the Opacity of IndeterminateGlyph is 1. The Setter value of the Checked VisualState is removed, so the Opacity of CheckGlyph is 0.

A circle is displayed.

The Setter value of the Indeterminate VisualState is removed, so the Opacity of IndeterminateGlyph is 0.

Nothing is displayed.

For more info about how to create visual states for controls, and in particular how to use the Storyboard class and the animation types, see Storyboarded animations for visual states.

Use tools to work with themes easily A fast way to apply themes to your controls is to right-click on a control on the Microsoft Visual Studio Document Outline and select Edit Theme or Edit Style (depending on the control you are right-clicking on). You can then apply an existing theme by selecting Apply Resource or define a new one by selecting Create Empty.

Controls and accessibility When you create a new template for a control, in addition to possibly changing the control's behavior and visual appearance, you might also be changing how the control represents itself to accessibility frameworks. The Universal Windows Platform (UWP) supports the Microsoft UI Automation framework for accessibility. All of the default controls and their templates have support for common UI Automation control types and patterns that are appropriate for the control's purpose and function. These control types and patterns are interpreted by UI Automation clients such as assistive technologies, and this enables a control to be accessible as a part of a larger accessible app UI. To separate the basic control logic and also to satisfy some of the architectural requirements of UI Automation, control classes include their accessibility support in a separate class, an automation peer. The automation peers sometimes have interactions with the control templates because the peers expect certain named parts to exist in the templates, so that functionality such as enabling assistive technologies to invoke actions of buttons is possible. When you create a completely new custom control, you sometimes also will want to create a new automation peer to go along with it. For more info, see Custom automation peers.

Learn more about a control's default template The topics that document the styles and templates for XAML controls show you excerpts of the same starting XAML you'd see if you used the Edit Theme or Edit Style techniques explained previously. Each topic lists the names of the visual states, the theme resources used, and the full XAML for the style that contains the template. The topics can be useful guidance if you've already started modifying a template and want to see what the original template looked like, or to verify that your new template has all of the required named visual states.

Theme resources in control templates For some of the attributes in the XAML examples, you may have noticed resource references that use the {ThemeResource} markup extension. This is a technique that enables a single control template to use resources that can be different values depending on which theme is currently active. This is particularly important for brushes and colors, because the main purpose of the themes is to enable users to choose whether they want a dark, light, or high contrast theme applied to the system overall. Apps that use the XAML resource system can use a resource set that's appropriate for that theme, so that the theme choices in an app's UI are reflective of the user's systemwide theme choice.

Get the sample code XAML UI basics sample Custom text edit control sample

ResourceDictionary and XAML resource references 3/6/2017 • 21 min to read • Edit on GitHub

You can define the UI or resources for your app using XAML. Resources are typically definitions of some object that you expect to use more than once. To refer to a XAML resource later, you specify a key for a resource that acts like its name. You can reference a resource throughout an app or from any XAML page within it. You can define your resources using a ResourceDictionary element from the Windows Runtime XAML. Then, you can reference your resources by using a StaticResource markup extension or ThemeResource markup extension. The XAML elements you might want to declare most often as XAML resources include Style, ControlTemplate, animation components, and Brush subclasses. Here, we explain how to define a ResourceDictionary and keyed resources, and how XAML resources relate to other resources that you define as part of your app or app package. We also explain resource dictionary advanced features such as MergedDictionaries and ThemeDictionaries. Prerequisites We assume that you understand XAML markup and have read the XAML overview.

Define and use XAML resources XAML resources are objects that are referenced from markup more than once. Resources are defined in a ResourceDictionary, typically in a separate file or at the top of the markup page, like this. Hello world Goodbye world

In this example: - Defines the resource dictionary. - Defines the resource with the key "greeting". {StaticResource greeting} - Looks up the resource with the key "greeting", which is assigned to the Text property of the TextBlock. …

Note Don't confuse the concepts related to ResourceDictionary with the Resource build action, resource (.resw) files, or other "resources" that are discussed in the context of structuring the code project that produces your app package. Resources don't have to be strings; they can be any shareable object, such as styles, templates, brushes, and colors. However, controls, shapes, and other FrameworkElements are not shareable, so they can't be declared as reusable resources. For more info about sharing, see the XAML resources must be shareable section later in this topic. Here, both a brush and a string are declared as resources and used by controls in a page.

Hello world

All resources need to have a key. Usually that key is a string defined with other ways to specify a key:

x:Key=”myString”

. However, there are a few

Style and ControlTemplate require a TargetType, and will use the TargetType as the key if x:Key is not specified. In this case, the key is the actual Type object, not a string. (See examples below) DataTemplate resources that have a TargetType will use the TargetType as the key if x:Key is not specified. In this case, the key is the actual Type object, not a string. x:Name can be used instead of x:Key. However, x:Name also generates a code behind field for the resource. As a result, x:Name is less efficient than x:Key because that field needs to be initialized when the page is loaded. The StaticResource markup extension can retrieve resources only with a string name (x:Key or x:Name). However, the XAML framework also looks for implicit style resources (those which use TargetType rather than x:Key or x:Name) when it decides which style & template to use for a control that hasn't set the Style and ContentTemplate or ItemTemplate properties. Here, the Style has an implicit key of typeof(Button), and since the Button at the bottom of the page doesn't specify a Style property, it looks for a style with key of typeof(Button):

For more info about implicit styles and how they work, see Styling controls and Control templates.

Look up resources in code You access members of the resource dictionary like any other dictionary. Caution When you perform a resource lookup in code, only the resources in the Page.Resources dictionary are looked at. Unlike the StaticResource markup extension, the code doesn't fall back to the Application.Resources dictionary if the resources aren’t found in the first dictionary. This example shows how to retrieve the

redButtonStyle

resource out of a page’s resource dictionary:



public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); Style redButtonStyle = (Style)this.Resources["redButtonStyle"]; } }

To look up app-wide resources from code, use Application.Current.Resources to get the app's resource dictionary, as shown here.

public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); Style appButtonStyle = (Style)Application.Current.Resources["appButtonStyle"]; } }

You can also add an application resource in code. There are two things to keep in mind when doing this. First, you need to add the resources before any page tries to use the resource. Second, you can’t add resources in the App’s constructor. You can avoid both problems if you add the resource in the Application.OnLaunched method, like this.

// App.xaml.cs sealed partial class App : Application { protected override void OnLaunched(LaunchActivatedEventArgs e) { Frame rootFrame = Window.Current.Content as Frame; if (rootFrame == null) { SolidColorBrush brush = new SolidColorBrush(Windows.UI.Color.FromArgb(255, 0, 255, 0)); // green this.Resources["brush"] = brush; // … Other code that VS generates for you … } } }

Every FrameworkElement can have a ResourceDictionary FrameworkElement is a base class that controls inherit from, and it has a Resources property. So, you can add a local resource dictionary to any FrameworkElement. Here, a resource dictionary is added to a page element. Hello world Hola mundo

Here, both the Page and the Border have resource dictionaries, and they both have a resource called "greeting". The TextBlock is inside the Border, so its resource lookup looks first to the Border’s resources, then the Page’s resources, and then the Application resources. The TextBlock will read "Hola mundo". To access that element’s resources from code, use that element’s Resources property. Accessing a FrameworkElement’s resources in code, rather than XAML, will look only in that dictionary, not in parent element’s dictionaries.

Hello world Hola mundo

public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); string str = (string)border.Resources["greeting"]; } }

Merged resource dictionaries A merged resource dictionary combines one resource dictionary into another, usually in another file. Tip You can create a resource dictionary file in Microsoft Visual Studio by using the Add > New Item… > Resource Dictionary option from the Project menu. Here, you define a resource dictionary in a separate XAML file called Dictionary1.xaml.

To use that dictionary, you merge it with your page’s dictionary:

Hello world

Here's what happens in this example. In , you declare . The XAML framework implicitly creates a resource dictionary for you when you add resources to ; however, in this case, you don’t want just any resource dictionary, you want one that contains merged dictionaries. So you declare , then add things to its collection. Each of those entries takes the form . To add more than one dictionary, just add a entry after the first entry. After … , you can optionally put additional resources in your main dictionary. You use resources from a merged to dictionary just like a regular dictionary. In the example above, {StaticResource brush} finds the resource in the child/merged dictionary (Dictionary1.xaml), while {StaticResource greeting} finds its resource in the main page dictionary. In the resource-lookup sequence, a MergedDictionaries dictionary is checked only after a check of all the other keyed resources of that ResourceDictionary. After searching that level, the lookup reaches the merged dictionaries, and each item in MergedDictionaries is checked. If multiple merged dictionaries exist, these dictionaries are checked in the inverse of the order in which they are declared in the MergedDictionaries property. In the following example, if both Dictionary2.xaml and Dictionary1.xaml declared the same key, the key from Dictionary2.xaml is used first because it's last in the MergedDictionaries set.

Within the scope of any one ResourceDictionary, the dictionary is checked for key uniqueness. However, that scope does not extend across different items in different MergedDictionaries files. You can use the combination of the lookup sequence and lack of unique key enforcement across merged-dictionary scopes to create a fallback value sequence of ResourceDictionary resources. For example, you might store user

preferences for a particular brush color in the last merged resource dictionary in the sequence, using a resource dictionary that synchronizes to your app's state and user preference data. However, if no user preferences exist yet, you can define that same key string for a ResourceDictionary resource in the initial MergedDictionaries file, and it can serve as the fallback value. Remember that any value you provide in a primary resource dictionary is always checked before the merged dictionaries are checked, so if you want to use the fallback technique, don't define that resource in a primary resource dictionary.

Theme resources and theme dictionaries A ThemeResource is similar to a StaticResource, but the resource lookup is reevaluated when the theme changes. In this example, you set the foreground of a TextBlock to a value from the current theme.

A theme dictionary is a special type of merged dictionary that holds the resources that vary with the theme a user is currently using on his or her device. For example, the "light" theme might use a white color brush whereas the "dark" theme might use a dark color brush. The brush changes the resource that it resolves to, but otherwise the composition of a control that uses the brush as a resource could be the same. To reproduce the theme-switching behavior in your own templates and styles, instead of using MergedDictionaries as the property to merge items into the main dictionaries, use the ThemeDictionaries property. Each ResourceDictionary element within ThemeDictionaries must have an x:Key value. The value is a string that names the relevant theme—for example, "Default", "Dark", "Light", or "HighContrast". Typically, Dictionary1 and Dictionary2 will define resources that have the same names but different values. Here, you use red text for the light theme and blue text for the dark theme.

In this example, you set the foreground of a TextBlock to a value from the current theme.



For theme dictionaries, the active dictionary to be used for resource lookup changes dynamically, whenever ThemeResource markup extension is used to make the reference and the system detects a theme change. The lookup behavior that is done by the system is based on mapping the active theme to the x:Key of a specific theme dictionary. It can be useful to examine the way that the theme dictionaries are structured in the default XAML design resources, which parallel the templates that the Windows Runtime uses by default for its controls. Open the XAML files in \ (Program Files)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\\Generic using a text editor or your IDE. Note how the theme dictionaries are defined first in generic.xaml, and how each theme dictionary defines the same keys. Each such key is then referenced by elements of composition in the various keyed elements that are outside the theme dictionaries and defined later in the XAML. There's also a separate themeresources.xaml file for design that contains only the theme resources and extra templates, not the default control templates. The theme areas are duplicates of what you'd see in generic.xaml. When you use XAML design tools to edit copies of styles and templates, the design tools extract sections from the XAML design resource dictionaries and place them as local copies of XAML dictionary elements that are part of your app and project. For more info and for a list of the theme-specific and system resources that are available to your app, see XAML theme resources.

Lookup behavior for XAML resource references Lookup behavior is the term that describes how the XAML resources system tries to find a XAML resource. The lookup occurs when a key is referenced as a XAML resource reference from somewhere in the app's XAML. First, the resources system has predictable behavior for where it will check for the existence of a resource based on scope. If a resource isn't found in the initial scope, the scope expands. The lookup behavior continues on throughout the locations and scopes that a XAML resource could possibly be defined by an app or by the system. If all possible resource lookup attempts fail, an error often results. It's usually possible to eliminate these errors during the development process. The lookup behavior for XAML resource references starts with the object where the actual usage is applied and its own Resources property. If a ResourceDictionary exists there, that ResourceDictionary is checked for an item that has the requested key. This first level of lookup is rarely relevant because you usually do not define and then reference a resource on the same object. In fact, a Resources property often doesn't exist here. You can make XAML resource references from nearly anywhere in XAML; you aren't limited to properties of FrameworkElement subclasses. The lookup sequence then checks the next parent object in the runtime object tree of the app. If a FrameworkElement.Resources exists and holds a ResourceDictionary, the dictionary item with the specified key string is requested. If the resource is found, the lookup sequence stops and the object is provided to the location where the reference was made. Otherwise, the lookup behavior advances to the next parent level towards the object

tree root. The search continues recursively upwards until the root element of the XAML is reached, exhausting the search of all possible immediate resource locations. Note It is a common practice to define all the immediate resources at the root level of a page, both to take advantage of this resource-lookup behavior and also as a convention of XAML markup style. If the requested resource is not found in the immediate resources, the next lookup step is to check the Application.Resources property. Application.Resources is the best place to put any app-specific resources that are referenced by multiple pages in your app's navigation structure. Control templates have another possible location in the reference lookup: theme dictionaries. A theme dictionary is a single XAML file that has a ResourceDictionary element as its root. The theme dictionary might be a merged dictionary from Application.Resources. The theme dictionary might also be the control-specific theme dictionary for a templated custom control. Finally, there is a resource lookup against platform resources. Platform resources include the control templates that are defined for each of the system UI themes, and which define the default appearance of all the controls that you use for UI in a Windows Runtime app. Platform resources also include a set of named resources that relate to system-wide appearance and themes. These resources are technically a MergedDictionaries item, and thus are available for lookup from XAML or code once the app has loaded. For example, the system theme resources include a resource named "SystemColorWindowTextColor" that provides a Color definition to match app text color to a system window's text color that comes from the operating system and user preferences. Other XAML styles for your app can refer to this style, or your code can get a resource lookup value (and cast it to Color in the example case). For more info and for a list of the theme-specific and system resources that are available to a Windows Store app that uses XAML, see XAML theme resources. If the requested key is still not found in any of these locations, a XAML parsing error/exception occurs. In certain circumstances, the XAML parse exception may be a run-time exception that is not detected either by a XAML markup compile action, or by a XAML design environment. Because of the tiered lookup behavior for resource dictionaries, you can deliberately define multiple resource items that each have the same string value as the key, as long as each resource is defined at a different level. In other words, although keys must be unique within any given ResourceDictionary, the uniqueness requirement does not extend to the lookup behavior sequence as a whole. During lookup, only the first such object that's successfully retrieved is used for the XAML resource reference, and then the lookup stops. You could use this behavior to request the same XAML resource by key at various positions within your app's XAML but get different resources back, depending on the scope from which the XAML resource reference was made and how that particular lookup behaves.

Forward references within a ResourceDictionary XAML resource references within a particular resource dictionary must reference a resource that has already been defined with a key, and that resource must appear lexically before the resource reference. Forward references cannot be resolved by a XAML resource reference. For this reason, if you use XAML resource references from within another resource, you must design your resource dictionary structure so that the resources that are used by other resources are defined first in a resource dictionary. Resources defined at the app level cannot make references to immediate resources. This is equivalent to attempting a forward reference, because the app resources are actually processed first (when the app first starts, and before any navigation-page content is loaded). However, any immediate resource can make a reference to an app resource, and this can be a useful technique for avoiding forward-reference situations.

XAML resources must be shareable For an object to exist in a ResourceDictionary, that object must be shareable. Being shareable is required because, when the object tree of an app is constructed and used at run time, objects cannot exist at multiple locations in the tree. Internally, the resource system creates copies of resource values to use in the object graph of your app when each XAML resource is requested. A ResourceDictionary and Windows Runtime XAML in general supports these objects for shareable usage: Styles and templates (Style and classes derived from FrameworkTemplate) Brushes and colors (classes derived from Brush, and Color values) Animation types including Storyboard Transforms (classes derived from GeneralTransform) Matrix and Matrix3D Point values Certain other UI-related structures such as Thickness and CornerRadius XAML intrinsic data types You can also use custom types as a shareable resource if you follow the necessary implementation patterns. You define such classes in your backing code (or in runtime components that you include) and then instantiate those classes in XAML as a resource. Examples are object data sources and IValueConverter implementations for data binding. Custom types must have a default constructor, because that's what a XAML parser uses to instantiate a class. Custom types used as resources can't have the UIElement class in their inheritance, because a UIElement can never be shareable (it's always intended to represent exactly one UI element that exists at one position in the object graph of your runtime app).

UserControl usage scope A UserControl element has a special situation for resource-lookup behavior because it has the inherent concepts of a definition scope and a usage scope. A UserControl that makes a XAML resource reference from its definition scope must be able to support the lookup of that resource within its own definition-scope lookup sequence—that is, it cannot access app resources. From a UserControl usage scope, a resource reference is treated as being within the lookup sequence towards its usage page root (just like any other resource reference made from an object in a loaded object tree) and can access app resources.

ResourceDictionary and XamlReader.Load You can use a ResourceDictionary as either the root or a part of the XAML input for the XamlReader.Load method. You can also include XAML resource references in that XAML if all such references are completely selfcontained in the XAML submitted for loading. XamlReader.Load parses the XAML in a context that is not aware of any other ResourceDictionary objects, not even Application.Resources. Also, don't use {ThemeResource} from within XAML submitted to XamlReader.Load.

Using a ResourceDictionary from code Most of the scenarios for a ResourceDictionary are handled exclusively in XAML. You declare the ResourceDictionary container and the resources within as a XAML file or set of XAML nodes in a UI definition file. And then you use XAML resource references to request those resources from other parts of XAML. Still, there are certain scenarios where your app might want to adjust the contents of a ResourceDictionary using code that executes while the app is running, or at least to query the contents of a ResourceDictionary to see if a resource is already defined. These code calls are made on a ResourceDictionary instance, so you must first retrieve one—

either an immediate ResourceDictionary somewhere in the object tree by getting FrameworkElement.Resources, or Application.Current.Resources . In C# or Microsoft Visual Basic code, you can reference a resource in a given ResourceDictionary by using the indexer (Item). A ResourceDictionary is a string-keyed dictionary, so the indexer uses the string key instead of an integer index. In Visual C++ component extensions (C++/CX) code, use Lookup. When using code to examine or change a ResourceDictionary, the behavior for APIs like Lookup or Item does not traverse from immediate resources to app resources; that's a XAML parser behavior that only happens as XAML pages are loaded. At run time, scope for keys is self-contained to the ResourceDictionary instance that you are using at the time. However, that scope does extend into MergedDictionaries. Also, if you request a key that does not exist in the ResourceDictionary, there may not be an error; the return value may simply be provided as null. You may still get an error, though, if you try to use the returned null as a value. The error would come from the property's setter, not your ResourceDictionary call. The only way you'd avoid an error is if the property accepted null as a valid value. Note how this behavior contrasts with XAML lookup behavior at XAML parse time; a failure to resolve the provided key from XAML at parse time results in a XAML parse error, even in cases where the property could have accepted null. Merged resource dictionaries are included into the index scope of the primary resource dictionary that references the merged dictionary at run time. In other words, you can use Item or Lookup of the primary dictionary to find any objects that were actually defined in the merged dictionary. In this case, the lookup behavior does resemble the parse-time XAML lookup behavior: if there are multiple objects in merged dictionaries that each have the same key, the object from the last-added dictionary is returned. You are permitted to add items to an existing ResourceDictionary by calling Add (C# or Visual Basic) or Insert (C++/CX). You could add the items to either immediate resources or app resources. Either of these API calls requires a key, which satisfies the requirement that each item in a ResourceDictionary must have a key. However, items that you add to a ResourceDictionary at run time are not relevant to XAML resource references. The necessary lookup for XAML resource references happens when that XAML is first parsed as the app is loaded (or a theme change is detected). Resources added to collections at run time weren't available then, and altering the ResourceDictionary doesn't invalidate an already retrieved resource from it even if you change the value of that resource. You also can remove items from a ResourceDictionary at run time, make copies of some or all items, or other operations. The members listing for ResourceDictionary indicates which APIs are available. Note that because ResourceDictionary has a projected API to support its underlying collection interfaces, your API options differ depending on whether you are using C# or Visual Basic versus C++/CX.

ResourceDictionary and localization A XAML ResourceDictionary might initially contain strings that are to be localized. If so, store these strings as project resources instead of in a ResourceDictionary. Take the strings out of the XAML, and instead give the owning element an x:Uid directive value. Then, define a resource in a resources file. Provide a resource name in the form XUIDValue.PropertyName and a resource value of the string that should be localized.

Custom resource lookup For advanced scenarios, you can implement a class that can have different behavior than the XAML resource reference lookup behavior described in this topic. To do this, you implement the class CustomXamlResourceLoader, and then you can access that behavior by using the CustomResource markup extension for resource references rather than using StaticResource or ThemeResource. Most apps won't have scenarios that require this. For more info, see CustomXamlResourceLoader.

Related topics

ResourceDictionary XAML overview StaticResource markup extension ThemeResource markup extension XAML theme resources Styling controls x:Key attribute

XAML theme resources 3/6/2017 • 13 min to read • Edit on GitHub

Theme resources in XAML are a set of resources that apply different values depending on which system theme is active. There are 3 themes that the XAML framework supports: "Light", "Dark", and "HighContrast". Prerequisites This topic assumes that you have read ResourceDictionary and XAML resource references.

How theme resources differ from static resources There are two XAML markup extensions that can reference a XAML resource from an existing XAML resource dictionary: {StaticResource} markup extension and {ThemeResource} markup extension. Evaluation of a {ThemeResource} markup extension occurs when the app loads and subsequently each time the theme changes at runtime. This is typically the result of the user changing their device settings or from a programmatic change within the app that alters its current theme. In contrast, a {StaticResource} markup extension is evaluated only when the XAML is first loaded by the app. It does not update. It’s similar to a find and replace in your XAML with the actual runtime value at app launch.

Theme resources and where they fit in the resource dictionary structure Each theme resource is part of the XAML file themeresources.xaml. For design purposes, themeresources.xaml is available in the \(Program Files)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\\Generic folder from a Windows Software Development Kit (SDK) installation. The resource dictionaries in themeresources.xaml are also reproduced in generic.xaml in the same directory. Note The Windows Runtime doesn't use these physical files for runtime lookup. That's why they are specifically in a DesignTime folder, and they aren't copied into apps by default. Instead, these resource dictionaries exist in memory as part of the Windows Runtime itself, and your app's XAML resource references to theme resources (or system resources) resolve there at runtime.

Guidelines for using theme resources Follow these guidelines when you define and consume your own custom theme resources. DO: Specify theme dictionaries for both "Light" and "Dark" in addition to your "HighContrast" dictionary. Although you can create a ResourceDictionary with "Default" as the key, it’s preferred to be explicit and instead use "Light", "Dark", and "HighContrast". Use the {ThemeResource} markup extension in: Styles, Setters, Control templates, Property setters, and Animations. DO NOT: Use the {ThemeResource} markup extension in your resource definitions inside your ThemeDictionaries. Use {StaticResource} markup extension instead.

EXCEPTION: it is alright to use the {ThemeResource} markup extension to reference resources that are agnostic to the app theme in your ThemeDictionaries. Examples of these resources are accent color resources like SystemAccentColor , or system color resources, which are typically prefixed with "SystemColor" like SystemColorButtonFaceColor . Caution If you don’t follow these guidelines, you might see unexpected behavior related to themes in your app. For more info, see the Troubleshooting theme resources section.

The XAML color ramp and theme-dependent brushes The combined set of colors for "Light", "Dark", and "HighContrast" themes make up the Windows color ramp in XAML. Whether you want to modify the system themes, or apply a system theme to your own XAML elements, it’s important to understand how the color resources are structured. Light and Dark theme colors

The XAML framework provides a set of named Color resources with values that are tailored for the "Light" and "Dark" themes. The keys you use to reference these follow the naming format: System[Simple Light/Dark Name]Color . This table lists the key, simple name, and string representation of the color (using the #aarrggbb format) for the "Light" and "Dark" resources provided by the XAML framework. The key is used to reference the resource in an app. The "Simple light/dark name" is used as part of the brush naming convention that we explain later. KEY

SIMPLE LIGHT/DARK NAME

LIGHT

DARK

SystemAltHighColor

AltHigh

#FFFFFFFF

#FF000000

SystemAltLowColor

AltLow

#33FFFFFF

#33000000

SystemAltMediumColor

AltMedium

#99FFFFFF

#99000000

SystemAltMediumHighColor

AltMediumHigh

#CCFFFFFF

#CC000000

SystemAltMediumLowColor

AltMediumLow

#66FFFFFF

#66000000

SystemBaseHighColor

BaseHigh

#FF000000

#FFFFFFFF

SystemBaseLowColor

BaseLow

#33000000

#33FFFFFF

SystemBaseMediumColor

BaseMedium

#99000000

#99FFFFFF

SystemBaseMediumHighCol or

BaseMediumHigh

#CC000000

#CCFFFFFF

SystemBaseMediumLowColo r

BaseMediumLow

#66000000

#66FFFFFF

SystemChromeAltLowColor

ChromeAltLow

#FF171717

#FFF2F2F2

SystemChromeBlackHighCol or

ChromeBlackHigh

#FF000000

#FF000000

SystemChromeBlackLowCol or

ChromeBlackLow

#33000000

#33000000

KEY

SIMPLE LIGHT/DARK NAME

LIGHT

DARK

SystemChromeBlackMedium LowColor

ChromeBlackMediumLow

#66000000

#66000000

SystemChromeBlackMedium Color

ChromeBlackMedium

#CC000000

#CC000000

SystemChromeDisabledHigh Color

ChromeDisabledHigh

#FFCCCCCC

#FF333333

SystemChromeDisabledLow Color

ChromeDisabledLow

#FF7A7A7A

#FF858585

SystemChromeHighColor

ChromeHigh

#FFCCCCCC

#FF767676

SystemChromeLowColor

ChromeLow

#FFF2F2F2

#FF171717

SystemChromeMediumColo r

ChromeMedium

#FFE6E6E6

#FF1F1F1F

SystemChromeMediumLow Color

ChromeMediumLow

#FFF2F2F2

#FF2B2B2B

SystemChromeWhiteColor

ChromeWhite

#FFFFFFFF

#FFFFFFFF

SystemListLowColor

ListLow

#19000000

#19FFFFFF

SystemListMediumColor

ListMedium

#33000000

#33FFFFFF

Windows system high-contrast colors

In addition to the set of resources provided by the XAML framework, there's a set of color values derived from the Windows system palette. These colors are not specific to the Windows Runtime or Universal Windows Platform (UWP) apps. However, many of the XAML Brush resources consume these colors when the system is operating (and the app is running) using the "HighContrast" theme. The XAML framework provides these system-wide colors as keyed resources. The keys follow the naming format: SystemColor[name]Color . This table lists the system-wide colors that XAML provides as resource objects derived from the Windows system palette. The "Ease of Access name" column shows how color is labeled in the Windows settings UI. The "Simple HighContrast name" column is a one word description of how the color is applied across the XAML common controls. It's used as part of the brush naming convention that we explain later. The "Initial default" column shows the values you'd get if the system is not running in high contrast at all. KEY

EASE OF ACCESS NAME

SIMPLE HIGHCONTRAST NAME

INITIAL DEFAULT

SystemColorButtonFaceColo r

Button Text (background)

Background

#FFF0F0F0

SystemColorButtonTextColo r

Button Text (foreground)

Foreground

#FF000000

SystemColorGrayTextColor

Disabled Text

Disabled

#FF6D6D6D

SystemColorHighlightColor

Selected Text (background)

Highlight

#FF3399FF

KEY

EASE OF ACCESS NAME

SIMPLE HIGHCONTRAST NAME

INITIAL DEFAULT

SystemColorHighlightTextCo lor

Selected Text (foreground)

HighlightAlt

#FFFFFFFF

SystemColorHotlightColor

Hyperlinks

Hyperlink

#FF0066CC

SystemColorWindowColor

Background

PageBackground

#FFFFFFFF

SystemColorWindowTextCol or

Text

PageText

#FF000000

Windows provides different high-contrast themes, and enables the user to set the specific colors to for their highcontrast settings through the Ease of Access Center, as shown here. Therefore, it's not possible to provide a definitive list of high-contrast color values.

For more info about supporting high-contrast themes, see High-contrast themes. System accent color

In addition to the system high-contrast theme colors, the system accent color is provided as a special color resource using the key SystemAccentColor . At runtime, this resource gets the color that the user has specified as the accent color in the Windows personalization settings. Note It’s possible to override the system color resources for high-contrast color and accent color by creating resources with the same names, but it’s a best practice to respect the user’s color choices, especially for highcontrast settings. Theme-dependent brushes

The color resources shown in the preceding sections are used to set the Color property of SolidColorBrush resources in the system theme resource dictionaries. You use the brush resources to apply the color to XAML elements. The keys for the brush resources follow the naming format:

SystemControl[Simple HighContrast name][Simple light/dark name]Brush

. For example,

SystemControlBackroundAltHighBrush

.

Let’s look at how the color value for this brush is determined at run-time. In the "Light" and "Dark" resource dictionaries, this brush is defined like this:

In the "HighContrast" resource dictionary, this brush is defined like this:

When this brush is applied to a XAML element, its color is determined at run-time by the current theme, as shown in this table. THEME

COLOR SIMPLE NAME

COLOR RESOURCE

RUNTIME VALUE

Light

AltHigh

SystemAltHighColor

#FFFFFFFF

Dark

AltHigh

SystemAltHighColor

#FF000000

HighContrast

Background

SystemColorButtonFaceColo r

The color specified in settings for the button background.

You can use the SystemControl[Simple HighContrast name][Simple light/dark name]Brush naming scheme to determine which brush to apply to your own XAML elements. Note Not every combination of [Simple HighContrast name][Simple light/dark name] is provided as a brush resource.

The XAML type ramp The themeresources.xaml file defines several resources that define a Style that you can apply to text containers in your UI, specifically for either TextBlock or RichTextBlock. These are not the default implicit styles. They are provided to make it easier for you to create XAML UI definitions that match the Windows type ramp documented in Guidelines for fonts. These styles are for text attributes that you want applied to the whole text container. If you want styles applied just to sections of the text, set attributes on the text elements within the container, such as on a Run in TextBlock.Inlines or on a Paragraph in RichTextBlock.Blocks. The styles look like this when applied to a TextBlock:

BaseTextBlockStyle

TargetType: TextBlock Supplies the common properties for all the other TextBlock container styles.

HeaderTextBlockStyle

SubheaderTextBlockStyle

TitleTextBlockStyle

SubtitleTextBlockStyle



BodyTextBlockStyle

CaptionTextBlockStyle

BaseRichTextBlockStyle

TargetType: RichTextBlock Supplies the common properties for all the other RichTextBlock container styles. Rich text.

BodyRichTextBlockStyle

Rich text.

Note The RichTextBlock styles don't have all the text ramp styles that TextBlock does, mainly because the block-based document object model for RichTextBlock makes it easier to set attributes on the individual text elements. Also, setting TextBlock.Text using the XAML content property introduces a situation where there is no text element to style and thus you'd have to style the container. That isn't an issue for RichTextBlock because its text content always has to be in specific text elements like Paragraph, which is where you might apply XAML styles for page header, page subheader and similar text ramp definitions.

Miscellaneous Named styles There's an additional set of keyed Style definitions you can apply to style a Button differently than its default implicit style. TextBlockButtonStyle

TargetType: ButtonBase Apply this style to a Button when you need to show text that a user can click to take action. The text is styled using the current accent color to distinguish it as interactive and has focus rectangles that work well for text. Unlike the implicit style of a HyperlinkButton, the TextBlockButtonStyle does not underline the text. The template also styles the presented text to use SystemControlHyperlinkBaseMediumBrush (for "PointerOver" state), SystemControlHighlightBaseMediumLowBrush (for "Pressed" state) and SystemControlDisabledBaseLowBrush (for "Disabled" state). Here's a Button with the TextBlockButtonStyle resource applied to it.

It looks like this:

NavigationBackButtonNormalStyle

TargetType: Button This Style provides a complete template for a Button that can be the navigation back button for a navigation app. It includes theme resource references that make this button use the Segoe MDL2 Assets symbol font, so you should use a Symbol value as the content rather than text. The default dimensions are 40 x 40 pixels. To tailor the styling you can either explicitly set the Height, Width, FontSize, and other properties on your Button or create a derived style using BasedOn. Here's a Button with the NavigationBackButtonNormalStyle resource applied to it.



It looks like this:

NavigationBackButtonSmallStyle

TargetType: Button This Style provides a complete template for a Button that can be the navigation back button for a navigation app. It's similar to NavigationBackButtonNormalStyle, but its dimensions are 30 by 30 pixels. Here's a Button with the NavigationBackButtonSmallStyle resource applied to it.

Troubleshooting theme resources If you don’t follow the guidelines for using theme resources, you might see unexpected behavior related to themes in your app. For example, when you open a light-themed flyout, parts of your dark-themed app also change as if they were in the light theme. Or if you navigate to a light-themed page and then navigate back, the original dark-themed page (or parts of it) now looks as though it is in the light theme. Typically, these types of issues occur when you provide a "Default" theme and a "HighContrast" theme to support high-contrast scenarios, and then use both "Light" and "Dark" themes in different parts of your app. For example, consider this theme dictionary definition:

Intuitively, this looks correct. You want to change the color pointed to by myBrush when in high-contrast, but when not in high-contrast, you rely on the {ThemeResource} markup extension to make sure that myBrush points to the right color for your theme. If your app never has FrameworkElement.RequestedTheme set on elements within its visual tree, this will typically work as expected. However, you run into problems in your app as soon as you start to re-theme different parts of your visual tree. The problem occurs because brushes are shared resources, unlike most other XAML types. If you have 2 elements in XAML sub-trees with different themes that reference the same brush resource, then as the framework walks each sub-tree to update its {ThemeResource} markup extension expressions, changes to the shared brush resource are reflected in the other sub-tree, which is not your intended result.

To fix this, replace the "Default" dictionary with separate theme dictionaries for both "Light" and "Dark" themes in addition to "HighContrast":

However, problems still occur if any of these resources are referenced in inherited properties like Foreground. Your custom control template might specify the foreground color of an element using the {ThemeResource} markup extension, but when the framework propagates the inherited value to child elements, it provides a direct reference to the resource that was resolved by the {ThemeResource} markup extension expression. This causes problems when the framework processes theme changes as it walks your control's visual tree. It re-evaluates the {ThemeResource} markup extension expression to get a new brush resource but doesn’t yet propagate this reference down to the children of your control; this happens later, such as during the next measure pass. As a result, after walking the control visual tree in response to a theme change, the framework walks the children and updates any {ThemeResource} markup extension expressions set on them, or on objects set on their properties. This is where the problem occurs; the framework walks the brush resource and because it specifies its color using a {ThemeResource} markup extension, it's re-evaluated. At this point, the framework appears to have polluted your theme dictionary because it now has a resource from one dictionary that has its color set from another dictionary. To fix this problem, use the {StaticResource} markup extension instead of {ThemeResource} markup extension. With the guidelines applied, the theme dictionaries look like this:

Notice that the {ThemeResource} markup extension is still used in the "HighContrast" dictionary instead of {StaticResource} markup extension. This situation falls under the exception given earlier in the guidelines. Most of the brush values that are used for the "HighContrast" theme are using color choices that are globally controlled by the system, but exposed to XAML as a specially-named resource (those prefixed with ‘SystemColor’ in the name). The system enables the user to set the specific colors that should be used for their high contrast settings through the Ease of Access Center. Those color choices are applied to the specially-named resources. The XAML framework uses the same theme changed event to also update these brushes when it detects they’ve changed at the system

level. This is why the {ThemeResource} markup extension is used here.

Controls and patterns for UWP apps 3/6/2017 • 2 min to read • Edit on GitHub

In UWP app development, a control is a UI element that displays content or enables interaction. Controls are the building blocks of the user interface. We provide 45+ controls for you to use, ranging from simple buttons to powerful data controls like the grid view. A pattern is a recipe for combining several controls to make something new. The articles in this section provide design guidance and coding instructions for adding controls & patterns to your UWP app.

Intro General instructions and code examples for adding and styling controls in XAML and C#. Add controls and handle events There are 3 key steps to adding controls to your app: Add a control to your app UI, set properties on the control, and add code to the control's event handlers so that it does something. Styling controls You can customize the appearance of your apps in many ways by using the XAML framework. Styles let you set control properties and reuse those settings for a consistent appearance across multiple controls.

Alphabetical index Detailed information about specific controls and patterns. (For a list sorted by function, see Index of controls by function.) Auto-suggest box Bars Buttons Checkbox Date and time controls Calendar date picker Calendar view Date picker Time picker Dialogs and flyouts Flip view Hub Hyperlinks Images and image brushes Lists Map control

Master/details Media playback Custom transport controls Menus and context menus Nav pane Progress controls Radio button Scrolling and panning controls Search Semantic zoom Slider Split view Tabs and pivots Text controls Labels Password boxes Rich-edit boxes Rich-text blocks Spell-checking and prediction Text block Text box Tiles, badges, and notifications Tiles Adaptive tiles Adaptive tiles schema Asset guidelines Special tile templates Adaptive and interactive toast notifications Badge notifications Notifications visualizer Notification delivery methods Local tile notifications Periodic notifications WNS Raw notifications Toggle Tooltips Web view

Additional controls options Additional controls for UWP development are available from companies such as Telerik, SyncFusion, DevExpress,

Infragistics, ComponentOne, and ActiPro. These controls provide additional support for enterprise and .NET developers by augmenting the standard system controls with custom controls and services. If you're interested in learning more about these controls, check out the Customer orders database sample on GitHub. This sample makes use of the data grid control and data entry validation from Telerik, which is part of their UI for UWP suite. The UI for UWP suite is a collection of over 20 controls that is available as an open source project through the .NET foundation.

Intro to controls and patterns 3/6/2017 • 6 min to read • Edit on GitHub

In UWP app development, a control is a UI element that displays content or enables interaction. You create the UI for your app by using controls such as buttons, text boxes, and combo boxes to display data and get user input. A pattern is a recipe for modifying a control or combining several controls to make something new. For example, the Nav pane pattern is a way that you can use a SplitView control for app navigation. Similarly, you can customize the template of a Pivot control to implement the tab pattern. In many cases, you can use a control as-is. But XAML controls separate function from structure and appearance, so you can make various levels of modification to make them fit your needs. In the Style section, you can learn how to use XAML styles and control templates to modify a control. In this section, we provide guidance for each of the XAML controls you can use to build your app UI. To start, this article shows you how to add controls to your app. There are 3 key steps to using controls to your app: Add a control to your app UI. Set properties on the control, such as width, height, or foreground color. Add code to the control's event handlers so that it does something.

Add a control You can add a control to an app in several ways: Use a design tool like Blend for Visual Studio or the Microsoft Visual Studio Extensible Application Markup Language (XAML) designer. Add the control to the XAML markup in the Visual Studio XAML editor. Add the control in code. Controls that you add in code are visible when the app runs, but are not visible in the Visual Studio XAML designer. In Visual Studio, when you add and manipulate controls in your app, you can use many of the program's features, including the Toolbox, XAML designer, XAML editor, and the Properties window. The Visual Studio Toolbox displays many of the controls that you can use in your app. To add a control to your app, double-click it in the Toolbox. For example, when you double-click the TextBox control, this XAML is added to the XAML view.

You can also drag the control from the Toolbox to the XAML designer.

Set the name of a control To work with a control in code, you set its x:Name attribute and reference it by name in your code. You can set the name in the Visual Studio Properties window or in XAML. Here's how to set the name of the currently selected control by using the Name text box at the top of the Properties window. To name a control 1. Select the element to name. 2. In the Properties panel, type a name into the Name text box.

3. Press Enter to commit the name.

Here's how to set the name of a control in the XAML editor by adding the x:Name attribute.

Set the control properties You use properties to specify the appearance, content, and other attributes of controls. When you add a control using a design tool, some properties that control size, position, and content might be set for you by Visual Studio. You can change some properties, such as Width, Height or Margin, by selecting and manipulating the control in the Design view. This illustration shows some of the resizing tools available in Design view.

You might want to let the control be sized and positioned automatically. In this case, you can reset the size and position properties that Visual Studio set for you. To reset a property 1. In the Properties panel, click the property marker next to the property value. The property menu opens. 2. In the property menu, click Reset.

You can set control properties in the Properties window, in XAML, or in code. For example, to change the foreground color for a Button, you set the control's Foreground property. This illustration shows how to set the Foreground property by using the color picker in the Properties window.

Here's how to set the Foreground property in the XAML editor. Notice the Visual Studio IntelliSense window that opens to help you with the syntax.

Here's the resulting XAML after you set the Foreground property.

Here's how to set the Foreground property in code.

Button1.Foreground = new SolidColorBrush(Windows.UI.Colors.Beige);

Create an event handler Each control has events that enable you to respond to actions from your user or other changes in your app. For example, a Button control has a Click event that is raised when a user clicks the Button. You create a method, called an event handler, to handle the event. You can associate a control's event with an event handler method in the Properties window, in XAML, or in code. For more info about events, see Events and routed events overview. To create an event handler, select the control and then click the Events tab at the top of the Properties window. The Properties window lists all of the events available for that control. Here are some of the events for a Button.

To create an event handler with the default name, double-click the text box next to the event name in the Properties window. To create an event handler with a custom name, type the name of your choice into the text box and press enter. The event handler is created and the code-behind file is opened in the code editor. The event handler method has 2 parameters. The first is sender , which is a reference to the object where the handler is attached. The sender parameter is an Object type. You typically cast sender to a more precise type if you expect to check or change the state on the sender object itself. Based on your own app design, you expect a type that is safe to cast the sender to, based on where the handler is attached. The second value is event data, which generally appears in signatures as the e or args parameter. Here's code that handles the Click event of a Button named property of the Button you clicked is set to blue.

Button1

. When you click the button, the Foreground

private void Button_Click(object sender, RoutedEventArgs e) { Button b = (Button)sender; b.Foreground = new SolidColorBrush(Windows.UI.Colors.Blue); }

You can also associate an event handler in XAML. In the XAML editor, type in the event name that you want to handle. Visual Studio shows an IntelliSense window when you begin typing. After you specify the event, you can double-click in the IntelliSense window to create a new event handler with the default name, or select an existing event handler from the list.

Here's the IntelliSense window that appears. It helps you create a new event handler or select an existing event handler.

This example shows how to associate a Click event with an event handler named Button_Click in XAML.

You can also associate an event with its event handler in the code-behind. Here's how to associate an event handler in code. Button1.Click += new RoutedEventHandler(Button_Click);

Related topics Index of controls by function Windows.UI.Xaml.Controls namespace Layout Style Usability

Controls by function 3/6/2017 • 9 min to read • Edit on GitHub

The XAML UI framework for Windows provides an extensive library of controls that support UI development. Some of these controls have a visual representation; others function as the containers for other controls or content, such as images and media. You can see many of the Windows UI controls in action by downloading the XAML UI Basics sample. Here's a list by function of the common XAML controls you can use in your app.

Appbars and commands App bar

A toolbar for displaying application-specific commands. See Command bar. Reference: AppBar App bar button

A button for showing commands using app bar styling.

Reference: AppBarButton, SymbolIcon, BitmapIcon, FontIcon, PathIcon Design and how-to: App bar and command bar control guide Sample code: XAML Commanding sample App bar separator

Visually separates groups of commands in a command bar. Reference: AppBarSeparator Sample code: XAML Commanding sample App bar toggle button

A button for toggling commands in a command bar. Reference: AppBarToggleButton Sample code: XAML Commanding sample Command bar

A specialized app bar that handles the resizing of app bar button elements.



Reference: CommandBar Design and how-to: App bar and command bar control guide Sample code: XAML Commanding sample

Buttons Button

A control that responds to user input and raises a Click event.



Reference: Button Design and how-to: Buttons control guide Hyperlink

See Hyperlink button. Hyperlink button

A button that appears as marked up text and opens the specified URI in a browser.



Reference: HyperlinkButton Design and how-to: Hyperlinks control guide Repeat button

A button that raises its Click event repeatedly from the time it's pressed until it's released.



Reference: RepeatButton

Design and how-to: Buttons control guide

Collection/data controls Flip view

A control that presents a collection of items that the user can flip through, one item at a time.

Reference: FlipView Design and how-to: Flip view control guide Grid view

A control that presents a collection of items in rows and columns that can scroll horizontally. Item 1 Item 2

Reference: GridView Design and how-to: Lists Sample code: ListView sample Items control

A control that presents a collection of items in a UI specified by a data template.

Reference: ItemsControl List view

A control that presents a collection of items in a list that can scroll vertically. Item 1 Item 2

Reference: ListView Design and how-to: Lists Sample code: ListView sample

Date and time controls Calendar date picker

A control that lets a user select a date using a drop-down calendar display.



Reference: CalendarDatePicker Design and how-to: Calendar, date, and time controls Calendar view

A configurable calendar display that lets a user select single or multiple dates.

Reference: CalendarView Design and how-to: Calendar, date, and time controls Date picker

A control that lets a user select a date.



Reference: DatePicker Design and how-to: Calendar, date, and time controls Time picker

A control that lets a user set a time value.



Reference: TimePicker Design and how-to: Calendar, date, and time controls

Flyouts Context menu

See Menu flyout and Popup menu. Flyout

Displays a message that requires user interaction. (Unlike a dialog, a flyout does not create a separate window, and does not block other user interaction.)



Reference: Flyout Design and how-to: Context menus and dialogs Menu flyout

Temporarily displays a list of commands or options related to what the user is currently doing.



Reference: MenuFlyout, MenuFlyoutItem, MenuFlyoutSeparator, ToggleMenuFlyoutItem Design and how-to: Context menus and dialogs

Sample code: XAML Context Menu sample Popup menu

A custom menu that presents commands that you specify. Reference: PopupMenu Design and how-to: Context menus and dialogs Tooltip

A pop-up window that displays information for an element.



Reference: ToolTip, ToolTipService Design and how-to: Guidelines for tooltips

Images Image

A control that presents an image.

Reference: Image Design and how-to: Image and ImageBrush Sample code: XAML images sample

Graphics and ink InkCanvas

A control that receives and displays ink strokes.

Reference: InkCanvas Shapes

Various retained mode graphical objects that can be presented like ellipses, rectangles, lines, Bezier paths, etc.



Reference: Shapes How to: Drawing shapes Sample code: XAML vector-based drawing sample

Layout controls Border

A container control that draws a border, background, or both, around another object.



Reference: Border Canvas

A layout panel that supports the absolute positioning of child elements relative to the top left corner of the canvas.



Reference: Canvas Grid

A layout panel that supports the arranging of child elements in rows and columns.



Reference: Grid Panning scroll viewer

See Scroll viewer. RelativePanel

A panel that lets you position and align child objects in relation to each other or the parent panel.



Reference: RelativePanel Scroll bar

See scroll viewer. (ScrollBar is an element of ScrollViewer. You don't typically use it as a stand-alone control.) Reference: ScrollBar Scroll viewer

A container control that lets the user pan and zoom its content.



Reference: ScrollViewer Design and how-to: Scroll and panning controls guide Sample code: XAML scrolling, panning and zooming sample Stack panel

A layout panel that arranges child elements into a single line that can be oriented horizontally or vertically.



Reference: StackPanel VariableSizedWrapGrid

A layout panel that supports the arranging of child elements in rows and columns. Each child element can span multiple rows and columns.



Reference: VariableSizedWrapGrid

Viewbox

A container control that scales its content to a specified size.



Reference: Viewbox Zooming scroll viewer

See Scroll viewer.

Media controls Audio

See Media element. Media element

A control that plays audio and video content.

Reference: MediaElement Design and how-to: Media element control guide MediaTransportControls

A control that provides playback controls for a MediaElement.



Reference: MediaTransportControls

Design and how-to: Media element control guide Sample code: Media Transport Controls sample Video

See Media element.

Navigation Hub

A container control that lets the user view and navigate to different sections of content.

Reference: Hub Design and how-to: Hub control guide Sample code:XAML Hub control sample Pivot

A full-screen container and navigation model that also provides a quick way to move between different pivots (views or filters), typically in the same set of data. The Pivot control can be styled to have a "tab" layout. Reference: Pivot Design and how-to: Tabs and pivot control guide Sample code: Pivot sample Semantic zoom

A container control that lets the user zoom between two views of a collection of items.

Reference: SemanticZoom Design and how-to: Semantic zoom control guide Sample code: XAML GridView grouping and SemanticZoom sample SplitView

A container control with two views; one view for the main content and another view that is typically used for a

navigation menu.



Reference: SplitView Design and how-to: Split view control guide Web view

A container control that hosts web content.

Reference: WebView Design and how-to: Guidelines for Web views Sample code: XAML WebView control sample

Progress controls Progress bar

A control that indicates progress by displaying a bar.

A progress bar that shows a specific value.

A progress bar that shows indeterminate progress.

Reference: ProgressBar Design and how-to: Progress controls guide Progress ring

A control that indicates indeterminate progress by displaying a ring.



Reference: ProgressRing Design and how-to: Progress controls guide

Text controls Auto suggest box

A text input box that provides suggested text as the user types.

Reference: AutoSuggestBox Design and how-to: Text controls, Auto suggest box control guide Sample code: AutoSuggestBox migration sample Multi-line text box

See Text box. Password box

A control for entering passwords.



Reference: PasswordBox Design and how-to: Text controls, Password box control guide Sample code: XAML text display sample, XAML text editing sample

Rich edit box

A control that lets a user edit rich text documents with content like formatted text, hyperlinks, and images.

Reference: RichEditBox Design and how-to: Text controls, Rich edit box control guide Sample code: XAML text sample Search box

See Auto suggest box. Single-line text box

See Text box. Static text/paragraph

See Text block. Text block

A control that displays text.



Reference: TextBlock, RichTextBlock Design and how-to: Text controls, Text block control guide, Rich text block control guide Sample code: XAML text sample Text box

A single-line or multi-line plain text field.



Reference: TextBox Design and how-to: Text controls, Text box control guide Sample code: XAML text sample

Selection controls Check box

A control that a user can select or clear.



Reference: CheckBox Design and how-to: Check box control guide Combo box

A drop-down list of items a user can select from.

Item 1 Item 2 Item 3

Reference: ComboBox Design and how-to: Lists List box

A control that presents an inline list of items that the user can select from.

Item 1 Item 2 Item 3

Reference: ListBox Design and how-to: Lists Radio button

A control that allows a user to select a single option from a group of options. When radio buttons are grouped together, they are mutually exclusive.



Reference: RadioButton Design and how-to: Radio button control guide Slider

A control that lets the user select from a range of values by moving a Thumb control along a track.



Reference: Slider Design and how-to: Slider control guide Toggle button

A button that can be toggled between 2 states.

Reference: ToggleButton Design and how-to: Toggle control guide Toggle switch

A switch that can be toggled between 2 states.



Reference: ToggleSwitch Design and how-to: Toggle control guide

App bar and command bar 3/6/2017 • 12 min to read • Edit on GitHub

Command bars (also called "app bars") provide users with easy access to your app's most common tasks, and can be used to show commands or options that are specific to the user's context, such as a photo selection or drawing mode. They can also be used for navigation among app pages or between app sections. Command bars can be used with any navigation pattern.

Important APIs CommandBar AppBarButton AppBarToggleButton AppBarSeparator

Is this the right control? The CommandBar control is a general-purpose, flexible, light-weight control that can display both complex content, such as images or text blocks, as well as simple commands such as AppBarButton, AppBarToggleButton, and AppBarSeparator controls. XAML provides both the AppBar control and the CommandBar control. You should use the AppBar only when you are upgrading a Universal Windows 8 app that uses the AppBar, and need to minimize changes. For new apps in Windows 10, we recommend using the CommandBar control instead. This document assumes you are using the CommandBar control.

Examples An expanded command bar in the Microsoft Photos app.

A command bar in the Outlook Calendar on Windows Phone.

Anatomy By default, the command bar shows a row of icon buttons and an optional "see more" button, which is represented by an ellipsis [•••]. Here's the command bar created by the example code shown later. It's shown in its closed compact state.

The command bar can also be shown in a closed minimal state that looks like this. See the Open and closed states section for more info.

Here's the same command bar in its open state. The labels identify the main parts of the control.

The command bar is divided into 4 main areas:

The "see more" [•••] button is shown on the right of the bar. Pressing the "see more" [•••] button has 2 effects: it reveals the labels on the primary command buttons, and it opens the overflow menu if any secondary commands are present. In the newest SDK, the button will not be visible when no secondary commands and no hidden labels are present. OverflowButtonVisibility property allows apps to change this default auto-hide behavior. The content area is aligned to the left side of the bar. It is shown if the Content property is populated. The primary command area is aligned to the right side of the bar, next to the "see more" [•••] button. It is shown if the PrimaryCommands property is populated. The overflow menu is shown only when the command bar is open and the SecondaryCommands property is populated. The new dynamic overflow behavior will automatically move primary commands into the SecondaryCommands area when space is limited. The layout is reversed when the FlowDirection is RightToLeft.

Create a command bar This example creates the command bar shown previously.

Commands and content The CommandBar control has 3 properties you can use to add commands and content: PrimaryCommands, SecondaryCommands, and Content. Primary actions and overflow

By default, items you add to the command bar are added to the PrimaryCommands collection. These commands are shown to the left of the "see more" [•••] button, in what we call the action space. Place the most important commands, the ones that you want to remain visible in the bar, in the action space. On the smallest screens (320 epx width), a maximum of 4 items will fit in the command bar's action space. You can add commands to the SecondaryCommands collection, and these items are shown in the overflow area. Place less important commands within the overflow area. The default overflow area is styled to be distinct from the bar. You can adjust the styling by setting the CommandBarOverflowPresenterStyle property to a Style that targets the CommandBarOverflowPresenter. You can programmatically move commands between the PrimaryCommands and SecondaryCommands as needed.

App bar buttons

Both the PrimaryCommands and SecondaryCommands can be populated only with AppBarButton, AppBarToggleButton, and AppBarSeparator command elements. These controls are optimized for use in a command bar, and their appearance changes depending on whether the control is used in the action space or overflow area. The app bar button controls are characterized by an icon and associated label. They have two sizes; normal and compact. By default, the text label is shown. When the IsCompact property is set to true, the text label is hidden. When used in a CommandBar control, the command bar overwrites the button's IsCompact property automatically as the command bar is opened and closed. To position app bar button labels to the right of their icons, apps can use CommandBar's new DefaultLabelPosition property.

Here is what the code snippet above looks like when drawn by an app.

Individual app bar buttons cannot move their label position, this must be done on the command bar as a whole. App bar buttons can specify that their labels never show by setting the new LabelPosition property to Collapsed. We recommend limiting the use of this setting to universally recognizable iconography such as '+'. When you place an app bar button in the overflow menu (SecondaryCommands), it's shown as text only. The LabelPosition of app bar buttons in the overflow will be ignored. Here's the same app bar toggle button shown in the action space as a primary command (top), and in the overflow area as a secondary command (bottom).

If there is a command that would appear consistently across pages, it's best to keep that command in a consistent location. We recommended placing Accept, Yes, and OK commands to the left of Reject, No, and Cancel. Consistency gives users the confidence to move around the system and helps them transfer their knowledge of app navigation from app to app. Button labels

We recommend keeping app bar button labels short, preferably a single word. Longer labels positioned bellow an app bar button's icon will wrap to multiple lines thus increasing the overall height of the opened command bar. You can include a soft-hyphen character (0x00AD) in the text for a label to hint at the character boundary where a word break should occur. In XAML, you express this using an escape sequence, like this:

When the label wraps at the hinted location, it looks like this.

Other content

You can add any XAML elements to the content area by setting the Content property. If you want to add more than one element, you need to place them in a panel container and make the panel the single child of the Content property. When there are both primary commands and content, the primary commands take precedence and may cause the content to be clipped. When the ClosedDisplayMode is Compact, the content can be clipped if it is larger than the compact size of the command bar. You should handle the Opening and Closed events to show or hide parts of the UI in the content area so that they aren't clipped. See the Open and closed states section for more info.

Open and closed states The command bar can be open or closed. A user can switch between these states by pressing the "see more" [•••] button. You can switch between them programmatically by setting the IsOpen property. When open, the primary command buttons are shown with text labels and the overflow menu is open if secondary commands are present, as shown previously. You can use the Opening, Opened, Closing, and Closed events to respond to the command bar being opened or closed. The Opening and Closing events occur before the transition animation begins. The Opened and Closed events occur after the transition completes. In this example, the Opening and Closing events are used to change the opacity of the command bar. When the command bar is closed, it's semi-transparent so the app background shows through. When the command bar is opened, the command bar is made opaque so the user can focus on the commands.

private void CommandBar_Opening(object sender, object e) { CommandBar cb = sender as CommandBar; if (cb != null) cb.Background.Opacity = 1.0; } private void CommandBar_Closing(object sender, object e) { CommandBar cb = sender as CommandBar; if (cb != null) cb.Background.Opacity = 0.5; }

ClosedDisplayMode

You can control how the command bar is shown in its closed state by setting the ClosedDisplayMode property. There are 3 closed display modes to choose from:

Compact: The default mode. Shows content, primary command icons without labels, and the "see more" [•••] button. Minimal: Shows only a thin bar that acts as the "see more" [•••] button. The user can press anywhere on the bar to open it. Hidden: The command bar is not shown when it's closed. This can be useful for showing contextual commands with an inline command bar. In this case, you must open the command bar programmatically by setting the IsOpen property or changing the ClosedDisplayMode to Minimal or Compact. Here, a command bar is used to hold simple formatting commands for a RichEditBox. When the edit box doesn't have focus, the formatting commands can be distracting, so they're hidden. When the edit box is being used, the command bar's ClosedDisplayMode is changed to Compact so the formatting commands are visible.

private void EditStackPanel_GotFocus(object sender, RoutedEventArgs e) { FormattingCommandBar.ClosedDisplayMode = AppBarClosedDisplayMode.Compact; } private void EditStackPanel_LostFocus(object sender, RoutedEventArgs e) { FormattingCommandBar.ClosedDisplayMode = AppBarClosedDisplayMode.Hidden; }

Note The implementation of the editing commands is beyond the scope of this example. For more info, see the RichEditBox article. Although the Minimal and Hidden modes are useful in some situations, keep in mind that hiding all actions could confuse users. Changing the ClosedDisplayMode to provide more or less of a hint to the user affects the layout of surrounding elements. In contrast, when the CommandBar transitions between closed and open, it does not affect the layout of other elements. IsSticky

After opening the command bar, if the user interacts with the app anywhere outside of the control then by default the overflow menu is dismissed and the labels are hidden. Closing it in this way is called light dismiss. You can control how the bar is dismissed by setting the IsSticky property. When the bar is sticky ( IsSticky="true" ), it's not closed by a light dismiss gesture. The bar remains open until the user presses the "see more" [•••] button or selects an item from the overflow menu. We recommend avoiding sticky command bars because they don't conform to users' expectations around light dismiss.

Do's and don'ts Placement

Command bars can be placed at the top of the app window, at the bottom of the app window, and inline.

For small handheld devices, we recommend positioning command bars at the bottom of the screen for easy reachability. For devices with larger screens, if you're placing just one command bar, we recommend placing it near the top of the window. Use the DiagonalSizeInInches API to determine physical screen size. Command bars can be placed in the following screen regions on single-view screens (left example) and on multi-view screens (right example). Inline command bars can be placed anywhere in the action space.

Touch devices: If the command bar must remain visible to a user when the touch keyboard, or Soft Input Panel (SIP), appears then you can assign the command bar to the BottomAppBar property of a Page and it will move to remain visible when the SIP is present. Otherwise, you should place the command bar inline and positioned relative to your app content. Actions

Prioritize the actions that go in the command bar based on their visibility. Place the most important commands, the ones that you want to remain visible in the bar, in the first few slots of the action space. On the smallest screens (320 epx width), between 2-4 items will fit in the command bar's action space, depending on other on-screen UI. Place less-important commands later in the bar's action space or within the first few slots of the overflow area. These commands will be visible when the bar has enough screen real estate, but will fall into the overflow area's drop-down menu when there isn't enough room. Place the least-important commands within the overflow area. These commands will always appear in the drop-down menu. If there is a command that would appear consistently across pages, it's best to keep that command in a

consistent location. We recommended placing Accept, Yes, and OK commands to the left of Reject, No, and Cancel. Consistency gives users the confidence to move around the system and helps them transfer their knowledge of app navigation from app to app. Although you can place all actions within the overflow area so that only the "see more" [•••] button is visible on the command bar, keep in mind that hiding all actions could confuse users. Command bar flyouts

Consider logical groupings for the commands, such as placing Reply, Reply All, and Forward in a Respond menu. While typically an app bar button activates a single command, an app bar button can be used to show a MenuFlyout or Flyout with custom content.

Overflow menu

The overflow menu is represented by the "see more" [•••] button, the visible entry point for the menu. It's on the far-right of the toolbar, adjacent to primary actions. The overflow area is allocated for actions that are less frequently used. Actions can come and go between the primary action space and the overflow menu at breakpoints. You can also designate actions to always remain in the primary action space regardless of screen or app window size. Infrequently used actions can remain in the overflow menu even when the app bar is expanded on larger screens.

Adaptability The same number of actions in the app bar should be visible in both portrait and landscape orientation, which reduces the user's cognitive load. The number of actions available should be determined by the device's width in portrait orientation. On small screens that are likely to be used one-handed, app bars should be positioned near the bottom of the screen.

On larger screens, placing app bars closer to the top of the window makes them more noticeable and discoverable. By targeting breakpoints, you can move actions in and out of the menu as the window size changes. By targeting screen diagonal, you can modify app bar position based on device screen size. Consider moving labels to the right of app bar button icons to improve legibility. Labels on the bottom require users to open the command bar to reveal labels, while labels on the right are visible even when command bar is closed. This optimization works well on larger windows.

Get the sample code Commanding sample XAML UI basics sample

Related articles Command design basics for UWP apps CommandBar class

Auto-suggest box 3/6/2017 • 4 min to read • Edit on GitHub

Use an AutoSuggestBox to provide a list of suggestions for a user to select from as they type.

Important APIs AutoSuggestBox class TextChanged event SuggestionChose event QuerySubmitted event

Is this the right control? If you'd like a simple, customizable control that allows text search with a list of suggestions, then choose an autosuggest box. For more info about choosing the right text control, see the Text controls article.

Examples An auto suggest box in the Groove Music app.

Anatomy The entry point for the auto-suggest box consists of an optional header and a text box with optional hint text:

The auto-suggest results list populates automatically once the user starts to enter text. The results list can appear above or below the text entry box. A "clear all" button appears:

Create an auto-suggest box To use an AutoSuggestBox, you need to respond to 3 user actions. Text changed - When the user enters text, update the suggestion list. Suggestion chosen - When the user chooses a suggestion in the suggestion list, update the text box. Query submitted - When the user submits a query, show the query results. Text changed

The TextChanged event occurs whenever the content of the text box is updated. Use the event args Reason property to determine whether the change was due to user input. If the change reason is UserInput, filter your data based on the input. Then, set the filtered data as the ItemsSource of the AutoSuggestBox to update the suggestion list. To control how items are displayed in the suggestion list, you can use DisplayMemberPath or ItemTemplate. To display the text of a single property of your data item, set the DisplayMemberPath property to choose which property from your object to display in the suggestion list. To define a custom look for each item in the list, use the ItemTemplate property. Suggestion chosen

When a user navigates through the suggestion list using the keyboard, you need to update the text in the text box to match. You can set the TextMemberPath property to choose which property from your data object to display in the text box. If you specify a TextMemberPath, the text box is updated automatically. You should typically specify the same value for DisplayMemberPath and TextMemberPath so the text is the same in the suggestion list and the text box. If you need to show more than a simple property, handle the SuggestionChosen event to populate the text box with custom text based on the selected item. Query submitted

Handle the QuerySubmitted event to perform a query action appropriate to your app and show the result to the user.

The QuerySubmitted event occurs when a user commits a query string. The user can commit a query in one of these ways: While the focus is in the text box, press Enter or click the query icon. The event args ChosenSuggestion property is null. While the focus is in the suggestion list, press Enter, click, or tap an item. The event args ChosenSuggestion property contains the item that was selected from the list. In all cases, the event args QueryText property contains the text from the text box.

Use AutoSuggestBox for search Use an AutoSuggestBox to provide a list of suggestions for a user to select from as they type. By default, the text entry box doesn’t have a query button shown. You can set the QueryIcon property to add a button with the specified icon on the right side of the text box. For example, to make the AutoSuggestBox look like a typical search box, add a ‘find’ icon, like this.

Here's an AutoSuggestBox with a 'find' icon.

Get the sample code To see complete working examples of AutoSuggestBox, see the AutoSuggestBox sample and XAML UI Basics sample. Here is a simple AutoSuggestBox with the required event handlers.

private void AutoSuggestBox_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args) { // Only get results when it was a user typing, // otherwise assume the value got filled in by TextMemberPath // or the handler for SuggestionChosen. if (args.Reason == AutoSuggestionBoxTextChangeReason.UserInput) { //Set the ItemsSource to be your filtered dataset //sender.ItemsSource = dataset; } }

private void AutoSuggestBox_SuggestionChosen(AutoSuggestBox sender, AutoSuggestBoxSuggestionChosenEventArgs args) { // Set sender.Text. You can use args.SelectedItem to build your text string. }

private void AutoSuggestBox_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args) { if (args.ChosenSuggestion != null) { // User selected an item from the suggestion list, take an action on it here. } else { // Use args.QueryText to determine what to do. } }

Do's and don'ts When using the auto-suggest box to perform searches and no search results exist for the entered text, display a single-line "No results" message as the result so that users know their search request executed:

Related articles Text controls Spell checking Search TextBox class Windows.UI.Xaml.Controls PasswordBox class String.Length property

Buttons 3/13/2017 • 5 min to read • Edit on GitHub

A button gives the user a way to trigger an immediate action.

Important APIs Button class RepeatButton class Click event

Is this the right control? A button lets the user initiate an immediate action, such as submitting a form. Don't use a button when the action is to navigate to another page; use a link instead. See Hyperlinks for more info. Exception: For wizard navigation, use buttons labeled "Back" and "Next". For other types of backwards navigation or navigation to an upper level, use a back button.

Example This example uses two buttons, Close all and Cancel, in a dialog in the Microsoft Edge browser.

Create a button This example shows a button that responds to a click. Create the button in XAML.

Or create the button in code.

Button submitButton = new Button(); submitButton.Content = "Submit"; submitButton.Click += SubmitButton_Click; // Add the button to a parent container in the visual tree. stackPanel1.Children.Add(submitButton);

Handle the Click event. private async void SubmitButton_Click(object sender, RoutedEventArgs e) { // Call app specific code to submit form. For example: // form.Submit(); Windows.UI.Popups.MessageDialog messageDialog = new Windows.UI.Popups.MessageDialog("Thank you for your submission."); await messageDialog.ShowAsync(); }

Button interaction

When you tap a Button with a finger or stylus, or press a left mouse button while the pointer is over it, the button raises the Click event. If a button has keyboard focus, pressing the Enter key or the Spacebar key also raises the Click event. You generally can't handle low-level PointerPressed events on a Button because it has the Click behavior instead. For more info, see Events and routed events overview. You can change how a button raises the Click event by changing the ClickMode property. The default ClickMode value is Release. If ClickMode is Hover, the Click event can't be raised with the keyboard or touch. Button content

Button is a ContentControl. Its XAML content property is Content, which enables a syntax like this for XAML: A button's content . You can set any object as the button's content. If the content is a UIElement, it is rendered in the button. If the content is another type of object, its string representation is shown in the button. Here, a StackPanel that contains an image of an orange and text is set as the content of a button.

The button looks like this.

Create a repeat button

A RepeatButton is a button that raises Click events repeatedly from the time it's pressed until it's released. Set the Delay property to specify the time that the RepeatButton waits after it is pressed before it starts repeating the click action. Set the Interval property to specify the time between repetitions of the click action. Times for both properties are specified in milliseconds. The following example shows two RepeatButton controls whose respective Click events are used to increase and decrease the value shown in a text block. Increase Decrease

private static int _clicks = 0; private void Increase_Click(object sender, RoutedEventArgs e) { _clicks += 1; clickTextBlock.Text = "Number of Clicks: " + _clicks; } private void Decrease_Click(object sender, RoutedEventArgs e) { if(_clicks > 0) { _clicks -= 1; clickTextBlock.Text = "Number of Clicks: " + _clicks; } }

Recommendations Make sure the purpose and state of a button are clear to the user. Use a concise, specific, self-explanatory text that clearly describes the action that the button performs. Usually button text content is a single word, a verb. When there are multiple buttons for the same decision (such as in a confirmation dialog), present the commit buttons in this order: OK/[Do it]/Yes [Don't do it]/No Cancel (where [Do it] and [Don't do it] are specific responses to the main instruction.) If the button's text content is dynamic, for example, it is localized, consider how the button will resize and what will happen to controls around it. For command buttons with text content, use a minimum button width. Avoid narrow, short, or tall command buttons with text content. Use the default font unless your brand guidelines tell you to use something different. For an action that needs to be available across multiple pages within your app, instead of duplicating a button on multiple pages, consider using a bottom app bar. Expose only one or two buttons to the user at a time, for example, Accept and Cancel. If you need to expose more actions to the user, consider using checkboxes or radio buttons from which the user can select actions, with a single command button to trigger those actions. Use the default command button to indicate the most common or recommended action.

Consider customizing your buttons. A button's shape is rectangular by default, but you can customize the visuals that make up the button's appearance. A button's content is usually text—for example, Accept or Cancel —but you could replace the text with an icon, or use an icon plus text. Make sure that as the user interacts with a button, the button changes state and appearance to provide feedback to the user. Normal, pressed, and disabled are examples of button states. Trigger the button's action when the user taps or presses the button. Usually the action is triggered when the user releases the button, but you also can set a button's action to trigger when a finger first presses it. Don't use a command button to set state. Don't change button text while the app is running; for example, don't change the text of a button that says "Next" to "Continue". Don't swap the default submit, reset, and button styles. Don't put too much content inside a button. Make the content concise and easy to understand (nothing more than a picture and some text).

Back buttons The back button is a system-provided UI element that enables backward navigation through either the back stack or navigation history of the user. You don't have to create your own back button, but you might have to do some work to enable a good backwards navigation experience. For more info, see History and backwards navigation

Get the sample code XAML UI basics sample See all of the XAML controls in an interactive format.

Related articles Radio buttons Toggle switches Check boxes Button class

Check boxes 3/6/2017 • 7 min to read • Edit on GitHub

A check box is used to select or deselect action items. It can be used for a single item or for a list of multiple items that a user can choose from. The control has three selection states: unselected, selected, and indeterminate. Use the indeterminate state when a collection of sub-choices have both unselected and selected states.

Important APIs CheckBox class Checked event IsChecked property

Is this the right control? Use a single check box for a binary yes/no choice, such as with a "Remember me?" login scenario or with a terms of service agreement.

For a binary choice, the main difference between a check box and a toggle switch is that the check box is for status and the toggle switch is for action. You can delay committing a check box interaction (as part of a form submit, for example), while you should immediately commit a toggle switch interaction. Also, only check boxes allow for multi-selection. Use multiple check boxes for multi-select scenarios in which a user chooses one or more items from a group of choices that are not mutually exclusive. Create a group of check boxes when users can select any combination of options.

When options can be grouped, you can use an indeterminate check box to represent the whole group. Use the check box's indeterminate state when a user selects some, but not all, sub-items in the group.

Both check box and radio button controls let the user select from a list of options. Check boxes let the user select a combination of options. In contrast, radio buttons let the user make a single choice from mutually exclusive options. When there is more than one option but only one can be selected, use a radio button instead.

Examples A check box in a dialog in the Microsoft Edge browser.

Check boxes in the Alarms & Clock app in Windows.

Create a checkbox To assign a label to the checkbox, set the Content property. The label displays next to the checkbox. This XAML creates a single check box that is used to agree to terms of service before a form can be submitted.

Here's the same check box created in code. CheckBox checkBox1 = new CheckBox(); checkBox1.Content = "I agree to the terms of service.";

Bind to IsChecked

Use the IsChecked property to determine whether the check box is checked or cleared. You can bind the value of the IsChecked property to another binary value. However, because IsChecked is a nullable boolean value, you must use a value converter to bind it to a boolean value. In this example, the IsChecked property of the check box to agree to terms of service is bound to the IsEnabled property of a Submit button. The Submit button is enabled only if the terms of service are agreed to. Note We only show the relevant code here. For more info about data binding and value converters, see Data binding overview.

... ...

public class NullableBooleanToBooleanConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { if (value is bool?) { return (bool)value; } return false; } public object ConvertBack(object value, Type targetType, object parameter, string language) { if (value is bool) return (bool)value; return false; } }

Handle Click and Checked events

To perform an action when the check box state changes, you can handle either the Click event, or the Checked and Unchecked events. The Click event occurs whenever the checked state changes. If you handle the Click event, use the IsChecked property to determine the state of the check box. The Checked and Unchecked events occur independently. If you handle these events, you should handle both of them to repsond to state changes in the check box. In the following examples, we show handling the Click event, and the Checked and Unchecked events. Multiple checkboxes can share the same event handler. This example creates four checkboxes for selecting pizza toppings. The four checkboxes share the same Click event handler to update the list of selected toppings.



Here's the event handler for the Click event. Every time a checkbox is clicked, it examines the checkboxes to see which ones are checked and update list of selected toppings. private void toppingsCheckbox_Click(object sender, RoutedEventArgs e) { string selectedToppingsText = string.Empty; CheckBox[] checkboxes = new CheckBox[] { pepperoniCheckbox, beefCheckbox, mushroomsCheckbox, onionsCheckbox }; foreach (CheckBox c in checkboxes) { if (c.IsChecked == true) { if (selectedToppingsText.Length > 1) { selectedToppingsText += ", "; } selectedToppingsText += c.Content; } } toppingsList.Text = selectedToppingsText; }

Use the indeterminate state

The CheckBox control inherits from ToggleButton and can have three states: STATE

PROPERTY

VALUE

checked

IsChecked

true

unchecked

IsChecked

false

indeterminate

IsChecked

null

For the check box to report the indeterminate state, you must set the IsThreeState property to true. When options can be grouped, you can use an indeterminate check box to represent the whole group. Use the check box's indeterminate state when a user selects some, but not all, sub-items in the group. In the following example, the "Select all" checkbox has its IsThreeState property set to true. The "Select all" checkbox is checked if all child elements are checked, unchecked if all child elements are unchecked, and indeterminate otherwise.



private void Option_Checked(object sender, RoutedEventArgs e) { SetCheckedState(); } private void Option_Unchecked(object sender, RoutedEventArgs e) { SetCheckedState(); } private void SelectAll_Checked(object sender, RoutedEventArgs e) { Option1CheckBox.IsChecked = Option2CheckBox.IsChecked = Option3CheckBox.IsChecked = true; } private void SelectAll_Unchecked(object sender, RoutedEventArgs e) { Option1CheckBox.IsChecked = Option2CheckBox.IsChecked = Option3CheckBox.IsChecked = false; } private void SelectAll_Indeterminate(object sender, RoutedEventArgs e) { // If the SelectAll box is checked (all options are selected), // clicking the box will change it to its indeterminate state. // Instead, we want to uncheck all the boxes, // so we do this programatically. The indeterminate state should // only be set programatically, not by the user. if (Option1CheckBox.IsChecked == true && Option2CheckBox.IsChecked == true && Option3CheckBox.IsChecked == true) { // This will cause SelectAll_Unchecked to be executed, so // we don't need to uncheck the other boxes here. OptionsAllCheckBox.IsChecked = false; } } private void SetCheckedState() { // Controls are null the first time this is called, so we just // need to perform a null check on any one of the controls. if (Option1CheckBox != null) { if (Option1CheckBox.IsChecked == true && Option2CheckBox.IsChecked == true && Option3CheckBox.IsChecked == true) { OptionsAllCheckBox.IsChecked = true; } else if (Option1CheckBox.IsChecked == false && Option2CheckBox.IsChecked == false && Option3CheckBox.IsChecked == false) { OptionsAllCheckBox.IsChecked = false; } else { // Set third state (indeterminate) by setting IsChecked to null. OptionsAllCheckBox.IsChecked = null; } } }

Do's and don'ts

Verify that the purpose and current state of the check box is clear. Limit check box text content to no more than two lines. Word the checkbox label as a statement that the check mark makes true and the absence of a check mark makes false. Use the default font unless your brand guidelines tell you to use another. If the text content is dynamic, consider how the control will resize and what will happen to visuals around it. If there are two or more mutually exclusive options from which to choose, consider using radio buttons. Don't put two check box groups next to each other. Use group labels to separate the groups. Don't use a check box as an on/off control or to perform a command; instead, use a toggle switch. Don't use a check box to display other controls, such as a dialog box. Use the indeterminate state to indicate that an option is set for some, but not all, sub-choices. When using indeterminate state, use subordinate check boxes to show which options are selected and which are not. Design the UI so that the user can get see the sub-choices. Don't use the indeterminate state to represent a third state. The indeterminate state is used to indicate that an option is set for some, but not all, sub-choices. So, don't allow users to set an indeterminate state directly. For an example of what not to do, this check box uses the indeterminate state to indicate medium spiciness:

Instead, use a radio button group that has three options: Not spicy, Spicy, and Extra spicy.

Related articles CheckBox class Radio buttons Toggle switch

Calendar, date, and time controls 3/6/2017 • 4 min to read • Edit on GitHub

Date and time controls give you standard, localized ways to let a user view and set date and time values in your app. This article provides design guidelines and helps you pick the right control. Important APIs CalendarView class CalendarDatePicker class DatePicker class TimePicker class

Which date or time control should you use? There are four date and time controls to choose from; the control you use depends on your scenario. Use this info to pick the right control to use in your app.

Calendar view

Use to pick a single date or a range of dates from an always visible calendar.

Calendar date picker

Use to pick a single date from a contextual calendar.

Date picker

Use to pick a single known date when contextual info isn't important.

Time picker

Use to pick a single time value.

Calendar view

CalendarView lets a user view and interact with a calendar that they can navigate by month, year, or decade. A user can select a single date or a range of dates. It doesn't have a picker surface and the calendar is always visible. The calendar view is made up of 3 separate views: the month view, year view, and decade view. By default, it

starts with the month view open, but you can specify any view as the startup view.

If you need to let a user select multiple dates, you must use a CalendarView. If you need to let a user pick only a single date and don’t need a calendar to be always visible, consider using a CalendarDatePicker or DatePicker control. Calendar date picker

CalendarDatePicker is a drop down control that’s optimized for picking a single date from a calendar view where contextual information like the day of the week or fullness of the calendar is important. You can modify the calendar to provide additional context or to limit available dates. The entry point displays placeholder text if a date has not been set; otherwise, it displays the chosen date. When the user selects the entry point, a calendar view expands for the user to make a date selection. The calendar view overlays other UI; it doesn't push other UI out of the way.

Use a calendar date picker for things like choosing an appointment or departure date. Date picker

The DatePicker control provides a standardized way to choose a specific date. The entry point displays the chosen date, and when the user selects the entry point, a picker surface expands vertically from the middle for the user to make a selection. The date picker overlays other UI; it doesn't push other UI out of the way.

Use a date picker to let a user pick a known date, such as a date of birth, where the context of the calendar is not important. Time picker

The TimePicker is used to select a single time value for things like appointments or a departure time. It's a static display that is set by the user or in code, but it doesn't update to display the current time. The entry point displays the chosen time, and when the user selects the entry point, a picker surface expands vertically from the middle for the user to make a selection. The time picker overlays other UI; it doesn't push other UI out of the way.

Use a time picker to let a user pick a single time value.

Create a date or time control See these articles for info and examples specific to each date and time control. Calendar view Calendar date picker Date picker Time Picker Globalization

The XAML date controls support each of the calendar systems supported by Windows. These calendars are specified in the Windows.Globalization.CalendarIdentifiers class. Each control uses the correct calendar for your app's default language, or you can set the CalendarIdentifier property to use a specific calendar system. The time picker control supports each of the clock systems specified in the

Windows.Globalization.ClockIdentifiers class. You can set the ClockIdentifier property to use either a 12hour clock or 24-hour clock. The type of the property is String, but you must use values that correspond to the static string properties of the ClockIdentifiers class. These are: TwelveHour (the string "12HourClock")and TwentyFourHour (the string "24HourClock"). "12HourClock" is the default value. DateTime and Calendar values

The date objects used in the XAML date and time controls have a different representation depending on your programming language. C# and Visual Basic use the System.DateTimeOffset structure that is part of .NET. C++/CX uses the Windows::Foundation::DateTime structure. A related concept is the Calendar class, which influences how dates are interpreted in context. All Windows Runtime apps can use the Windows.Globalization.Calendar class. C# and Visual Basic apps can alternatively use the System.Globalization.Calendar class, which has very similar functionality. (Windows Runtime apps can use the base .NET Calendar class but not the specific implementations; for example, GregorianCalendar.) .NET also supports a type named DateTime, which is implicitly convertible to a DateTimeOffset. So you might see a "DateTime" type being used in .NET code that's used to set values that are really DateTimeOffset. For more info on the difference between DateTime and DateTimeOffset, see Remarks in the DateTimeOffset class. Note Properties that take date objects can't be set as a XAML attribute string, because the Windows Runtime XAML parser doesn't have a conversion logic for converting strings to dates as DateTime/DateTimeOffset objects. You typically set these values in code. Another possible technique is to define a date that's available as a data object or in the data context, then set the property as a XAML attribute that references a {Binding} markup extension expression that can access the date as data.

Get the sample code XAML UI basics sample

Related topics For developers (XAML) CalendarView class CalendarDatePicker class DatePicker class TimePicker class

Calendar date picker 3/6/2017 • 2 min to read • Edit on GitHub

The calendar date picker is a drop down control that’s optimized for picking a single date from a calendar view where contextual information like the day of the week or fullness of the calendar is important. You can modify the calendar to provide additional context or to limit available dates. Important APIs CalendarDatePicker class Date property DateChanged event

Is this the right control? Use a calendar date picker to let a user pick a single date from a contextual calendar view. Use it for things like choosing an appointment or departure date. To let a user pick a known date, such as a date of birth, where the context of the calendar is not important, consider using a date picker. For more info about choosing the right control, see the Date and time controls article.

Examples The entry point displays placeholder text if a date has not been set; otherwise, it displays the chosen date. When the user selects the entry point, a calendar view expands for the user to make a date selection. The calendar view overlays other UI; it doesn't push other UI out of the way.

Create a date picker

CalendarDatePicker arrivalCalendarDatePicker = new CalendarDatePicker(); arrivalCalendarDatePicker.Header = "Arrival date";

The resulting calendar date picker looks like this:

The calendar date picker has an internal CalendarView for picking a date. A subset of CalendarView properties, like IsTodayHighlighted and FirstDayOfWeek, exist on CalendarDatePicker and are forwarded to the internal CalendarView to let you modify it. However, you can't change the SelectionMode of the internal CalendarView to allow multiple selection. If you need to let a user pick multiple dates or need a calendar to be always visible, consider using a calendar view instead of a calendar date picker. See the Calendar view article for more info on how you can modify the calendar display. Selecting dates

Use the Date property to get or set the selected date. By default, the Date property is null. When a user selects a date in the calendar view, this property is updated. A user can clear the date by clicking the selected date in the calendar view to deselect it. You can set the date in your code like this. myCalendarDatePicker.Date = new DateTime(1977, 1, 5);

When you set the Date in code, the value is constrained by the MinDate and MaxDate properties. If Date is smaller than MinDate, the value is set to MinDate. If Date is greater than MaxDate, the value is set to MaxDate. You can handle the DateChanged event to be notified when the Date value has changed. NOTE For important info about date values, see DateTime and Calendar values in the Date and time controls article.

Setting a header and placeholder text

You can add a Header (or label) and PlaceholderText (or watermark) to the calendar date picker to give the user an indication of what it's used for. To customize the look of the header, you can set the HeaderTemplate property instead of Header. The default placeholder text is "select a date". You can remove this by setting the PlaceholderText property to an empty string, or you can provide custom text as shown here.

Get the sample code XAML UI basics sample

Related articles Date and time controls Calendar view Date picker Time picker

Calendar view 3/6/2017 • 6 min to read • Edit on GitHub

A calendar view lets a user view and interact with a calendar that they can navigate by month, year, or decade. A user can select a single date or a range of dates. It doesn't have a picker surface and the calendar is always visible. Important APIs CalendarView class SelectedDatesChanged event

Is this the right control? Use a calendar view to let a user pick a single date or a range of dates from an always visible calendar. If you need to let a user select multiple dates at one time, you must use a calendar view. If you need to let a user pick only a single date and don’t need a calendar to be always visible, consider using a calendar date picker or date picker control. For more info about choosing the right control, see the Date and time controls article.

Examples The calendar view is made up of 3 separate views: the month view, year view, and decade view. By default, it starts with the month view open. You can specify a startup view by setting the DisplayMode property.

Users click the header in the month view to open the year view, and click the header in the year view to open the decade view. Users pick a year in the decade view to return to the year view, and pick a month in the year view to return to the month view. The two arrows to the side of the header navigate forward or backward by month, by year, or by decade.

Create a calendar view This example shows how to create a simple calendar view.

The resulting calendar view looks like this:

Selecting dates

By default, the SelectionMode property is set to Single. This lets a user pick a single date in the calendar. Set SelectionMode to None to disable date selection. Set SelectionMode to Multiple to let a user select multiple dates. You can select multiple dates programmatically by adding DateTime/DateTimeOffset objects to the SelectedDates collection, as shown here: calendarView1.SelectedDates.Add(DateTimeOffset.Now); calendarView1.SelectedDates.Add(new DateTime(1977, 1, 5));

A user can deselect a selected date by clicking or tapping it in the calendar grid. You can handle the SelectedDatesChanged event to be notified when the SelectedDates collection has changed. NOTE For important info about date values, see DateTime and Calendar values in the Date and time controls article.

Customizing the calendar view's appearance

The calendar view is composed of both XAML elements defined in the ControlTemplate and visual elements rendered directly by the control. The XAML elements defined in the control template include the border that encloses the control, the header, previous and next buttons, and DayOfWeek elements. You can style and re-template these elements like any XAML control. The calendar grid is composed of CalendarViewDayItem objects. You can’t style or re-template these elements, but various properties are provided to let you to customize their appearance. This diagram shows the elements that make up the month view of the calendar. For more info, see the Remarks on the CalendarViewDayItem class.

This table lists the properties you can change to modify the appearance of calendar elements. ELEMENT

PROPERTIES

DayOfWeek

DayOfWeekFormat

CalendarItem

CalendarItemBackground, CalendarItemBorderBrush, CalendarItemBorderThickness, CalendarItemForeground

DayItem

DayItemFontFamily, DayItemFontSize, DayItemFontStyle, DayItemFontWeight, HorizontalDayItemAlignment, VerticalDayItemAlignment, CalendarViewDayItemStyle

MonthYearItem (in the year and decade views, equivalent to DayItem)

MonthYearItemFontFamily, MonthYearItemFontSize, MonthYearItemFontStyle, MonthYearItemFontWeight

FirstOfMonthLabel

FirstOfMonthLabelFontFamily, FirstOfMonthLabelFontSize, FirstOfMonthLabelFontStyle, FirstOfMonthLabelFontWeight, HorizontalFirstOfMonthLabelAlignment, VerticalFirstOfMonthLabelAlignment, IsGroupLabelVisible

FirstofYearDecadeLabel (in the year and decade views, equivalent to FirstOfMonthLabel)

FirstOfYearDecadeLabelFontFamily, FirstOfYearDecadeLabelFontSize, FirstOfYearDecadeLabelFontStyle, FirstOfYearDecadeLabelFontWeight

Visual State Borders

FocusBorderBrush, HoverBorderBrush, PressedBorderBrush, SelectedBorderBrush, SelectedForeground, SelectedHoverBorderBrush, SelectedPressedBorderBrush

OutofScope

IsOutOfScopeEnabled, OutOfScopeBackground, OutOfScopeForeground

Today

IsTodayHighlighted, TodayFontWeight, TodayForeground

By default, the month view shows 6 weeks at a time. You can change the number of weeks shown by setting the NumberOfWeeksInView property. The minimum number of weeks to show is 2; the maximum is 8. By default, the year and decade views show in a 4x4 grid. To change the number of rows or columns, call SetYearDecadeDisplayDimensions with the your desired number of rows and columns. This will change the grid for both the year and decade views.

Here, the year and decade views are set to show in a 3x4 grid. calendarView1.SetYearDecadeDisplayDimensions(3, 4);

By default, the minimum date shown in the calendar view is 100 years prior to the current date, and the maximum date shown is 100 years past the current date. You can change the minimum and maximum dates that the calendar shows by setting the MinDate and MaxDate properties. calendarView1.MinDate = new DateTime(2000, 1, 1); calendarView1.MaxDate = new DateTime(2099, 12, 31);

Updating calendar day items

Each day in the calendar is represented by a CalendarViewDayItem object. To access an individual day item and use its properties and methods, handle the CalendarViewDayItemChanging event and use the Item property of the event args to access the CalendarViewDayItem. You can make a day not selectable in the calendar view by setting its CalendarViewDayItem.IsBlackout property to true. You can show contextual information about the density of events in a day by calling the CalendarViewDayItem.SetDensityColors method. You can show from 0 to 10 density bars for each day, and set the color of each bar. Here are some day items in a calendar. Days 1 and 2 are blacked out. Days 2, 3, and 4 have various density bars set.

Phased rendering

A calendar view can contain a large number of CalendarViewDayItem objects. To keep the UI responsive and enable smooth navigation through the calendar, calendar view supports phased rendering. This lets you break up processing of a day item into phases. If a day is moved out of view before all the phases are complete, no more time is used trying to process and render that item. This example shows phased rendering of a calendar view for scheduling appointments. In phase 0, the default day item is rendered. In phase 1, you blackout dates that can't be booked. This includes past dates, Sundays, and dates that are already fully booked. In phase 2, you check each appointment that's booked for the day. You show a green density bar for each confirmed appointment and a blue density bar for each tentative appointment. The

Bookings

class in this example is from a fictitious appointment booking app, and is not shown.



private void CalendarView_CalendarViewDayItemChanging(CalendarView sender, CalendarViewDayItemChangingEventArgs args) { // Render basic day items. if (args.Phase == 0) { // Register callback for next phase. args.RegisterUpdateCallback(CalendarView_CalendarViewDayItemChanging); } // Set blackout dates. else if (args.Phase == 1) { // Blackout dates in the past, Sundays, and dates that are fully booked. if (args.Item.Date < DateTimeOffset.Now || args.Item.Date.DayOfWeek == DayOfWeek.Sunday || Bookings.HasOpenings(args.Item.Date) == false) { args.Item.IsBlackout = true; } // Register callback for next phase. args.RegisterUpdateCallback(CalendarView_CalendarViewDayItemChanging); } // Set density bars. else if (args.Phase == 2) { // Avoid unnecessary processing. // You don't need to set bars on past dates or Sundays. if (args.Item.Date > DateTimeOffset.Now && args.Item.Date.DayOfWeek != DayOfWeek.Sunday) { // Get bookings for the date being rendered. var currentBookings = Bookings.GetBookings(args.Item.Date); List densityColors = new List(); // Set a density bar color for each of the days bookings. // It's assumed that there can't be more than 10 bookings in a day. Otherwise, // further processing is needed to fit within the max of 10 density bars. foreach (booking in currentBookings) { if (booking.IsConfirmed == true) { densityColors.Add(Colors.Green); } else { densityColors.Add(Colors.Blue); } } args.Item.SetDensityColors(densityColors); } } }

Related articles Date and time controls Calendar date picker Date picker Time picker

Date picker 3/6/2017 • 1 min to read • Edit on GitHub

The date picker gives you a standardized way to let users pick a localized date value using touch, mouse, or keyboard input. Important APIs DatePicker class Date property

Is this the right control? Use a date picker to let a user pick a known date, such as a date of birth, where the context of the calendar is not important. For more info about choosing the right date control, see the Date and time controls article.

Examples The entry point displays the chosen date, and when the user selects the entry point, a picker surface expands vertically from the middle for the user to make a selection. The date picker overlays other UI; it doesn't push other UI out of the way.

Create a date picker This example shows how to create a simple date picker with a header.

DatePicker birthDatePicker = new DatePicker(); birthDatePicker.Header = "Date of birth";

The resulting date picker looks like this:

Note For important info about date values, see DateTime and Calendar values in the Date and time controls article.

Related articles Date and time controls Calendar date picker Calendar view Time picker

Time picker 3/6/2017 • 1 min to read • Edit on GitHub

The time picker gives you a standardized way to let users pick a time value using touch, mouse, or keyboard input. Important APIs TimePicker class Time property

Is this the right control? Use a time picker to let a user pick a single time value. For more info about choosing the right control, see the Date and time controls article.

Examples The entry point displays the chosen time, and when the user selects the entry point, a picker surface expands vertically from the middle for the user to make a selection. The time picker overlays other UI; it doesn't push other UI out of the way.

Create a time picker This example shows how to create a simple time picker with a header.

TimePicker arrivalTimePicker = new TimePicker(); arrivalTimePicker.Header = "Arrival time";

The resulting time picker looks like this:

NOTE For important info about date and time values, see DateTime and Calendar values in the Date and time controls article.

Related topics Date and time controls Calendar date picker Calendar view Date picker

Dialogs and flyouts 3/6/2017 • 9 min to read • Edit on GitHub

Dialogs and flyouts are transient UI elements that appear when something happens that requires notification, approval, or additional information from the user. Important APIs ContentDialog class Flyout class

Dialogs

Dialogs are modal UI overlays that provide contextual app information. Dialogs block interactions with the app window until being explicitly dismissed. They often request some kind of action from the user.

Flyouts

A flyout is a lightweight contextual popup that displays UI related to what the user is doing. It includes placement and sizing logic, and can be used to reveal a hidden control, show more detail about an item, or ask the user to confirm an action. Unlike a dialog, a flyout can be quickly dismissed by tapping or clicking somewhere outside the flyout, pressing the Escape key or Back button, resizing the app window, or changing the device's orientation.

Is this the right control? Use dialogs and flyouts to notify users of important information or to request confirmation or additional info before an action can be completed.

Don't use a flyout instead of tooltip or context menu. Use a tooltip to show a short description that hides after a specified time. Use a context menu for contextual actions related to a UI element, such as copy and paste. Dialogs and flyouts make sure that users are aware of important information, but they also disrupt the user experience. Because dialogs are modal (blocking), they interupt users, preventing them from doing anything else until they interact with the dialog. Flyouts provide a less jarring experience, but displaying too many flyouts can be distracting. Consider the importance of the information you want to share: is it important enough to interupt the user? Also consider how frequently the information needs to be shown; if you're showing a dialog or notification every few minutes, you might want to allocate space for this info in the primary UI instead. For example, in a chat client, rather than showing a flyout every time a friend logs in, you might display a list of friends who are online at the moment and highlight friends as they log on. Flyouts and dialogs are frequently used to confirm an action (such as deleting a file) before executing it. If you expect the user to perform a particular action frequently, consider providing a way for the user to undo the action if it was a mistake, rather than forcing users to confirm the action every time.

Dialogs vs. flyouts Once you've determined that you want to use a dialog or flyout, you need to choose which one to use. Given that dialogs block interactions and flyouts do not, dialogs should be reserved for situations where you want the user to drop everything to focus on a specific bit of information or answer a question. Flyouts, on the other hand, can be used when you want to call attention to something, but it's ok if the user wants to ignore it. Use a dialog for... Expressing important information that the user must read and acknowledge before proceeding. Examples include: When the user's security might be compromised When the user is about to permanently alter a valuable asset When the user is about to delete a valuable asset To confirm an in-app purchase Error messages that apply to the overall app context, such as a connectivity error. Questions, when the app needs to ask the user a blocking question, such as when the app can't choose on the user's behalf. A blocking question can't be ignored or postponed, and should offer the user well-defined choices.

Use a flyout for... Collecting additional information needed before an action can be completed. Displaying info that's only relevent some of the time. For example, in a photo gallery app, when the user clicks an image thumbnail, you might use a flyout to display a large version of the image. Warnings and confirmations, including ones related to potentially destructive actions. Displaying more information, such as details or longer descriptions of an item on the page.

Dialogs General guidelines

Clearly identify the issue or the user's objective in the first line of the dialog's text.

The dialog title is the main instruction and is optional. Use a short title to explain what people need to do with the dialog. Long titles do not wrap and are truncated. If you're using the dialog to deliver a simple message, error or question, you can optionally omit the title. Rely on the content text to deliver that core information. Make sure that the title relates directly to the button choices. The dialog content contains the descriptive text and is required. Present the message, error, or blocking question as simply as possible. If a dialog title is used, use the content area to provide more detail or define terminology. Don't repeat the title with slightly different wording. At least one dialog button must appear. Buttons are the only mechanism for users to dismiss the dialog. Use buttons with text that identifies specific responses to the main instruction or content. An example is, "Do you want to allow AppName to access your location?", followed by "Allow" and "Block" buttons. Specific responses can be understood more quickly, resulting in efficient decision making. Present the commit buttons in this order: OK/[Do it]/Yes [Don't do it]/No Cancel (where [Do it] and [Don't do it] are specific responses to the main instruction.) Error dialogs display the error message in the dialog box, along with any pertinent information. The only button used in an error dialog should be “Close” or a similar action. Don't use dialogs for errors that are contextual to a specific place on the page, such as validation errors (in password fields, for example), use the app's canvas itself to show inline errors. Confirmation dialogs (OK/Cancel)

A confirmation dialog gives users the chance to confirm that they want to perform an action. They can affirm the action, or choose to cancel. A typical confirmation dialog has two buttons: an affirmation ("OK") button and a cancel button. In general, the affirmation button should be on the left (the primary button) and the cancel button (the secondary button) should be on the right.

As noted in the general recommendations section, use buttons with text that identifies specific responses to the main instruction or content. Some platforms put the affirmation button on the right instead of the left. So why do we recommend putting it on the left? If you assume that the majority of users are right-handed and they hold their phone with that hand, it's actually more comfortable to press the affirmation button when it's on the left, because the button is more likely to be within the user's thumb-arc. Buttons on the right-side of the screen require the user to pull their thumb inward into an less-comfortable position.

Create a dialog

To create a dialog, you use the ContentDialog class. You can create a dialog in code or markup. Although its usually easier to define UI elements in XAML, in the case of a simple dialog, it's actually easier to just use code. This example creates a dialog to notify the user that there's no WiFi connection, and then uses the ShowAsync method to display it. private async void displayNoWifiDialog() { ContentDialog noWifiDialog = new ContentDialog() { Title = "No wifi connection", Content = "Check connection and try again", PrimaryButtonText = "Ok" }; ContentDialogResult result = await noWifiDialog.ShowAsync(); }

When the user clicks a dialog button, the ShowAsync method returns a ContentDialogResult to let you know which button the user clicks. The dialog in this example asks a question and uses the returned ContentDialogResult to determine the user's response. private async void displayDeleteFileDialog() { ContentDialog deleteFileDialog = new ContentDialog() { Title = "Delete file permanently?", Content = "If you delete this file, you won't be able to recover it. Do you want to delete it?", PrimaryButtonText = "Delete", SecondaryButtonText = "Cancel" }; ContentDialogResult result = await deleteFileDialog.ShowAsync(); // Delete the file if the user clicked the primary button. /// Otherwise, do nothing. if (result == ContentDialogResult.Primary) { // Delete the file. } }

Flyouts Create a flyout

A flyout is an open-ended container that can show arbitrary UI as its content. Flyouts are attached to specific controls. You can use the Placement property to specify where flyout appears: Top, Left, Bottom, Right, or Full. If you select the Full placement mode, the app stretches the flyout and centers it inside the app window. When visible, they should be anchored to the invoking object and specify their preferred relative position to the object: Top, Left, Bottom, or Right. Flyout also has a Full placement mode which attempts to stretch the flyout and center it inside the app window. Some controls, such as Button, provide a Flyout property that you can use to associate a flyout. This example creates a simple flyout that displays some text when the button is pressed.



If the control doesn't have a flyout property, you can use the FlyoutBase.AttachedFlyout attached property instead. When you do this, you also need to call the FlyoutBase.ShowAttachedFlyout method to show the flyout. This example adds a simple flyout to an image. When the user taps the image, the app shows the flyout.

private void Image_Tapped(object sender, TappedRoutedEventArgs e) { FlyoutBase.ShowAttachedFlyout((FrameworkElement)sender); }

The previous examples defined their flyouts inline. You can also define a flyout as a static resource and then use it with multiple elements. This example creates a more complicated flyout that displays a larger version of an image when its thumbnail is tapped.



private void Image_Tapped(object sender, TappedRoutedEventArgs e) { FlyoutBase.ShowAttachedFlyout((FrameworkElement)sender); }

Style a flyout

To style a Flyout, modify its FlyoutPresenterStyle. This example shows a paragraph of wrapping text and makes the text block accessible to a screen reader.

Get the samples XAML UI basics See all of the XAML controls in an interactive format.

Related articles Tooltips Menus and context menu Flyout class ContentDialog class

Flip view 3/6/2017 • 6 min to read • Edit on GitHub

Use a flip view for browsing images or other items in a collection, such as photos in an album or items in a product details page, one item at a time. For touch devices, swiping across an item moves through the collection. For a mouse, navigation buttons appear on mouse hover. For a keyboard, arrow keys move through the collection. Important APIs FlipView class ItemsSource property ItemTemplate property

Is this the right control? Flip view is best for perusing images in small to medium collections (up to 25 or so items). Examples of such collections include items in a product details page or photos in a photo album. Although we don't recommend flip view for most large collections, the control is common for viewing individual images in a photo album.

Examples Horizontal browsing, starting at the left-most item and flipping right, is the typical layout for a flip view. This layout works well in either portrait or landscape orientation on all devices:

A flip view can also be browsed vertically:

Create a flip view

FlipView is an ItemsControl, so it can contain a collection of items of any type. To populate the view, add items to the Items collection, or set the ItemsSource property to a data source. By default, a data item is displayed in the flip view as the string representation of the data object it's bound to. To specify exactly how items in the flip view are displayed, you create a DataTemplate to define the layout of controls used to display an individual item. The controls in the layout can be bound to properties of a data object, or have content defined inline. You assign the DataTemplate to the ItemTemplate property of the FlipView. Add items to the Items collection

You can add items to the Items collection using XAML or code. You typically add items this way if you have a small number of items that don't change and are easily defined in XAML, or if you generate the items in code at run time. Here's a flip view with items defined inline.

// Create a new flip view, add content, // and add a SelectionChanged event handler. FlipView flipView1 = new FlipView(); flipView1.Items.Add("Item 1"); flipView1.Items.Add("Item 2"); // Add the flip view to a parent container in the visual tree. stackPanel1.Children.Add(flipView1);

When you add items to a flip view they are automatically placed in a FlipViewItem container. To change how an item is displayed you can apply a style to the item container by setting the ItemContainerStyle property. When you define the items in XAML, they are automatically added to the Items collection. Set the items source

You typically use a flip view to display data from a source such as a database or the Internet. To populate a flip view from a data source, you set its ItemsSource property to a collection of data items. Here, the flip view's ItemsSource is set in code directly to an instance of a collection. // Data source. List itemsList = new List(); itemsList.Add("Item 1"); itemsList.Add("Item 2"); // Create a new flip view, add content, // and add a SelectionChanged event handler. FlipView flipView1 = new FlipView(); flipView1.ItemsSource = itemsList; flipView1.SelectionChanged += FlipView_SelectionChanged; // Add the flip view to a parent container in the visual tree. stackPanel1.Children.Add(flipView1);

You can also bind the ItemsSource property to a collection in XAML. For more info, see Data binding with XAML. Here, the ItemsSource is bound to a CollectionViewSource named

itemsViewSource

.

...

Note You can populate a flip view either by adding items to its Items collection, or by setting its ItemsSource property, but you can't use both ways at the same time. If you set the ItemsSource property and you add an item in XAML, the added item is ignored. If you set the ItemsSource property and you add an item to the Items collection in code, an exception is thrown. Specify the look of the items

By default, a data item is displayed in the flip view as the string representation of the data object it's bound to. You typically want to show a more rich presentation of your data. To specify exactly how items in the flip view are displayed, you create a DataTemplate. The XAML in the DataTemplate defines the layout and appearance of controls used to display an individual item. The controls in the layout can be bound to properties of a data object, or have content defined inline. The DataTemplate is assigned to the ItemTemplate property of the FlipView control. In this example, the ItemTemplate of a FlipView is defined inline. An overlay is added to the image to display the image name.

Here's what the layout defined by the data template looks like. Flip view data template. Set the orientation of the flip view

By default, the flip view flips horizontally. To make the it flip vertically, use a stack panel with a vertical orientation as the flip view's ItemsPanel. This example shows how to use a stack panel with a vertical orientation as the ItemsPanel of a FlipView.



Here's what the flip view looks like with a vertical orientation.

Adding a context indicator A context indicator in a flip view provides a useful point of reference. The dots in a standard context indicator aren't interactive. As seen in this example, the best placement is usually centered and below the gallery:

For larger collections (10-25 items), consider using an indicator that provides more context, such as a film strip of thumbnails. Unlike a context indicator that uses simple dots, each thumbnail in the film strip shows a small version of the corresponding image and should be selectable:

For example code that shows how to add a context indicator to a FlipView, see XAML FlipView sample.

Do's and don'ts Flip views work best for collections of up to 25 or so items. Avoid using a flip view control for larger collections, as the repetitive motion of flipping through each item can be tedious. An exception would be for photo albums, which often have hundreds or thousands of images. Photo albums almost always switch to a flip view once a photo has been selected in the grid view layout. For other large collections, consider a List view or grid view. For context indicators: The order of dots (or whichever visual marker you choose) works best when centered and below a horizontally-panning gallery. If you want a context indicator in a vertically-panning gallery, it works best centered and to the right of the images. The highlighted dot indicates the current item. Usually the highlighted dot is white and the other dots are gray. The number of dots can vary, but don't have so many that the user might struggle to find his or her place - 10 dots is usually the maximum number to show.

Globalization and localization checklist BI-DIRECTIONAL CONSIDERATIONS

Get the sample code XAML UI basics sample

Related articles Guidelines for lists FlipView class

Use standard mirroring for RTL languages. The back and forward controls should be based on the language's direction, so for RTL languages, the right button should navigate backwards and the left button should navigate forward.

Hub control/pattern 3/6/2017 • 3 min to read • Edit on GitHub

A hub control lets you organize app content into distinct, yet related, sections or categories. Sections in a hub are meant to be traversed in a preferred order, and can serve as the starting point for more detailed experiences.

Content in a hub can be displayed in a panoramic view that allows users to get a glimpse of what's new, what's available, and what's relevant. Hubs typically have a page header, and content sections each get a section header. Important APIs Hub class HubSection class

Is this the right control? The hub control works well for displaying large amounts of content that is arranged in a hierarchy. Hubs prioritize the browsing and discovery of new content, making them useful for displaying items in a store or a media collection. The hub control has several features that make it work well for building a content navigation pattern. Visual navigation A hub allows content to be displayed in a diverse, brief, easy-to-scan array. Categorization Each hub section allows for its content to be arranged in a logical order. Mixed content types With mixed content types, variable asset sizes and ratios are common. A hub allows each content type to be uniquely and neatly laid out in each hub section. Variable page and content widths Being a panoramic model, the hub allows for variability in its section widths. This is great for content of

different depths or quantities. Flexible architecture If you'd prefer to keep your app architecture shallow, you can fit all channel content into a hub section summary. A hub is just one of several navigation elements you can use; to learn more about navigation patterns and the other navigation elements, see the Navigation design basics for Universal Windows Platform (UWP) apps.

Hub architecture The hub control has a hierarchical navigation pattern that support apps with a relational information architecture. A hub consists of different categories of content, each of which maps to the app's section pages. Section pages can be displayed in any form that best represents the scenario and content that the section contains.

Layouts and panning/scrolling There are a number of ways to lay out and navigate content in a hub; just be sure that content lists in a hub always pan in a direction perpendicular to the direction in which the hub scrolls. Horizontal panning

Vertical panning

Horizontal panning with vertically scrolling list/grid

Vertical panning with horizontally scrolling list/grid

Examples The hub provides a great deal of design flexibility. This lets you design apps that have a wide variety of compelling and visually rich experiences. You can use a hero image or content section for the first group; a large image for the hero can be cropped both vertically and horizontally without losing the center of interest. Here is an example of a single hero image and how that image may be cropped for landscape, portrait, and narrow width.

On mobile devices, one hub section is visible at a time.

Recommendations To let users know that there's more content in a hub section, we recommend clipping the content so that a certain amount of it peeks. Based on the needs of your app, you can add several hub sections to the hub control, with each one offering its own functional purpose. For example, one section could contain a series of links and controls, while another could be a repository for thumbnails. A user can pan between these sections using the gesture support built into the hub control. Having content dynamically reflow is the best way to accommodate different window sizes. If you have many hub sections, consider adding semantic zoom. This also makes it easier to find sections when the app is resized to a narrow width. We recommend not having an item in a hub section lead to another hub; instead, you can use interactive headers to navigate to another hub section or page. The hub is a starting point and is meant to be customized to fit the needs of your app. You can change the following aspects of a hub: Number of sections Type of content in each section Placement and order of sections Size of sections Spacing between sections Spacing between a section and the top or bottom of the hub

Text style and size in headers and content Color of the background, sections, section headers, and section content

Get the sample code XAML UI basics sample

Related articles Hub class Navigation basics Using a hub XAML Hub control sample

Hyperlinks 3/6/2017 • 6 min to read • Edit on GitHub

Hyperlinks navigate the user to another part of the app, to another app, or launch a specific uniform resource identifier (URI) using a separate browser app. There are two ways that you can add a hyperlink to a XAML app: the Hyperlink text element and HyperlinkButton control.

Important APIs Hyperlink text element HyperlinkButton control

Is this the right control? Use a hyperlink when you need text that responds when selected and navigates the user to more information about the text that was selected. Choose the right type of hyperlink based on your needs: Use an inline Hyperlink text element inside of a text control. A Hyperlink element flows with other text elements and you can use it in any InlineCollection. Use a text hyperlink if you want automatic text wrapping and don't necessarily need a large hit target. Hyperlink text can be small and difficult to target, especially for touch. Use a HyperlinkButton for stand-alone hyperlinks. A HyperlinkButton is a specialized Button control that you can use anywhere that you would use a Button. Use a HyperlinkButton with an Image as its content to make a clickable image.

Examples Hyperlinks in the Calculator app.

Create a Hyperlink text element This example shows how to use a Hyperlink text element inside of a TextBlock. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Read the Contoso Privacy Statement in your browser. Donec pharetra, enim sit amet mattis tincidunt, felis nisi semper lectus, vel porta diam nisi in augue.

The hyperlink appears inline and flows with the surrounding text:

Tip When you use a Hyperlink in a text control with other text elements in XAML, place the content in a Span container and apply the xml:space="preserve" attribute to the Span to keep the white space between the Hyperlink and other elements.

Create a HyperlinkButton Here's how to use a HyperlinkButton, both with text and with an image.

The hyperlink buttons with text content appear as marked-up text. The Contoso logo image is also a clickable hyperlink:

Handle navigation For both kinds of hyperlinks, you handle navigation the same way; you can set the NavigateUri property, or handle the Click event. Navigate to a URI To use the hyperlink to navigate to a URI, set the NavigateUri property. When a user clicks or taps the hyperlink, the specified URI opens in the default browser. The default browser runs in a separate process from your app. NOTE You don't have to use http: or https: schemes. You can use schemes such as ms-appx:, ms-appdata:, or ms-resources:, if there's resource content at these locations that's appropriate to load in a browser. However, the file: scheme is specifically blocked. For more info, see URI schemes. When a user clicks the hyperlink, the value of the NavigateUri property is passed to a system handler for URI types and schemes. The system then launches the app that is registered for the scheme of the URI provided for NavigateUri.

If you don't want the hyperlink to load content in a default Web browser (and don't want a browser to appear), then don't set a value for NavigateUri. Instead, handle the Click event, and write code that does what you want. Handle the Click event Use the Click event for actions other than launching a URI in a browser, such as navigation within the app. For example, if you want to load a new app page rather than opening a browser, call a Frame.Navigate method within

your Click event handler to navigate to the new app page. If you want an external, absolute URI to load within a WebView control that also exists in your app, call WebView.Navigate as part of your Click handler logic. You don't typically handle the Click event as well as specifying a NavigateUri value, as these represent two different ways of using the hyperlink element. If your intent is to open the URI in the default browser, and you have specified a value for NavigateUri, don't handle the Click event. Conversely, if you handle the Click event, don't specify a NavigateUri. There's nothing you can do within the Click event handler to prevent the default browser from loading any valid target specified for NavigateUri; that action takes place automatically (asynchronously) when the hyperlink is activated and can't be canceled from within the Click event handler.

Hyperlink underlines By default, hyperlinks are underlined. This underline is important because it helps meet accessibility requirements. Color-blind users use the underline to distinguish between hyperlinks and other text. If you disable underlines, you should consider adding some other type of formatting difference to distinguish hyperlinks from other text, such as FontWeight or FontStyle. Hyperlink text elements You can set the UnderlineStyle property to disable the underline. If you do, consider using FontWeight or FontStyle to differentiate your link text. HyperlinkButton By default, the HyperlinkButton appears as underlined text when you set a string as the value for the Content property. The text does not appear underlined in the following cases: You set a TextBlock as the value for the Content property, and set the Text property on the TextBlock. You re-template the HyperlinkButton and change the name of the ContentPresenter template part. If you need a button that appears as non-underlined text, consider using a standard Button control and applying the built-in TextBlockButtonStyle system resource to its Style property.

Notes for Hyperlink text element This section applies only to the Hyperlink text element, not to the HyperlinkButton control. Input events Because a Hyperlink is not a UIElement, it does not have the set of UI element input events such as Tapped, PointerPressed, and so on. Instead, a Hyperlink has its own Click event, plus the implicit behavior of the system loading any URI specified as the NavigateUri. The system handles all input actions that should invoke the Hyperlink actions and raises the Click event in response. Content Hyperlink has restrictions on the content that can exist in its Inlines collection. Specifically, a Hyperlink only permits Run and other [Span]() types that aren't another Hyperlink. InlineUIContainer can't be in the Inlines collection of a Hyperlink. Attempting to add restricted content throws an invalid argument exception or XAML parse exception. Hyperlink and theme/style behavior Hyperlink doesn't inherit from Control, so it doesn't have a Style property or a Template. You can edit the properties that are inherited from TextElement, such as Foreground or FontFamily, to change the appearance of a

Hyperlink, but you can't use a common style or template to apply changes. Instead of using a template, consider using common resources for values of Hyperlink properties to provide consistency. Some properties of Hyperlink use defaults from a {ThemeResource} markup extension value provided by the system. This enables the Hyperlink appearance to switch in appropriate ways when the user changes the system theme at run-time. The default color of the hyperlink is the accent color of the system. You can set the Foreground property to override this.

Recommendations Only use hyperlinks for navigation; don't use them for other actions. Use the Body style from the type ramp for text-based hyperlinks. Read about fonts and the Windows 10 type ramp. Keep discrete hyperlinks far enough apart so that the user can differentiate between them and has an easy time selecting each one. Add tooltips to hyperlinks that indicate to where the user will be directed. If the user will be directed to an external site, include the top-level domain name inside the tooltip, and style the text with a secondary font color.

Related articles Text controls Guidelines for tooltips For developers (XAML) Windows.UI.Xaml.Documents.Hyperlink class Windows.UI.Xaml.Controls.HyperlinkButton class

Images and image brushes 3/6/2017 • 6 min to read • Edit on GitHub

To display an image, you can use either the Image object or the ImageBrush object. An Image object renders an image, and an ImageBrush object paints another object with an image. Important APIs Image class Source property ImageBrush class ImageSource property

Are these the right elements? Use an Image element to display a stand-alone image in your app. Use an ImageBrush to apply an image to another object. Uses for an ImageBrush include decorative effects for text, or backgrounds for controls or layout containers.

Create an image Image

This example shows how to create an image by using the Image object.

Here's the rendered Image object.

In this example, the Source property specifies the location of the image that you want to display. You can set the Source by specifying an absolute URL (for example, http://contoso.com/myPicture.jpg) or by specifying a URL that is relative to your app packaging structure. For our example, we put the "licorice.jpg" image file in the root folder of our project and declare project settings that include the image file as content. ImageBrush

With the ImageBrush object, you can use an image to paint an area that takes a Brush object. For example, you can use an ImageBrush for the value of the Fill property of an Ellipse or the Background property of a Canvas. The next example shows how to use an ImageBrush to paint an Ellipse.



Here's the Ellipse painted by the ImageBrush.

Stretch an image

If you don't set the Width or Height values of an Image, it is displayed with the dimensions of the image specified by the Source. Setting the Width and Height creates a containing rectangular area in which the image is displayed. You can specify how the image fills this containing area by using the Stretch property. The Stretch property accepts these values, which the Stretch enumeration defines: None: The image doesn't stretch to fill the output dimensions. Be careful with this Stretch setting: if the source image is larger than the containing area, your image will be clipped, and this usually isn't desirable because you don't have any control over the viewport like you do with a deliberate Clip. Uniform: The image is scaled to fit the output dimensions. But the aspect ratio of the content is preserved. This is the default value. UniformToFill: The image is scaled so that it completely fills the output area but preserves its original aspect ratio. Fill: The image is scaled to fit the output dimensions. Because the content's height and width are scaled independently, the original aspect ratio of the image might not be preserved. That is, the image might be distorted to completely fill the output area.

Crop an image

You can use the Clip property to clip an area from the image output. You set the Clip property to a Geometry. Currently, non-rectangular clipping is not supported. The next example shows how to use a RectangleGeometry as the clip region for an image. In this example, we define an Image object with a height of 200. A RectangleGeometry defines a rectangle for the area of the image that will be displayed. The Rect property is set to "25,25,100,150", which defines a rectangle starting at position "25,25" with a width of 100 and a height of 150. Only the part of the image that is within the area of the rectangle is displayed.



Here's the clipped image on a black background.

Apply an opacity

You can apply an Opacity to an image so that the image is rendered semi-translucent. The opacity values are from 0.0 to 1.0 where 1.0 is fully opaque and 0.0 is fully transparent. This example shows how to apply an opacity of 0.5 to an Image.

Here's the rendered image with an opacity of 0.5 and a black background showing through the partial opacity.

Image file formats

Image and ImageBrush can display these image file formats: Joint Photographic Experts Group (JPEG) Portable Network Graphics (PNG) bitmap (BMP) Graphics Interchange Format (GIF) Tagged Image File Format (TIFF) JPEG XR icons (ICO) The APIs for Image, BitmapImage and BitmapSource don't include any dedicated methods for encoding and decoding of media formats. All of the encode and decode operations are built-in, and at most will surface aspects of encode or decode as part of event data for load events. If you want to do any special work with image encode or decode, which you might use if your app is doing image conversions or manipulation, you should use the APIs that are available in the Windows.Graphics.Imaging namespace. These APIs are also supported by the Windows

Imaging Component (WIC) in Windows. Starting in Windows 10, version 1607, the Image element supports animated GIF images. When you use a BitmapImage as the image Source, you can access BitmapImage APIs to control playback of the animated GIF image. For more info, see the Remarks on the BitmapImage class page. Note Animated GIF support is available when your app is compiled for Windows 10, version 1607 and running on version 1607 (or later). When your app is compiled for or runs on previous versions, the first frame of the GIF is shown, but it is not animated. For more info about app resources and how to package image sources in an app, see Defining app resources. WriteableBitmap

A WriteableBitmap provides a BitmapSource that can be modified and that doesn't use the basic file-based decoding from the WIC. You can alter images dynamically and re-render the updated image. To define the buffer content of a WriteableBitmap, use the PixelBuffer property to access the buffer and use a stream or languagespecific buffer type to fill it. For example code, see WriteableBitmap. RenderTargetBitmap

The RenderTargetBitmap class can capture the XAML UI tree from a running app, and then represents a bitmap image source. After capture, that image source can be applied to other parts of the app, saved as a resource or app data by the user, or used for other scenarios. One particularly useful scenario is creating a runtime thumbnail of a XAML page for a navigation scheme, such as providing an image link from a Hub control. RenderTargetBitmap does have some limitations on the content that will appear in the captured image. For more info, see the API reference topic for RenderTargetBitmap. Image sources and scaling

You should create your image sources at several recommended sizes, to ensure that your app looks great when Windows scales it. When specifying a Source for an Image, you can use a naming convention that will automatically reference the correct resource for the current scaling. For specifics of the naming convention and more info, see Quickstart: Using file or image resources. For more info about how to design for scaling, see UX guidelines for layout and scaling. Image and ImageBrush in code

It's typical to specify Image and ImageBrush elements using XAML rather than code. This is because these elements are often the output of design tools as part of a XAML UI definition. If you define an Image or ImageBrush using code, use the default constructors, then set the relevant source property (Image.Source or ImageBrush.ImageSource). The source properties require a BitmapImage (not a URI) when you set them using code. If your source is a stream, use the SetSourceAsync method to initialize the value. If your source is a URI, which includes content in your app that uses the ms-appx or ms-resource schemes, use the BitmapImage constructor that takes a URI. You might also consider handling the ImageOpened event if there are any timing issues with retrieving or decoding the image source, where you might need alternate content to display until the image source is available. For example code, see XAML images sample. NOTE If you establish images using code, you can use automatic handling for accessing unqualified resources with current scale and culture qualifiers, or you can use ResourceManager and ResourceMap with qualifiers for culture and scale to obtain the resources directly. For more info see Resource management system.

Related articles

Audio, video, and camera Image class ImageBrush class

Inking controls 3/6/2017 • 5 min to read • Edit on GitHub

There are two different controls that facilitate inking in Universal Windows Platform (UWP) apps: InkCanvas and InkToolbar. The InkCanvas control renders pen input as either an ink stroke (using default settings for color and thickness) or an erase stroke. This control is a transparent overlay that doesn't include any built-in UI for changing the default ink stroke properties. NOTE InkCanvas can be configured to support similar functionality for both mouse and touch input.

As the InkCanvas control does not include support for changing the default ink stroke settings, it can be paired with an InkToolbar control. The InkToolbar contains a customizable and extensible collection of buttons that activate inkrelated features in an associated InkCanvas. By default, the InkToolbar includes buttons for drawing, erasing, highlighting, and displaying a ruler. Depending on the feature, other settings and commands, such as ink color, stroke thickness, erase all ink, are provided in a flyout. NOTE InkToolbar supports pen and mouse input and can be configured to recognize touch input.

Important APIs InkCanvas class InkToolbar class InkPresenter class Windows.UI.Input.Inking

Is this the right control? Use the InkCanvas when you need to enable basic inking features in your app without providing any ink settings to the user. By default, strokes are rendered as ink when using the pen tip (a black ballpoint pen with a thickness of 2 pixels) and as an eraser when using the eraser tip. If an eraser tip is not present, the InkCanvas can be configured to process input from the pen tip as an erase stroke. Pair the InkCanvas with an InkToolbar to provide a UI for activating ink features and setting basic ink properties such as stroke size, color, and shape of the pen tip. NOTE For more extensive customization of ink stroke rendering on an InkCanvas, use the underlying InkPresenter object.

Examples Microsoft Edge The Edge browser uses the InkCanvas and InkToolbar for Web Notes.

Windows Ink Workspace The InkCanvas and InkToolbar are also used for both Sketchpad and Screen sketch in the Windows Ink Workspace.

Create an InkCanvas and InkToolbar Adding an InkCanvas to your app requires just one line of markup:

NOTE For detailed InkCanvas customization using InkPresenter, see the "Pen and stylus interactions in UWP apps" article.

The InkToolbar control must be used in conjunction with an InkCanvas. Incorporating an InkToolbar (with all builtin tools) into your app requires one additional line of markup:

This displays the following InkToolbar: Built-in buttons

The InkToolbar includes the following built-in buttons: Pens Ballpoint pen - draws a solid, opaque stroke with a circle pen tip. The stroke size is dependent on the pen pressure detected. Pencil - draws a soft-edged, textured, and semi-transparent stroke (useful for layered shading effects) with a circle pen tip. The stroke color (darkness) is dependent on the pen pressure detected. Highlighter – draws a semi-transparent stroke with a rectangle pen tip. You can customize both the color palette and size attributes (min, max, default) in the flyout for each pen. Tool Eraser – deletes any ink stroke touched. Note that the entire ink stroke is deleted, not just the portion under the eraser stroke. Toggle Ruler – shows or hides the ruler. Drawing near the ruler edge causes the ink stroke to snap to the ruler.

Although this is the default configuration, you have complete control over which built-in buttons are included in the InkToolbar for your app. Custom buttons

The InkToolbar consists of two distinct groups of button types: 1. A group of "tool" buttons containing the built-in drawing, erasing, and highlighting buttons. Custom pens and tools are added here. NOTE Feature selection is mutually exclusive.

2. A group of "toggle" buttons containing the built-in ruler button. Custom toggles are added here.

NOTE Features are not mutually exclusive and can be used concurrently with other active tools.

Depending on your application and the inking functionality required, you can add any of the following buttons (bound to your custom ink features) to the InkToolbar: Custom pen – a pen for which the ink color palette and pen tip properties, such as shape, rotation, and size, are defined by the host app. Custom tool – a non-pen tool, defined by the host app. Custom toggle – Sets the state of an app-defined feature to on or off. When turned on, the feature works in conjunction with the active tool. NOTE You cannot change the display order of the built-in buttons. The default display order is: Ballpoint pen, pencil, highlighter, eraser, and ruler. Custom pens are appended to the last default pen, custom tool buttons are added between the last pen button and the eraser button and custom toggle buttons are added after the ruler button. (Custom buttons are added in the order they are specified.)

Although the InkToolbar can be a top level item, it is typically exposed through an “Inking” button or command. We recommend using EE56 glyph from the Segoe MLD2 Assets font as a top level icon.

InkToolbar Interaction All built-in pen and tool buttons include a flyout menu where ink properties and pen tip shape and size can be set. An "extension glyph"

is displayed on the button to indicate the existence of the flyout.

The flyout is shown when the button of an active tool is selected again. When the color or size is changed, the flyout is automatically dismissed and inking can be resumed. Custom pens and tools can use the default flyout or specify a custom flyout. The eraser also has a flyout that provides the Erase All Ink command.

For information on customization and extensibility, check out SimpleInk sample.

Do's and don'ts The InkCanvas, and inking in general, is best experienced through an active pen. However, we recommend supporting inking with mouse and touch (including passive pen) input if required by your app. Use an InkToolbar control with the InkCanvas to provide basic inking features and settings. Both the InkCanvas and InkToolbar can be programmatically customized. The InkToolbar, and inking in general, is best experienced through an active pen. However, inking with mouse and touch can be supported if required by your app. If supporting inking with touch input, we recommend using the ED5F icon from the Segoe MLD2 Assets font for the toggle button, with a “Touch writing” tooltip. If providing stroke selection, we recommend using the EF20 icon from the Segoe MLD2 Assets font for the tool button, with a “Selection tool” tooltip.

If using more than one InkCanvas, we recommend using a single InkToolbar to control inking across canvases. For best performance, we recommend altering the default flyout rather than creating a custom one for both default and custom tools.

Get the sample code SimpleInk sample demonstrates 8 scenarios around the customization and extensibility capabilities of the InkCanvas and InkToolbar controls. Each scenario provides basic guidance on common inking situations and control implementations. For a more advanced inking sample, see ComplexInk sample.

Related articles Pen and stylus interactions in UWP apps Recognize ink strokes Store and retrieve ink strokes

Lists 3/6/2017 • 9 min to read • Edit on GitHub

Lists display and enable interactions with collection-based content. The four list patterns covered in this article include: List views, which are primarily used to display text-heavy content collections Grid views, which are primarily used to display image-heavy content collections Drop-down lists, which let users choose one item from an expanding list List boxes, which let users choose one item or multiple items from a box that can be scrolled Design guidelines, features, and examples are given for each list pattern. At the end of the article are links to related topics and APIs. Important APIs ListView class GridView class ComboBox class

List views List views let you categorize items and assign group headers, drag and drop items, curate content, and reorder items. Is this the right control?

Use a list view to: Display a content collection that primarily consists of text. Navigate a single or categorized collection of content. Create the master pane in the master/details pattern. A master/details pattern is often used in email apps, in which one pane (the master) has a list of selectable items while the other pane (details) has a detailed view of the selected item. Examples

Here's a simple list view showing grouped data on a phone.

Recommendations

Items within a list should have the same behavior. If your list is divided into groups, you can use semantic zoom to make it easier for users to navigate through grouped content. List view articles TOPIC

DESCRIPTION

List view and grid view

Learn the essentials of using a list view or grid view in your app.

List view item templates

The items you display in a list or grid can play a major role in the overall look of your app. Modify control templates and data templates to define the look of the items and make your app look great.

Inverted lists

Inverted lists have new items added at the bottom, like in a chat app. Follow this guidance to use an inverted list in your app.

TOPIC

DESCRIPTION

Pull-to-refresh

The pull-to-refresh pattern lets a user pull down on a list of data using touch in order to retrieve more data. Use this guidance to implement pull-to-refresh in your list view.

Nested UI

Nested UI is a user interface (UI) that exposes actionable controls enclosed inside a container that a user can also take action on. For example, you might have list view item that contains a button, and the user can select the list item, or press the button nested within it. Follow these best practices to provide the best nested UI experience for your users.

Grid views Grid views are suited for arranging and browsing image-based content collections. A grid view layout scrolls vertically and pans horizontally. Items are laid out in a left-to-right, then top-to-bottom reading order. Is this the right control?

Use a list view to: Display a content collection that primarily consists of images. Display content libraries. Format the two content views associated with semantic zoom. Examples

This example shows a typical grid view layout, in this case for browsing apps. Metadata for grid view items is usually restricted to a few lines of text and an item rating.

A grid view is an ideal solution for a content library, which is often used to present media such as pictures and videos. In a content library, users expect to be able to tap an item to invoke an action.

Recommendations

Items within a list should have the same behavior. If your list is divided into groups, you can use semantic zoom to make it easier for users to navigate through grouped content. Grid view articles TOPIC

DESCRIPTION

List view and grid view

Learn the essentials of using a list view or grid view in your app.

List view item templates

The items you display in a list or grid can play a major role in the overall look of your app. Modify control templates and data templates to define the look of the items and make your app look great.

Nested UI

Nested UI is a user interface (UI) that exposes actionable controls enclosed inside a container that a user can also take action on. For example, you might have list view item that contains a button, and the user can select the list item, or press the button nested within it. Follow these best practices to provide the best nested UI experience for your users.

Drop-down lists Drop-down lists, also known as combo boxes, start in a compact state and expand to show a list of selectable items. The selected item is always visible, and non-visible items can be brought into view when the user taps the combo box to expand it. Is this the right control?

Use a drop-down list to let users select a single value from a set of items that can be adequately represented with single lines of text. Use a list or grid view instead of a combo box to display items that contain multiple lines of text or images. When there are fewer than five items, consider using radio buttons (if only one item can be selected) or check boxes (if multiple items can be selected). Use a combo box when the selection items are of secondary importance in the flow of your app. If the default option is recommended for most users in most situations, showing all the items by using a list view might draw more attention to the options than necessary. You can save space and minimize distraction by using a combo box.

Examples

A combo box in its compact state can show a header.

Although combo boxes expand to support longer string lengths, avoid excessively long strings that are difficult to read.

If the collection in a combo box is long enough, a scroll bar will appear to accommodate it. Group items logically in the list.

Recommendations

Limit the text content of combo box items to a single line. Sort items in a combo box in the most logical order. Group together related options and place the most common options at the top. Sort names in alphabetical order, numbers in numerical order, and dates in chronological order. Text Search

Combo boxes automatically support search within their collections. As users type characters on a physical keyboard while focused on an open or closed combo box, candidates matching the user's string are brought into view. This functionality is especially helpful when navigating a long list. For example, when interacting with a drop-down containing a list of states, users can press the “w” key to bring “Washington” into view for quick selection.

List boxes A list box allows the user to choose either a single item or multiple items from a collection. List boxes are

similar to drop-down lists, except that list boxes are always open—there is no compact (non-expanded) state for a list box. Items in the list can be scrolled if there isn't space to show everything. Is this the right control?

A list box can be useful when items in the list are important enough to prominently display, and when there's enough screen real estate, to show the full list. A list box should draw the user's attention to the full set of alternatives in an important choice. By contrast, a drop-down list initially draws the user's attention to the selected item. Avoid using a list box if: There is a very small number of items for the list. A single-select list box that always has the same 2 options might be better presented as radio buttons. Also consider using radio buttons when there are 3 or 4 static items in the list. The list box is single-select and it always has the same 2 options where one can be implied as not the other, such as "on" and "off." Use a single check box or a toggle switch. There is a very large number of items. A better choice for long lists are grid view and list view. For very long lists of grouped data, semantic zoom is preferred. The items are contiguous numerical values. If that's the case, consider using a slider. The selection items are of secondary importance in the flow of your app or the default option is recommended for most users in most situations. Use a drop-down list instead. Recommendations

The ideal range of items in a list box is 3 to 9. A list box works well when its items can dynamically vary. If possible, set the size of a list box so that its list of items don't need to be panned or scrolled. Verify that the purpose of the list box, and which items are currently selected, is clear. Reserve visual effects and animations for touch feedback, and for the selected state of items. Limit the list box item's text content to a single line. If the items are visuals, you can customize the size. If an item contains multiple lines of text or images, instead use a grid view or list view. Use the default font unless your brand guidelines indicate to use another. Don't use a list box to perform commands or to dynamically show or hide other controls.

Selection mode Selection mode lets users select and take action on a single item or on multiple items. It can be invoked through a context menu, by using CTRL+click or SHIFT+click on an item, or by rolling-over a target on an item in a gallery view. When selection mode is active, check boxes appear next to each list item, and actions can appear at the top or the bottom of the screen. There are three selection modes: Single: The user can select only one item at a time. Multiple: The user can select multiple items without using a modifier. Extended: The user can select multiple items with a modifier, such as holding down the SHIFT key. Tapping anywhere on an item selects it. Tapping on the command bar action affects all selected items. If no item is selected, command bar actions should be inactive, except for "Select All". Selection mode doesn't have a light dismiss model; tapping outside of the frame in which selection mode is active won't cancel the mode. This is to prevent accidental deactivation of the mode. Clicking the back button dismisses the multi-select mode. Show a visual confirmation when an action is selected. Consider displaying a confirmation dialog for certain actions, especially destructive actions such as delete.

Selection mode is confined to the page in which it is active, and can't affect any items outside of that page. The entry point to selection mode should be juxtaposed against the content it affects. For command bar recommendations, see guidelines for command bars.

Globalization and localization checklist WRAPPING

Allow two lines for the list label.

HORIZONTAL EXPANSION

Make sure fields can accomdation text expension and are scrollable.

VERTICAL SPACING

Use non-Latin chracters for vertical spacing to ensure nonLatin scripts will display properly.

Related articles Hub Master/details Nav pane Semantic zoom Drag and drop For developers ListView class GridView class ComboBox class ListBox class

ListView and GridView 3/6/2017 • 15 min to read • Edit on GitHub

Most applications manipulate and display sets of data, such as a gallery of images or a set of email messages. The XAML UI framework provides ListView and GridView controls that make it easy to display and manipulate data in your app. ListView and GridView both derive from the ListViewBase class, so they have the same functionality, but display data differently. In this article, when we talk about ListView, the info applies to both the ListView and GridView controls unless otherwise specified. We may refer to classes like ListView or ListViewItem, but the “List” prefix can be replaced with “Grid” for the corresponding grid equivalent (GridView or GridViewItem). Important APIs ListView class GridView class ItemsSource property Items property

Is this the right control? The ListView displays data stacked vertically in a single column. It's often used to show an ordered list of items, such as a list of emails or search results.

The GridView presents a collection of items in rows and columns that can scroll vertically. Data is stacked horizontally until it fills the columns, then continues with the next row. It's often used when you need to show a rich visualization of each item that takes more space, such as a photo gallery.

For a more detailed comparison and guidance on which control to use, see Lists.

Create a list view List view is an ItemsControl, so it can contain a collection of items of any type. It must have items in its Items collection before it can show anything on the screen. To populate the view, you can add items directly to the Items collection, or set the ItemsSource property to a data source. Important You can use either Items or ItemsSource to populate the list, but you can't use both at the same time.

If you set the ItemsSource property and you add an item in XAML, the added item is ignored. If you set the ItemsSource property and you add an item to the Items collection in code, an exception is thrown. Note Many of the examples in this article populate the Items collection directly for the sake of simplicity. However, it's more common for the items in a list to come from a dynamic source, like a list of books from an online database. You use the ItemsSource property for this purpose. Add items to the Items collection

You can add items to the Items collection using XAML or code. You typically add items this way if you have a small number of items that don't change and are easily defined in XAML, or if you generate the items in code at run time. Here's a list view with items defined inline in XAML. When you define the items in XAML, they are automatically added to the Items collection. XAML Item 1 Item 2 Item 3 Item 4 Item 5

Here's the list view created in code. The resulting list is the same as the one created previously in XAML. C# // Create a new ListView and add content. ListView listView1 = new ListView(); listView1.Items.Add("Item 1"); listView1.Items.Add("Item 2"); listView1.Items.Add("Item 3"); listView1.Items.Add("Item 4"); listView1.Items.Add("Item 5"); // Add the ListView to a parent container in the visual tree. stackPanel1.Children.Add(listView1);

The ListView looks like this.

Set the items source

You typically use a list view to display data from a source such as a database or the Internet. To populate a list view from a data source, you set its ItemsSource property to a collection of data items. Here, the list view's ItemsSource is set in code directly to an instance of a collection.

C# // Instead of hard coded items, the data could be pulled // asynchronously from a database or the internet. ObservableCollection listItems = new ObservableCollection(); listItems.Add("Item 1"); listItems.Add("Item 2"); listItems.Add("Item 3"); listItems.Add("Item 4"); listItems.Add("Item 5"); // Create a new list view, add content, ListView itemListView = new ListView(); itemListView.ItemsSource = listItems; // Add the list view to a parent container in the visual tree. stackPanel1.Children.Add(itemListView);

You can also bind the ItemsSource property to a collection in XAML. For more info about data binding, see Data binding overview. Here, the ItemsSource is bound to a public property named

Items

that exposes the Page's private data collection.

XAML

C# private ObservableCollection _items = new ObservableCollection(); public ObservableCollection Items { get { return this._items; } } protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); // Instead of hard coded items, the data could be pulled // asynchronously from a database or the internet. Items.Add("Item 1"); Items.Add("Item 2"); Items.Add("Item 3"); Items.Add("Item 4"); Items.Add("Item 5"); }

If you need to show grouped data in your list view, you must bind to a CollectionViewSource. The CollectionViewSource acts as a proxy for the collection class in XAML and enables grouping support. For more info, see CollectionViewSource.

Data template An item’s data template defines how the data is visualized. By default, a data item is displayed in the list view as the string representation of the data object it's bound to. You can show the string representation of a particular property of the data item by setting the DisplayMemberPath to that property.

However, you typically want to show a more rich presentation of your data. To specify exactly how items in the list view are displayed, you create a DataTemplate. The XAML in the DataTemplate defines the layout and appearance of controls used to display an individual item. The controls in the layout can be bound to properties of a data object, or have static content defined inline. You assign the DataTemplate to the ItemTemplate property of the list control. In this example, the data item is a simple string. You use a DataTemplate to add an image to the left of the string, and show the string in blue. Note When you use the x:Bind markup extension in a DataTemplate, you have to specify the DataType ( x:DataType ) on the DataTemplate. XAML Item 1 Item 2 Item 3 Item 4 Item 5

Here's what the data items look like when displayed with this data template.

Data templates are the primary way you define the look of your list view. They can also have a significant impact on performance if your list displays a large number of items. In this article, we use simple string data for most of the examples, and don't specify a data template. For more info and examples of how to use data templates and item containers to define the look of items in your list or grid, see List view item templates.

Change the layout of items When you add items to a list view or grid view, the control automatically wraps each item in an item container and

then lays out all of the item containers. How these item containers are laid out depends on the ItemsPanel of the control. By default, ListView uses an ItemsStackPanel, which produces a vertical list, like this.

GridView uses an ItemsWrapGrid, which adds items horizontally, and wraps and scrolls vertically, like this.

You can modify the layout of items by adjusting properties on the items panel, or you can replace the default panel with another panel. Note Be careful to not disable virtualization if you change the ItemsPanel. Both ItemsStackPanel and ItemsWrapGrid support virtualization, so these are safe to use. If you use any other panel, you might disable virtualization and slow the performance of the list view. For more info, see the list view articles under Performance. This example shows how to make a ListView lay out its item containers in a horizontal list by changing the Orientation property of the ItemsStackPanel. Because the list view scrolls vertically by default, you also need to adjust some properties on the list view’s internal ScrollViewer to make it scroll horizontally. ScrollViewer.HorizontalScrollMode to Enabled or Auto ScrollViewer.HorizontalScrollBarVisibility to Auto ScrollViewer.VerticalScrollMode to Disabled ScrollViewer.VerticalScrollBarVisibility to Hidden Note These examples are shown with the list view width unconstrained, so the horizontal scrollbars are not shown. If you run this code, you can set Width="180" on the ListView to make the scrollbars show. XAML

Item 1 Item 2 Item 3 Item 4 Item 5

The resulting list looks like this.

In the next example, the ListView lays out items in a vertical wrapping list by using an ItemsWrapGrid instead of an ItemsStackPanel. Note The height of the list view must be constrained to force the control to wrap the containers. XAML Item 1 Item 2 Item 3 Item 4 Item 5

The resulting list looks like this.

If you show grouped data in your list view, the ItemsPanel determines how the item groups are layed out, not how the individual items are layed out. For example, if the horizontal ItemsStackPanel shown previously is used to show grouped data, the groups are arranged horizontally, but the items in each group are still stacked vertically, as shown here.

Item selection and interaction You can choose from various ways to let a user interact with a list view. By default, a user can select a single item. You can change the SelectionMode property to enable multi-selection or to disable selection. You can set the IsItemClickEnabled property so that a user clicks an item to invoke an action (like a button) instead of selecting the item. Note Both ListView and GridView use the ListViewSelectionMode enumeration for their SelectionMode properties. IsItemClickEnabled is False by default, so you need to set it only to enable click mode. This table shows the ways a user can interact with a list view, and how you can respond to the interaction. TO ENABLE THIS INTERACTION:

USE THESE SETTINGS:

HANDLE THIS EVENT:

USE THIS PROPERTY TO GET THE SELECTED ITEM:

No interaction

SelectionMode = None, IsItemClickEnabled = False

N/A

N/A

Single selection

SelectionMode = Single, IsItemClickEnabled = False

SelectionChanged

SelectedItem, SelectedIndex

Multiple selection

SelectionMode = Multiple, IsItemClickEnabled = False

SelectionChanged

SelectedItems

Extended selection

SelectionMode = Extended, IsItemClickEnabled = False

SelectionChanged

SelectedItems

Click

SelectionMode = None, IsItemClickEnabled = True

ItemClick

N/A

Note Starting in Windows 10, you can enable IsItemClickEnabled to raise an ItemClick event while SelectionMode is also set to Single, Multiple, or Extended. If you do this, the ItemClick event is raised first, and then the SelectionChanged event is raised. In some cases, like if you navigate to another page in the ItemClick event handler, the SelectionChanged event is not raised and the item is not selected. You can set these properties in XAML or in code, as shown here. XAML

C# myListView.SelectionMode = ListViewSelectionMode.Multiple; myGridView.SelectionMode = ListViewSelectionMode.None; myGridView.IsItemClickEnabled = true;

Read-only

You can set the SelectionMode property to ListViewSelectionMode.None to disable item selection. This puts the control in read only mode, to be used for displaying data, but not for interacting with it. The control itself is not disabled, only item selection is disabled. Single selection

This table describes the keyboard, mouse, and touch interactions when SelectionMode is Single. MODIFIER KEY

INTERACTION

None

A user can select a single item using the space bar, mouse click, or touch tap.

Ctrl

A user can deselect a single item using the space bar, mouse click, or touch tap. Using the arrow keys, a user can move focus independently of selection.

When SelectionMode is Single, you can get the selected data item from the SelectedItem property. You can get the index in the collection of the selected item using the SelectedIndex property. If no item is selected, SelectedItem is null, and SelectedIndex is -1. If you try to set an item that is not in the Items collection as the SelectedItem, the operation is ignored and SelectedItem isnull. However, if you try to set the SelectedIndex to an index that's out of the range of the Items in the list, a System.ArgumentException exception occurs. Multiple selection

This table describes the keyboard, mouse, and touch interactions when SelectionMode is Multiple. MODIFIER KEY

INTERACTION

None

A user can select multiple items using the space bar, mouse click, or touch tap to toggle selection on the focused item. Using the arrow keys, a user can move focus independently of selection.

Shift

A user can select multiple contiguous items by clicking or tapping the first item in the selection and then the last item in the selection. Using the arrow keys, a user can create a contiguous selection starting with the item selected when Shift is pressed.

Extended selection

This table describes the keyboard, mouse, and touch interactions when SelectionMode is Extended. MODIFIER KEY

None

INTERACTION

The behavior is the same as Single selection.

MODIFIER KEY

INTERACTION

Ctrl

A user can select multiple items using the space bar, mouse click, or touch tap to toggle selection on the focused item. Using the arrow keys, a user can move focus independently of selection.

Shift

A user can select multiple contiguous items by clicking or tapping the first item in the selection and then the last item in the selection. Using the arrow keys, a user can create a contiguous selection starting with the item selected when Shift is pressed.

When SelectionMode is Multiple or Extended, you can get the selected data items from the SelectedItems property. The SelectedIndex, SelectedItem, and SelectedItems properties are synchronized. For example, if you set SelectedIndex to -1, SelectedItem is set to null and SelectedItems is empty; if you set SelectedItem to null, SelectedIndex is set to -1 and SelectedItems is empty. In multi-select mode, SelectedItem contains the item that was selected first, and Selectedindex contains the index of the item that was selected first. Respond to selection changes

To respond to selection changes in a list view, handle the SelectionChanged event. In the event handler code, you can get the list of selected items from the SelectionChangedEventArgs.AddedItems property. You can get any items that were deselected from the SelectionChangedEventArgs.RemovedItems property. The AddedItems and RemovedItems collections contain at most 1 item unless the user selects a range of items by holding down the Shift key. This example shows how to handle the SelectionChanged event and access the various items collections. XAML Item 1 Item 2 Item 3 Item 4 Item 5

C#

private void ListView1_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (listView1.SelectedItem != null) { selectedItem.Text = "Selected item: " + listView1.SelectedItem.ToString(); } else { selectedItem.Text = "Selected item: null"; } selectedIndex.Text = "Selected index: " + listView1.SelectedIndex.ToString(); selectedItemCount.Text = "Items selected: " + listView1.SelectedItems.Count.ToString(); addedItems.Text = "Added: " + e.AddedItems.Count.ToString(); removedItems.Text = "Removed: " + e.RemovedItems.Count.ToString(); }

Click mode

You can change a list view so that a user clicks items like buttons instead of selecting them. For example, this is useful when your app navigates to a new page when your user clicks an item in a list or grid. To enable this behavior: Set SelectionMode to None. Set IsItemClickEnabled to true. Handle the ItemClick event to do something when your user clicks an item. Here's a list view with clickable items. The code in the ItemClick event handler navigates to a new page. XAML Page 1 Page 2 Page 3 Page 4 Page 5

C#

private void ListView1_ItemClick(object sender, ItemClickEventArgs e) { switch (e.ClickedItem.ToString()) { case "Page 1": this.Frame.Navigate(typeof(Page1)); break; case "Page 2": this.Frame.Navigate(typeof(Page2)); break; case "Page 3": this.Frame.Navigate(typeof(Page3)); break; case "Page 4": this.Frame.Navigate(typeof(Page4)); break; case "Page 5": this.Frame.Navigate(typeof(Page5)); break; default: break; } }

Select a range of items programmatically

Sometimes, you need to manipulate a list view’s item selection programmatically. For example, you might have a Select all button to let a user select all items in a list. In this case, it’s usually not very efficient to add and remove items from the SelectedItems collection one by one. Each item change causes a SelectionChanged event to occur, and when you work with the items directly instead of working with index values, the item is de-virtualized. The SelectAll, SelectRange, and DeselectRange methods provide a more efficient way to modify the selection than using the SelectedItems property. These methods select or deselect using ranges of item indexes. Items that are virtualized remain virtualized, because only the index is used. All items in the specified range are selected (or deselected), regardless of their original selection state. The SelectionChanged event occurs only once for each call to these methods. Important You should call these methods only when the SelectionMode property is set to Multiple or Extended. If you call SelectRange when the SelectionMode is Single or None, an exception is thrown. When you select items using index ranges, use the SelectedRanges property to get all selected ranges in the list. If the ItemsSource implements IItemsRangeInfo, and you use these methods to modify the selection, the AddedItems and RemovedItems properties are not set in the SelectionChangedEventArgs. Setting these properties requires de-virtualizing the item object. Use the SelectedRanges property to get the items instead. You can select all items in a collection by calling the SelectAll method. However, there is no corresponding method to deselect all items. You can deselect all items by calling DeselectRange and passing an ItemIndexRange with a FirstIndex value of 0 and a Length value equal to the number of items in the collection. XAML

Item 1 Item 2 Item 3 Item 4 Item 5

C# private void SelectAllButton_Click(object sender, RoutedEventArgs e) { if (listView1.SelectionMode == ListViewSelectionMode.Multiple || listView1.SelectionMode == ListViewSelectionMode.Extended) { listView1.SelectAll(); } } private void DeselectAllButton_Click(object sender, RoutedEventArgs e) { if (listView1.SelectionMode == ListViewSelectionMode.Multiple || listView1.SelectionMode == ListViewSelectionMode.Extended) { listView1.DeselectRange(new ItemIndexRange(0, (uint)listView1.Items.Count)); } }

For info about how to change the look of selected items, see List view item templates. Drag and drop

ListView and GridView controls support drag and drop of items within themselves, and between themselves and other ListView and GridView controls. For more info about implementing the drag and drop pattern, see Drag and drop.

Get the sample code XAML ListView and GridView sample This sample shows the usage of ListView and Gridview controls. XAML UI basics sample See all of the XAML controls in an interactive format.

Related articles Lists List view item templates Drag and drop

Item containers and templates 3/6/2017 • 14 min to read • Edit on GitHub

ListView and GridView controls manage how their items are arranged (horizontal, vertical, wrapping, etc…) and how a user interacts with the items, but not how the individual items are shown on the screen. Item visualization is managed by item containers. When you add items to a list view they are automatically placed in a container. The default item container for ListView is ListViewItem; for GridView, it’s GridViewItem. Important APIs ListView class GridView class ItemTemplate property ItemContainerStyle property

ListView and GridView both derive from the ListViewBase class, so they have the same functionality, but display data differently. In this article, when we talk about list view, the info applies to both the ListView and GridView controls unless otherwise specified. We may refer to classes like ListView or ListViewItem, but the List prefix can be replaced with Grid for the corresponding grid equivalent (GridView or GridViewItem). These container controls consist of two important parts that combine to create the final visuals shown for an item: the data template and the control template. Data template - You assign a DataTemplate to the ItemTemplate property of the list view to specify how individual data items are shown. Control template - The control template provides the part of the item visualization that the framework is responsible for, like visual states. You can use the ItemContainerStyle property to modify the control template. Typically, you do this to modify the list view colors to match your branding, or change how selected items are shown. This image shows how the control template and the data template combine to create the final visual for an item.

Here's the XAML that creates this item. We explain the templates later.

Item 1 Item 2 Item 3 Item 4 Item 5

Prerequisites We assume that you know how to use a list view control. For more info, see the ListView and GridView article. We also assume that you understand control styles and templates, including how to use a style inline or as a resource. For more info, see Styling controls and Control templates.

The data Before we look deeper into how to show data items in a list view, we need to understand the data to be shown. In this example, we create a data type called NamedColor . It combines a color name, color value, and a SolidColorBrush for the color, which are exposed as 3 properties: Name , Color , and Brush . We then populate a List with a ItemsSource for the list view.

NamedColor

object for each named color in the Colors class. The list is set as the

Here’s the code to define the class and populate the C#

NamedColors

list.

using System.Collections.Generic; using System.Linq; using System.Reflection; using Windows.UI; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Media; namespace ColorsListApp { public sealed partial class MainPage : Page { // The list of colors won't change after it's populated, so we use List. // If the data can change, we should use an ObservableCollection intead. List NamedColors = new List(); public MainPage() { this.InitializeComponent(); // Use reflection to get all the properties of the Colors class. IEnumerable propertyInfos = typeof(Colors).GetRuntimeProperties(); // For each property, create a NamedColor with the property name (color name), // and property value (color value). Add it the NamedColors list. for (int i = 0; i < propertyInfos.Count(); i++) { NamedColors.Add(new NamedColor(propertyInfos.ElementAt(i).Name, (Color)propertyInfos.ElementAt(i).GetValue(null))); } colorsListView.ItemsSource = NamedColors; } } class NamedColor { public NamedColor(string colorName, Color colorValue) { Name = colorName; Color = colorValue; } public string Name { get; set; } public Color Color { get; set; } public SolidColorBrush Brush { get { return new SolidColorBrush(Color); } } } }

Data template You specify a data template to tell the list view how your data item should be shown. By default, a data item is displayed in the list view as the string representation of the data object it's bound to. If you show the 'NamedColors' data in a list view without telling the list view how it should look, it just shows whatever the ToString method returns, like this. XAML



You can show the string representation of a particular property of the data item by setting the DisplayMemberPath to that property. Here, you set DisplayMemberPath to the Name property of the NamedColor item. XAML

The list view now displays items by name, as shown here. It’s more useful, but it’s not very interesting and leaves a lot of information hidden.

You typically want to show a more rich presentation of your data. To specify exactly how items in the list view are displayed, you create a DataTemplate. The XAML in the DataTemplate defines the layout and appearance of controls used to display an individual item. The controls in the layout can be bound to properties of a data object, or have static content defined inline. You assign the DataTemplate to the ItemTemplate property of the list control. IMPORTANT You can’t use a ItemTemplate and DisplayMemberPath at the same time. If both properties are set, an exception occurs.

Here, you define a DataTemplate that shows a Rectangle in the color of the item, along with the color name and RGB values. NOTE When you use the x:Bind markup extension in a DataTemplate, you have to specify the DataType ( DataTemplate.

XAML

x:DataType

) on the



Here's what the data items look like when they're displayed with this data template.

You might want to show the data in a GridView. Here's another data template that displays the data in a way that's more appropriate for a grid layout. This time, the data template is defined as a resource rather than inline with the XAML for the GridView. XAML

...

When the data is shown in a grid using this data template, it looks like this.

Performance considerations

Data templates are the primary way you define the look of your list view. They can also have a significant impact on performance if your list displays a large number of items. An instance of every XAML element in a data template is created for each item in the list view. For example, the grid template in the previous example has 10 XAML elements (1 Grid, 1 Rectangle, 3 Borders, 5 TextBlocks). A

GridView that shows 20 items on screen using this data template creates at least 200 elements (20*10=200). Reducing the number of elements in a data template can greatly reduce the total number of elements created for your list view. For more info, see ListView and GridView UI optimization: Element count reduction per item. Consider this section of the grid data template. Let's look at a few things that reduce the element count. XAML

First, the layout uses a single Grid. You could have a single-column Grid and place these 3 TextBlocks in a StackPanel, but in a data template that gets created many times, you should look for ways to avoid embedding layout panels within other layout panels. Second, you can use a Border control to render a background without actually placing items within the Border element. A Border element can have only one child element, so you would need to add an additional layout panel to host the 3 TextBlock elements within the Border element in XAML. By not making the TextBlocks children of the Border, you eliminate the need for a panel to hold the TextBlocks. Finally, you could place the TextBlocks inside a StackPanel, and set the border properties on the StackPanel rather than using an explicit Border element. However, the Border element is a more lightweight control than a StackPanel, so it has less of an impact on performance when rendered many times over.

Control template An item’s control template contains the visuals that display state, like selection, pointer over, and focus. These visuals are rendered either on top of or below the data template. Some of the common default visuals drawn by the ListView control template are shown here. Hover – A light gray rectangle drawn below the data template. Selection – A light blue rectangle drawn below the data template. Keyboard focus– A black and white dotted border drown on top of the item template.

The list view combines the elements from the data template and control template to create the final visuals rendered on the screen. Here, the state visuals are shown in the context of a list view.

ListViewItemPresenter

As we noted previously about data templates, the number of XAML elements created for each item can have a significant impact on the performance of a list view. Because the data template and control template are combined to display each item, the actual number of elements needed to display an item includes the elements in both templates. The ListView and GridView controls are optimized to reduce the number of XAML elements created per item. The ListViewItem visuals are created by the ListViewItemPresenter, which is a special XAML element that displays complex visuals for focus, selection, and other visual states, without the overhead of numerous UIElements. NOTE In UWP apps for Windows 10, both ListViewItem and GridViewItem use ListViewItemPresenter; the GridViewItemPresenter is deprecated and you should not use it. ListViewItem and GridViewItem set different property values on ListViewItemPresenter to achieve different default looks.)

To modify the look of the item container, use the ItemContainerStyle property and provide a Style with its TargetType set to ListViewItem or GridViewItem. In this example, you add padding to the ListViewItem to create some space between the items in the list.

Now the list view looks like this with space between the items.

In the ListViewItem default style, the ListViewItemPresenter ContentMargin property has a TemplateBinding to the ListViewItem Padding property ( ). When we set the Padding property, that value is really being passed to the ListViewItemPresenter ContentMargin property. To modify other ListViewItemPresenter properties that aren't template bound to ListViewItems properties, you need to retemplate the ListViewItem with a new ListViewItemPresenter that you can modify properties on.

NOTE ListViewItem and GridViewItem default styles set a lot of properties on ListViewItemPresenter. You should always start with a copy of the default style and modify only the properties you need too. Otherwise, the visuals will probably not show up the way you expect because some properties won't be set correctly.

To make a copy of the default template in Visual Studio 1. Open the Document Outline pane (View > Other Windows > Document Outline). 2. Select the list or grid element to modify. In this example, you modify the colorsGridView element. 3. Right-click and select Edit Additional Templates > Edit Generated Item Container (ItemContainerStyle) > Edit a Copy.

4. In the Create Style Resource dialog, enter a name for the style. In this example, you use [Visual Studio Create Style Resource dialog(images/listview-style-resource-vs.png)

colorsGridViewItemStyle

.!

A copy of the default style is added to your app as a resource, and the GridView.ItemContainerStyle property is set to that resource, as shown in this XAML.

...

You can now modify properties on the ListViewItemPresenter to control the selection check box, item positioning, and brush colors for visual states. Inline and Overlay selection visuals

ListView and GridView indicate selected items in different ways depending on the control and the SelectionMode. For more info about list view selection, see ListView and GridView. When SelectionMode is set to Multiple, a selection check box is shown as part of the item's control template. You can use the SelectionCheckMarkVisualEnabled property to turn off the selection check box in Multiple selection mode. However, this property is ignored in other selection modes, so you can't turn on the check box in Extended or Single selection mode. You can set the CheckMode property to specify whether the check box is shown using the inline style or overlay style.

Inline: This style shows the check box to the left of the content, and colors the background of the item container to indicate selection. This is the default style for ListView. Overlay: This style shows the check box on top of the content, and colors only the border of the item container to indicate selection. This is the default style for GridView. This table shows the default visuals used to indicate selection. SELECTIONMODE:

SINGLE/EXTENDED

MULTIPLE

Inline

Overlay

NOTE In this and the following examples, simple string data items are shown without data templates to emphasize the visuals provided by the control template.

There are also several brush properties to change the colors of the check box. We'll look at these next along with other brush properties. Brushes

Many of the properties specify the brushes used for different visual states. You might want to modify these to match the color of your brand. This table shows the Common and Selection visual states for ListViewItem, and the brushes used to render the visuals for each state. The images show the effects of the brushes on both the inline and overlay selection visual styles. NOTE In this table, the modified color values for the brushes are hardcoded named colors and the colors are selected to make it more apparent where they are applied in the template. These are not the default colors for the visual states. If you modify the default colors in your app, you should use brush resources to modify the color values as done in the default template.

STATE/BRUSH NAME

Normal CheckBoxBrush="Red"

PointerOver PointerOverForeground="Da rkOrange" PointerOverBackground="Mi styRose" CheckBoxBrush="Red"

Pressed PressedBackground="LightC yan" PointerOverForeground="Dark Orange" CheckBoxBrush="Red"

Selected SelectedForeground="Navy" SelectedBackground="Khaki " CheckBrush="Green" CheckBoxBrush="Red" (inline only)

PointerOverSelected SelectedPointerOverBackgro und="Lavender" SelectedForeground="Navy" SelectedBackground="Khaki" (overlay only) CheckBrush="Green" CheckBoxBrush="Red" (inline only)

PressedSelected SelectedPressedBackground ="MediumTurquoise" SelectedForeground="Navy" SelectedBackground="Khaki" (overlay only) CheckBrush="Green" CheckBoxBrush="Red" (inline only)

INLINE STYLE

OVERLAY STYLE

STATE/BRUSH NAME

INLINE STYLE

OVERLAY STYLE

Focused FocusBorderBrush="Crimson " FocusSecondaryBorderBrush ="Gold" CheckBoxBrush="Red"

ListViewItemPresenter has other brush properties for data placeholders and drag states. If you use incremental loading or drag and drop in your list view, you should consider whether you need to also modify these additional brush properties. See the ListViewItemPresenter class for the complete list of properties you can modify. Expanded XAML item templates

If you need to make more modifications than what is allowed by the ListViewItemPresenter properties - if you need to change the position of the check box, for example - you can use the ListViewItemExpanded or GridViewItemExpanded templates. These templates are included with the default styles in generic.xaml. They follow the standard XAML pattern of building all the visuals from individual UIElements. As mentioned previously, the number of UIElements in an item template has a significant impact on the performance of your list view. Replacing ListViewItemPresenter with the expanded XAML templates greatly increases the element count, and is not recommended when your list view will show a large number of items or when performance is a concern. NOTE ListViewItemPresenter is supported only when the list view’s ItemsPanel is an ItemsWrapGrid or ItemsStackPanel. If you change the ItemsPanel to use VariableSizedWrapGrid, WrapGrid, or StackPanel, then the item template is automatically switched to the expanded XAML template. For more info, see ListView and GridView UI optimization.

To customize an expanded XAML template, you need to make a copy of it in your app, and set the ItemContainerStyle property to your copy. To copy the expanded template 1. Set the ItemContainerStyle property as shown here for your ListView or GridView. xaml

2. In the Visual Studio Properties pane, expand the Miscellaneous section and find the ItemContainerStyle property. (Make sure the ListView or GridView is selected.) 3. Click the property marker for the ItemContainerStyle property. (It’s the small box next to the TextBox. It’s coloreed green to show that it’s set to a StaticResource.) The property menu opens. 4. In the property menu, click Convert to New Resource.

5. In the Create Style Resource dialog, enter a name for the resource and click OK. A copy of the expanded template from generic.xaml is created in your app, which you can modify as needed.

Related articles Lists ListView and GridView

Inverted lists 3/6/2017 • 1 min to read • Edit on GitHub

You can use a list view to present a conversation in a chat experience with items that are visually distinct to represent the sender/receiver. Using different colors and horizontal alignment to separate messages from the sender/receiver helps the user quickly orient themselves in a conversation. You will typically need to present the list such that it appears to grow from the bottom up instead of from the top down. When a new message arrives and is added to the end, the previous messages slide up to make room drawing the user’s attention to the latest arrival. However, if a user has scrolled up to view previous replies then the arrival of a new message must not cause a visual shift that would disrupt their focus.

Important APIs ListView class ItemsStackPanel class ItemsUpdatingScrollMode property

Create an inverted list To create an inverted list, use a list view with an ItemsStackPanel as its items panel. On the ItemsStackPanel, set the ItemsUpdatingScrollMode to KeepLastItemInView.

IMPORTANT The KeepLastItemInView enum value is available starting with Windows 10, version 1607. You can't use this value when your app runs on earlier versions of Windows 10.

This example shows how to align the list view’s items to the bottom and indicate that when there is a change to the items the last item should remain in view. XAML

Do's and don'ts Align messages from the sender/receiver on opposite sides to make the flow of conversation clear to users. Animate the existing messages out of the way to display the latest message if the user is already at the end of the conversation awaiting the next message. Don’t disrupt the users focus by moving items if they’re not reading the end of the conversation.

Pull to refresh 3/6/2017 • 7 min to read • Edit on GitHub

The pull-to-refresh pattern lets a user pull down on a list of data using touch in order to retrieve more data. Pull-torefresh is widely used on mobile apps, but is useful on any device with a touch screen. You can handle manipulation events to implement pull-to-refresh in your app. The pull-to-refresh sample shows how to extend a ListView control to support this pattern. In this article, we use this sample to explain the key points of implementing pull-to-refresh.

Is this the right pattern? Use the pull-to-refresh pattern when you have a list or grid of data that the user might want to refresh regularly, and your app is likely to be running on mobile, touch-first devices.

Implement pull-to-refresh To implement pull-to-refresh, you need to handle manipulation events to detect when a user has pulled the list down, provide visual feedback, and refresh the data. Here, we look at how this is done in the pull-to-refresh sample. We don't show all the code here, so you should download the sample or view the code on GitHub. The pull-to-refresh sample creates a custom control called RefreshableListView that extends the ListView control. This control adds a refresh indicator to provide visual feedback and handles the manipulation events on the list view's internal scroll viewer. It also adds 2 events to notify you when the list is pulled and when the data should be refreshed. RefreshableListView only provides notification that the data should be refreshed. You need to handle the event in your app to update the data, and that code will be different for every app. RefreshableListView provides an 'auto refresh' mode that determines when the refresh is requested and how the refresh indicator goes out of view. Auto refresh can be on or off. Off: A refresh is requested only if the list is released while the PullThreshold is exceded. The indicator animates out of view when the user releases the scroller. The status bar indicator is shown if it's available (on phone). On: A refresh is requested as soon as the PullThreshold is exceded, whether released or not. The indicator remains in view until the new data is retrieved, then animates out of view. A Deferral is used to notify the app when fetching the data is complete. Note The code in sample is also applicable to a GridView. To modify a GridView, derive the custom class from GridView instead of ListView and modify the default GridView template.

Add a refresh indicator It's important to provide visual feedback to the user so they know that your app supports pull-to-refresh. RefreshableListView has a RefreshIndicatorContent property that lets you set the indicator visual in your XAML. It also includes a default text indicator that it falls back to if you don't set the RefreshIndicatorContent . Here are recommended guidelines for the refresh indicator.

Modify the list view template In the pull-to-refresh sample, the RefreshableListView control template modifies the standard ListView template by adding a refresh indicator. The refresh indicator is placed in a Grid above the ItemsPresenter, which is the part that shows the list items. Note The

text box provides a text fallback indicator that is shown only if the property is not set.

DefaultRefreshIndicatorContent

RefreshIndicatorContent

Here's the part of the control template that's modified from the default ListView template. XAML

Set the content in XAML You set the content of the refresh indicator in the XAML for your list view. The XAML content you set is displayed by the refresh indicator's ContentPresenter ( ). If you don't set this content, the default text indicator is shown instead.

XAML

Animate the spinner When the list is pulled down, RefreshableListView's PullProgressChanged event occurs. You handle this event in your app to control the refresh indicator. In the sample, this storyboard is started to animate the indicator's RotateTransform and spin the refresh indicator. XAML

Handle scroll viewer manipulation events The list view control template includes a built-in ScrollViewer that lets a user scroll through the list items. To implement pull-to-refresh, you have to handle the manipulation events on the built-in scroll viewer, as well as several related events. For more info about manipulation events, see Touch interactions. ** OnApplyTemplate** To get access to the scroll viewer and other template parts so that you can add event handlers and call them later in your code, you must override the OnApplyTemplate method. In OnApplyTemplate, you call GetTemplateChild

to get a reference to a named part in the control template, which you can save to use later in your code. In the sample, the variables used to store the template parts are declared in the Private Variables region. After they are retrieved in the OnApplyTemplate method, event handlers are added for the DirectManipulationStarted, DirectManipulationCompleted, ViewChanged, and PointerPressed events. DirectManipulationStarted In order to initiate a pull-to-refresh action, the content has to be scrolled to the top of the scroll viewer when the user starts to pull down. Otherwise, it's assumed that the user is pulling in order to pan up in the list. The code in this handler determines whether the manipulation started with the content at the top of the scroll viewer, and can result in the list being refreshed. The control's 'refreshable' status is set accordingly. If the control can be refreshed, event handlers for animations are also added. DirectManipulationCompleted When the user stops pulling the list down, the code in this handler checks whether a refresh was activated during the manipulation. If a refresh was activated, the RefreshRequested event is raised and the RefreshCommand command is executed. The event handlers for animations are also removed. Based on the value of the AutoRefresh property, the list can animate back up immediately, or wait until the refresh is complete and then animate back up. A Deferral object is used to to mark the completion of the refresh. At that point the refresh indicator UI is hidden. This part of the DirectManipulationCompleted event handler raises the if needed.

RefreshRequested

event and get's the Deferral

C# if (this.RefreshRequested != null) { RefreshRequestedEventArgs refreshRequestedEventArgs = new RefreshRequestedEventArgs( this.AutoRefresh ? new DeferralCompletedHandler(RefreshCompleted) : null); this.RefreshRequested(this, refreshRequestedEventArgs); if (this.AutoRefresh) { m_scrollerContent.ManipulationMode = ManipulationModes.None; if (!refreshRequestedEventArgs.WasDeferralRetrieved) { // The Deferral object was not retrieved in the event handler. // Animate the content up right away. this.RefreshCompleted(); } } }

ViewChanged Two cases are handled in the ViewChanged event handler. First, if the view changed due to the scroll viewer zooming, the control's 'refreshable' status is canceled. Second, if the content finished animating up at the end of an auto refresh, the padding rectangles are hidden, touch interactions with the scroll viewer are re-anabled, the VerticalOffset is set to 0. PointerPressed Pull-to-refresh happens only when the list is pulled down by a touch manipulation. In the PointerPressed event handler, the code checks what kind of pointer caused the event and sets a variable ( m_pointerPressed ) to indicate

whether it was a touch pointer. This variable is used in the DirectManipulationStarted handler. If the pointer is not a touch pointer, the DirectManipulationStarted handler returns without doing anything.

Add pull and refresh events 'RefreshableListView' adds 2 events that you can handle in your app to refresh the data and manage the refresh indicator. For more info about events, see Events and routed events overview. RefreshRequested The 'RefreshRequested' event notifies your app that the user has pulled the list to refresh it. You handle this event to fetch new data and update your list. Here's the event handler from the sample. The important thing to notice is that it check's the list view's AutoRefresh property and get's a Deferral if it's true. With a Deferral, the refresh indicator is not stopped and hidden until the refresh is complete. C# private async void listView_RefreshRequested(object sender, RefreshableListView.RefreshRequestedEventArgs e) { using (Deferral deferral = listView.AutoRefresh ? e.GetDeferral() : null) { await FetchAndInsertItemsAsync(_rand.Next(1, 5)); if (SpinnerStoryboard.GetCurrentState() != Windows.UI.Xaml.Media.Animation.ClockState.Stopped) { SpinnerStoryboard.Stop(); } } }

PullProgressChanged In the sample, content for the refresh indicator is provided and controlled by the app. The 'PullProgressChanged' event notifies your app when the use is pulling the list so that you can start, stop, and reset the refresh indicator.

Composition animations By default, content in a scroll viewer stops when the scrollbar reaches the top. To let the user continue to pull the list down, you need to access the visual layer and animate the list content. The sample uses composition animations for this; specifically, expression animations. In the sample, this work is done primarily in the UpdateCompositionAnimations method.

Related articles Styling controls Touch interactions List view and grid view List view item templates Expression animations

CompositionTarget_Rendering

event handler and the

Nested UI in list items 3/6/2017 • 10 min to read • Edit on GitHub

Nested UI is a user interface (UI) that exposes nested actionable controls enclosed inside a container that also can take independent focus. You can use nested UI to present a user with additional options that help accelerate taking important actions. However, the more actions you expose, the more complicated your UI becomes. You need to take extra care when you choose to use this UI pattern. This article provides guidelines to help you determine the best course of action for your particular UI. In this article, we discuss the creation of nested UI in ListView and GridView items. While this section does not talk about other nested UI cases, these concepts are transferrable. Before you start, you should be familiar with the general guidance for using ListView or GridView controls in your UI, which is found in the Lists and List view and grid view articles. In this article, we use the terms list, list item, and nested UI as defined here: List refers to a collection of items contained in a list view or grid view. List item refers to an individual item that a user can take action on in a list. Nested UI refers to UI elements within a list item that a user can take action on separate from taking action on the list item itself.

NOTE ListView and GridView both derive from the ListViewBase class, so they have the same functionality, but display data differently. In this article, when we talk about lists, the info applies to both the ListView and GridView controls.

Primary and secondary actions When creating UI with a list, consider what actions the user might take from those list items. Can a user click on the item to perform an action? Typically, clicking a list item initiates an action, but it doesn't have too.

Is there more than one action the user can take? For example, tapping an email in a list opens that email. However, there might be other actions, like deleting the email, that the user would want to take without opening it first. It would benefit the user to access this action directly in the list. How should the actions be exposed to the user? Consider all input types. Some forms of nested UI work great with one method of input, but might not work with other methods. The primary action is what the user expects to happen when they press the list item. Secondary actions are typically accelerators associated with list items. These accelerators can be for list management or actions related to the list item.

Options for secondary actions When creating list UI, you first need to make sure you account for all input methods that UWP supports. For more info about different kinds of input, see Input primer. After you have made sure that your app supports all inputs that UWP supports, you should decide if your app’s secondary actions are important enough to expose as accelerators in the main list. Remember that the more actions you expose, the more complicated your UI becomes. Do you really need to expose the secondary actions in the main list UI, or can you put them somewhere else? You might consider exposing additional actions in the main list UI when those actions need to be accessible by any input at all times. If you decide that putting secondary actions in the main list UI is not necessary, there are several other ways you can expose them to the user. Here are some options you can consider for where to place secondary actions. Put secondary actions on the detail page

Put the secondary actions on the page that the list item navigates to when it’s pressed. When you use the master/details pattern, the detail page is often a good place to put secondary actions. For more info, see the Master/detail pattern. Put secondary actions in a context menu

Put the secondary actions in a context menu that the user can access via right-click or press-and-hold. This provides the benefit of letting the user perform an action, such as deleting an email, without having to load the detail page. It's a good practice to also make these options available on the detail page, as context menus are intended to be accelerators rather than primary UI. To expose secondary actions when input is from a gamepad or remote control, we recommend that you use a context menu. For more info, see Context menus and flyouts. Put secondary actions in hover UI to optimize for pointer input

If you expect your app to be used frequently with pointer input such as mouse and pen, and want to make secondary actions readily available only to those inputs, then you can show the secondary actions only on hover. This accelerator is visible only when a pointer input is used, so be sure to use the other options to support other input types as well.

For more info, see Mouse interactions.

UI placement for primary and secondary actions If you decide that secondary actions should be exposed in the main list UI, we recommend the following guidelines. When you create a list item with primary and secondary actions, place the primary action to the left and secondary actions to the right. In left-to-right reading cultures, users associate actions on the left side of list item as the primary action. In these examples, we talk about list UI where the item flows more horizontally (it is wider than its height). However, you might have list items that are more square in shape, or taller than their width. Typically, these are items used in a grid. For these items, if the list doesn't scroll vertically, you can place the secondary actions at the bottom of the list item rather than to the right side.

Consider all inputs When deciding to use nested UI, also evaluate the user experience with all input types. As mentioned earlier, nested UI works great for some input types. However, it does not always work great for some other. In particular, keyboard, controller, and remote inputs can have difficulty accessing nested UI elements. Be sure to follow the guidance below to ensure your UWP works with all input types.

Nested UI handling When you have more than one action nested in the list item, we recommend this guidance to handle navigation with a keyboard, gamepad, remote control, or other non-pointer input. Nested UI where list items perform an action

If your list UI with nested elements supports actions such as invoking, selection (single or multiple), or drag-anddrop operations, we recommend these arrowing techniques to navigate through your nested UI elements.

Gamepad When input is from a gamepad, provide this user experience: From A, right directional key puts focus on B. From B, right directional key puts focus on C. From C, right directional key is either no op, or if there is a focusable UI element to the right of List, put the focus there. From C, left directional key puts focus on B. From B, left directional key puts focus on A. From A, left directional key is either no op, or if there is a focusable UI element to the right of List, put the focus there. From A, B, or C, down directional key puts focus on D. From UI element to the left of List Item, right directional key puts focus on A. From UI element to the right of List Item, left directional key puts focus on A. Keyboard When input is from a keyboard, this is the experience user gets:

From A, tab key puts focus on B. From B, tab key puts focus on C. From C, tab key puts focus on next focusable UI element in the tab order. From C, shift+tab key puts focus on B. From B, shift+tab or left arrow key puts focus on A. From A, shift+tab key puts focus on next focusable UI element in the reverse tab order. From A, B, or C, down arrow key puts focus on D. From UI element to the left of List Item, tab key puts focus on A. From UI element to the right of List Item, shift tab key puts focus on C. To achieve this UI, set IsItemClickEnabled to true on your list. SelectionMode can be any value. For the code to implement this, see the Example section of this article. Nested UI where list items do not perform an action

You might use a list view because it provides virtualization and optimized scrolling behavior, but not have an action associated with a list item. These UIs typically use the list item only to group elements and ensure they scroll as a set. This kind of UI tends to be much more complicated than the previous examples, with a lot of nested elements that the user can take action on.

To achieve this UI, set the following properties on your list: SelectionMode to None. IsItemClickEnabled to false. IsFocusEngagementEnabled to true.



When the list items do not perform an action, we recommend this guidance to handle navigation with a gamepad or keyboard. Gamepad When input is from a gamepad, provide this user experience: From List Item, down directional key puts focus on next List Item. From List Item, left/right key is either no op, or if there is a focusable UI element to the right of List, put the focus there. From List Item, 'A' button puts the focus on Nested UI in top/down left/right priority. While inside Nested UI, follow the XY Focus navigation model. Focus can only navigate around Nested UI contained inside the current List Item until user presses 'B' button, which puts the focus back onto the List Item. Keyboard When input is from a keyboard, this is the experience user gets: From List Item, down arrow key puts focus on the next List Item. From List Item, pressing left/right key is no op. From List Item, pressing tab key puts focus on the next tab stop amongst the Nested UI item. From one of the Nested UI items, pressing tab traverses the nested UI items in tab order. Once all the Nested UI items are traveled to, it puts the focus onto the next control in tab order after ListView. Shift+Tab behaves in reverse direction from tab behavior.

Example This example shows how to implement nested UI where list items perform an action.

private void OnListViewItemKeyDown(object sender, KeyRoutedEventArgs e) { // Code to handle going in/out of nested UI with gamepad and remote only. if (e.Handled == true) { return; } var focusedElementAsListViewItem = FocusManager.GetFocusedElement() as ListViewItem; if (focusedElementAsListViewItem != null) { // Focus is on the ListViewItem. // Go in with Right arrow. Control candidate = null; switch (e.OriginalKey) { case Windows.System.VirtualKey.GamepadDPadRight: case Windows.System.VirtualKey.GamepadLeftThumbstickRight:

case Windows.System.VirtualKey.GamepadLeftThumbstickRight: var rawPixelsPerViewPixel = DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel; GeneralTransform generalTransform = focusedElementAsListViewItem.TransformToVisual(null); Point startPoint = generalTransform.TransformPoint(new Point(0, 0)); Rect hintRect = new Rect(startPoint.X * rawPixelsPerViewPixel, startPoint.Y * rawPixelsPerViewPixel, 1, focusedElementAsListViewItem.ActualHeight * rawPixelsPerViewPixel); candidate = FocusManager.FindNextFocusableElement(FocusNavigationDirection.Right, hintRect) as Control; break; } if (candidate != null) { candidate.Focus(FocusState.Keyboard); e.Handled = true; } } else { // Focus is inside the ListViewItem. FocusNavigationDirection direction = FocusNavigationDirection.None; switch (e.OriginalKey) { case Windows.System.VirtualKey.GamepadDPadUp: case Windows.System.VirtualKey.GamepadLeftThumbstickUp: direction = FocusNavigationDirection.Up; break; case Windows.System.VirtualKey.GamepadDPadDown: case Windows.System.VirtualKey.GamepadLeftThumbstickDown: direction = FocusNavigationDirection.Down; break; case Windows.System.VirtualKey.GamepadDPadLeft: case Windows.System.VirtualKey.GamepadLeftThumbstickLeft: direction = FocusNavigationDirection.Left; break; case Windows.System.VirtualKey.GamepadDPadRight: case Windows.System.VirtualKey.GamepadLeftThumbstickRight: direction = FocusNavigationDirection.Right; break; default: break; } if (direction != FocusNavigationDirection.None) { Control candidate = FocusManager.FindNextFocusableElement(direction) as Control; if (candidate != null) { ListViewItem listViewItem = sender as ListViewItem; // If the next focusable candidate to the left is outside of ListViewItem, // put the focus on ListViewItem. if (direction == FocusNavigationDirection.Left && !listViewItem.IsAncestorOf(candidate)) { listViewItem.Focus(FocusState.Keyboard); } else { candidate.Focus(FocusState.Keyboard); } } e.Handled = true; } } } private void listview1_ChoosingItemContainer(ListViewBase sender, ChoosingItemContainerEventArgs args) {

if (args.ItemContainer == null) { args.ItemContainer = new ListViewItem(); args.ItemContainer.KeyDown += OnListViewItemKeyDown; } }

// DependencyObjectExtensions.cs definition. public static class DependencyObjectExtensions { public static bool IsAncestorOf(this DependencyObject parent, DependencyObject child) { DependencyObject current = child; bool isAncestor = false; while (current != null && !isAncestor) { if (current == parent) { isAncestor = true; } current = VisualTreeHelper.GetParent(current); } return isAncestor; } }

Master/details pattern 3/6/2017 • 2 min to read • Edit on GitHub

The master/details pattern has a master pane (usually with a list view) and a details pane for content. When an item in the master list is selected, the details pane is updated. This pattern is frequently used for email and address books.

Is this the right pattern? The master/details pattern works well if you want to: Build an email app, address book, or any app that is based on a list-details layout. Locate and prioritize a large collection of content. Allow the quick addition and removal of items from a list while working back-and-forth between contexts.

Choose the right style When implementing the master/details pattern, we recommend that you use either the stacked style or the sideby-side style, based on the amount of available screen space. AVAILABLE WINDOW WIDTH

RECOMMENDED STYLE

320 epx-719 epx

Stacked

720 epx or wider

Side-by-side

Stacked style In the stacked style, only one pane is visible at a time: the master or the details.

The user starts at the master pane and "drills down" to the details pane by selecting an item in the master list. To the user, it appears as though the master and details views exist on two separate pages. Create a stacked master/details pattern

One way to create the stacked master/details pattern is to use separate pages for the master pane and the details pane. Place the list view that provides the master list on one page, and the content element for the details pane on a separate page.

For the master pane, a list view control works well for presenting lists that can contain images and text. For the details pane, use the content element that makes the most sense. If you have a lot of separate fields, consider using a grid layout to arrange elements into a form.

Side-by-side style In the side-by-side style, the master pane and details pane are visible at the same time.

The list in the master pane has a selection visual to indicate the currently selected item. Selecting a new item in the master list updates the details pane. Create a side-by-side master/details pattern

For the master pane, a list view control works well for presenting lists that can contain images and text. For the details pane, use the content element that makes the most sense. If you have a lot of separate fields, consider using a grid layout to arrange elements into a form.

Examples This design of an app that tracks the stock market uses a master/details pattern. In this example of the app as it would appear on phone, the master pane/list is on the left, with the details pane on the right.

This design of an app that tracks the stock market uses a master/details pattern. In this example of the app as it would appear on desktop, the master pane/list and details pane are both visible and full-screen. The master pane features a search box at the top and a command bar at the bottom.

For sample code that shows the master/details pattern, see

ListView and GridView sample RSS Reader sample

Related articles Lists Search App and command bars ListView class (XAML)

Media player 3/6/2017 • 11 min to read • Edit on GitHub

The media player is used to view and listen to video and audio. Media playback can be inline (embedded in a page or with a group of other controls) or in a dedicated full-screen view. You can modify the player's button set, change the background of the control bar, and arrange layouts as you see fit. Just keep in mind that users expect a basic control set (play/pause, skip back, skip forward).

Important APIs MediaPlayerElement class MediaTransportControls class

Note MediaPlayerElement is only available in Windows 10, version 1607 and up. If you are developing an app for an earlier version of Windows 10 you will need to use MediaElement instead. All of the recommendations on this page apply to MediaElement as well.

Is this the right control? Use a media player when you want to play audio or video in your app. To display a collection of images, use a Flip view.

Examples A media player in the Windows 10 Get Started app.

Create a media player Add media to your app by creating a MediaPlayerElement object in XAML and set the Source to a MediaSource that points to an audio or video file. This XAML creates a MediaPlayerElement and sets its Source property to the URI of a video file that's local to the app. The MediaPlayerElement begins playing when the page loads. To suppress media from starting right away, you can set the AutoPlay property to false.

This XAML creates a MediaPlayerElement with the built in transport controls enabled and the AutoPlay property set to false.

Media transport controls

[MediaPlayerElement] ((https://msdn.microsoft.com/library/windows/apps/windows.ui.xaml.controls.mediaplayerelement.aspx) has built in transport controls that handle play, stop, pause, volume, mute, seeking/progress, closed captions, and audio track selection. To enable these controls, set AreTransportControlsEnabled to true. To disable them, set AreTransportControlsEnabled to false. The transport controls are represented by the MediaTransportControls class. You can use the transport controls as-is, or customize them in various ways. For more info, see the MediaTransportControls class reference and Create custom transport controls. The transport controls support single- and double-row layouts. The first example here is a single-row layout, with the play/pause button located to the left of the media timeline. This layout is best reserved for inline media playback and compact screens.

The double-row controls layout (below) is recommended for most usage scenarios, especially on larger screens. This layout provides more space for controls and makes the timeline easier for the user to operate.

System media transport controls MediaPlayerElement is automatically integrated with the system media transport controls. The system media transport controls are the controls that pop up when hardware media keys are pressed, such as the media buttons on keyboards. For more info, see SystemMediaTransportControls. Note MediaElement does not automatically integrate with the system media transport controls so you must connect them yourself. For more information, see System Media Transport Controls. Set the media source

To play files on the network or files embedded with the app, set the Source property to a MediaSource with the path of the file. Tip To open files from the internet, you need to declare the Internet (Client) capability in your app's manifest (Package.appxmanifest). For more info about declaring capabilities, see App capability declarations. This code attempts to set the Source property of the MediaPlayerElement defined in XAML to the path of a file entered into a TextBox.

private void TxtFilePath_KeyUp(object sender, KeyRoutedEventArgs e) { if (e.Key == Windows.System.VirtualKey.Enter) { TextBox tbPath = sender as TextBox; if (tbPath != null) { LoadMediaFromString(tbPath.Text); } } } private void LoadMediaFromString(string path) { try { Uri pathUri = new Uri(path); mediaPlayer.Source = MediaSource.CreateFromUri(pathUri); } catch (Exception ex) { if (ex is FormatException) { // handle exception. // For example: Log error or notify user problem with file } } }

To set the media source to a media file embedded in the app, initialize a Uri with the path prefixed with msappx:///, create a MediaSource with the Uri and then set the Source to the Uri. For example, for a file called video1.mp4 that is in a Videos subfolder, the path would look like: ms-appx:///Videos/video1.mp4 This code sets the Source property of the MediaPlayerElement defined previously in XAML to msappx:///Videos/video1.mp4. private void LoadEmbeddedAppFile() { try { Uri pathUri = new Uri("ms-appx:///Videos/video1.mp4"); mediaPlayer.Source = MediaSource.CreateFromUri(pathUri); } catch (Exception ex) { if (ex is FormatException) { // handle exception. // For example: Log error or notify user problem with file } } }

Open local media files

To open files on the local system or from OneDrive, you can use the FileOpenPicker to get the file and Source to set the media source, or you can programmatically access the user media folders. If your app needs access without user interaction to the Music or Video folders, for example, if you are enumerating all the music or video files in the user's collection and displaying them in your app, then you need to declare the Music Library and Video Library capabilities. For more info, see Files and folders in the Music, Pictures, and Videos libraries.

The FileOpenPicker does not require special capabilities to access files on the local file system, such as the user's Music or Video folders, since the user has complete control over which file is being accessed. From a security and privacy standpoint, it is best to minimize the number of capabilities your app uses. To open local media using FileOpenPicker 1. Call FileOpenPicker to let the user pick a media file. Use the FileOpenPicker class to select a media file. Set the FileTypeFilter to specify which file types the FileOpenPicker displays. Call PickSingleFileAsync to launch the file picker and get the file. 2. Use a MediaSource to set the chosen media file as the MediaPlayerElement.Source. To use the StorageFile returned from the FileOpenPicker, you need to call the CreateFromStorageFile method on MediaSource and set it as the Source of MediaPlayerElement. Then call Play on the MediaPlayerElement.MediaPlayer to start the media. This example shows how to use the FileOpenPicker to choose a file and set the file as the Source of a MediaPlayerElement. ...

private async void Button_Click(object sender, RoutedEventArgs e) { await SetLocalMedia(); } async private System.Threading.Tasks.Task SetLocalMedia() { var openPicker = new Windows.Storage.Pickers.FileOpenPicker(); openPicker.FileTypeFilter.Add(".wmv"); openPicker.FileTypeFilter.Add(".mp4"); openPicker.FileTypeFilter.Add(".wma"); openPicker.FileTypeFilter.Add(".mp3"); var file = await openPicker.PickSingleFileAsync(); // mediaPlayer is a MediaPlayerElement defined in XAML if (file != null) { mediaPlayer.Source = MediaSource.CreateFromStorageFile(file); mediaPlayer.MediaPlayer.Play(); } }

Set the poster source

You can use the PosterSource property to provide your MediaPlayerElement with a visual representation before the media is loaded. A PosterSource is an image, such as a screen shot or movie poster, that is displayed in place of the media. The PosterSource is displayed in the following situations: When a valid source is not set. For example, Source is not set, Source was set to Null, or the source is invalid (as is the case when a MediaFailed event occurs). While media is loading. For example, a valid source is set, but the MediaOpened event has not occurred yet. When media is streaming to another device. When the media is audio only.

Here's a MediaPlayerElement with its Source set to an album track, and it's PosterSource set to an image of the album cover.

Keep the device's screen active

Typically, a device dims the display (and eventually turns it off) to save battery life when the user is away, but video apps need to keep the screen on so the user can see the video. To prevent the display from being deactivated when user action is no longer detected, such as when an app is playing video, you can call DisplayRequest.RequestActive. The DisplayRequest class lets you tell Windows to keep the display turned on so the user can see the video. To conserve power and battery life, you should call DisplayRequest.RequestRelease to release the display request when it is no longer required. Windows automatically deactivates your app's active display requests when your app moves off screen, and re-activates them when your app comes back to the foreground. Here are some situations when you should release the display request: Video playback is paused, for example, by user action, buffering, or adjustment due to limited bandwidth. Playback stops. For example, the video is done playing or the presentation is over. A playback error has occurred. For example, network connectivity issues or a corrupted file. Note If MediaPlayerElement.IsFullWindow is set to true and media is playing, the display will automatically be prevented from deactivating. To keep the screen active 1. Create a global DisplayRequest variable. Initialize it to null. // Create this variable at a global scope. Set it to null. private DisplayRequest appDisplayRequest = null;

2. Call RequestActive to notify Windows that the app requires the display to remain on. 3. Call RequestRelease to release the display request whenever video playback is stopped, paused, or interrupted by a playback error. When your app no longer has any active display requests, Windows saves battery life by dimming the display (and eventually turning it off) when the device is not being used. Each MediaPlayerElement.MediaPlayer has a PlaybackSession of type MediaPlaybackSession that controls various aspects of media playback such as PlaybackRate, PlaybackState and Position. Here, you use the PlaybackStateChanged event on MediaPlayer.PlaybackSession to detect situations when you should release the display request. Then, use the NaturalVideoHeight property to determine whether an audio or video file is playing, and keep the screen active only if video is playing.

protected override void OnNavigatedTo(NavigationEventArgs e) { mpe.MediaPlayer.PlaybackSession.PlaybackStateChanged += MediaPlayerElement_CurrentStateChanged; base.OnNavigatedTo(e); } private void MediaPlayerElement_CurrentStateChanged(object sender, RoutedEventArgs e) { MediaPlaybackSession playbackSession = sender as MediaPlaybackSession; if (playbackSession != null && playbackSession.NaturalVideoHeight != 0) { if(playbackSession.PlaybackState == MediaPlaybackState.Playing) { if(appDisplayRequest == null) { // This call creates an instance of the DisplayRequest object appDisplayRequest = new DisplayRequest(); appDisplayRequest.RequestActive(); } } else // PlaybackState is Buffering, None, Opening or Paused { if(appDisplayRequest != null) { // Deactivate the displayr request and set the var to null appDisplayRequest.RequestRelease(); appDisplayRequest = null; } } } }

Control the media player programmatically

MediaPlayerElement provides numerous properties, methods, and events for controlling audio and video playback through the MediaPlayerElement.MediaPlayer property. For a full listing of properties, methods, and events, see the MediaPlayer reference page. Advanced media playback scenarios

For more complex media playback scenarios like playing a playlist, switching between audio languages or creating custom metadata tracks set the MediaPlayerElement.Source to a MediaPlaybackItem or a MediaPlaybackList. See the Media playback page in the dev center for more information on how to enable various advanced media functionality. Enable full window video rendering

Set the IsFullWindow property to enable and disable full window rendering. When you programmatically set full window rendering in your app, you should always use IsFullWindow instead of doing it manually. IsFullWindow insures that system level optimizations are performed that improve performance and battery life. If full window rendering is not set up correctly, these optimizations may not be enabled. Here is some code that creates an AppBarButton that toggles full window rendering. >

private void FullWindow_Click(object sender, object e) { mediaPlayer.IsFullWindow = !media.IsFullWindow; }

Resize and stretch video

Use the Stretch property to change how the video content and/or the PosterSource fills the container it's in. This resizes and stretches the video depending on the Stretch value. The Stretch states are similar to picture size settings on many TV sets. You can hook this up to a button and allow the user to choose which setting they prefer. None displays the native resolution of the content in its original size. Uniform fills up as much of the space as possible while preserving the aspect ratio and the image content. This can result in horizontal or vertical black bars at the edges of the video. This is similar to wide-screen modes. UniformToFill fills up the entire space while preserving the aspect ratio. This can result in some of the image being cropped. This is similar to full-screen modes. Fill fills up the entire space, but does not preserve the aspect ratio. None of image is cropped, but stretching may occur. This is similar to stretch modes.

Here, an AppBarButton is used to cycle through the Stretch options. A switch statement checks the current state of the Stretch property and sets it to the next value in the Stretch enumeration. This lets the user cycle through the different stretch states.

private void PictureSize_Click(object sender, RoutedEventArgs e) { switch (mediaPlayer.Stretch) { case Stretch.Fill: mediaPlayer.Stretch = Stretch.None; break; case Stretch.None: mediaPlayer.Stretch = Stretch.Uniform; break; case Stretch.Uniform: mediaPlayer.Stretch = Stretch.UniformToFill; break; case Stretch.UniformToFill: mediaPlayer.Stretch = Stretch.Fill; break; default: break; } }

Enable low-latency playback

Set the RealTimePlayback property to true on a MediaPlayerElement.MediaPlayer to enable the media player element to reduce the initial latency for playback. This is critical for two-way communications apps, and can be applicable to some gaming scenarios. Be aware that this mode is more resource intensive and less powerefficient. This example creates a MediaPlayerElement and sets RealTimePlayback to true. MediaPlayerElement mp = new MediaPlayerElement(); mp.MediaPlayer.RealTimePlayback = true;

Recommendations The media player supports both light and dark themes, but dark theme provides a better experience for most entertainment scenarios. The dark background provides better contrast, in particular for low-light conditions, and limits the control bar from interfering in the viewing experience. When playing video content, encourage a dedicated viewing experience by promoting full-screen mode over inline mode. The full-screen viewing experience is optimal, and options are restricted in the inline mode. If you have the screen real estate or are designing for the 10-foot experience, go with the double-row layout. It provides more space for controls than the compact single-row layout and it is easier to navigate using gamepad for 10-foot. Note Visit the Designing for Xbox and TV article for more information on optimizing your application for the 10-foot experience. The default controls have been optimized for media playback, however you have the ability to add custom options you need to the media player in order to provide the best experience for you app. Visit Create custom transport controls to learn more about adding custom controls.

Related articles Command design basics for UWP apps Content design basics for UWP apps

Create custom transport controls 3/6/2017 • 9 min to read • Edit on GitHub

MediaPlayerElement has customizable XAML transport controls to manage control of audio and video content within a Universal Windows Platform (UWP) app. Here, we demonstrate how to customize the MediaTransportControls template. We’ll show you how to work with the overflow menu, add a custom button and modify the slider. Before starting, you should be familiar with the MediaPlayerElement and the MediaTransportControls classes. For more info, see the MediaPlayerElement control guide. TIP The examples in this topic are based on the Media Transport Controls sample. You can download the sample to view and run the completed code.

Important APIs MediaPlayerElement MediaPlayerElement.AreTransportControlsEnabled MediaTransportControls

NOTE MediaPlayerElement is only available in Windows 10, version 1607 and up. If you are developing an app for an earlier version of Windows 10 you will need to use MediaElement instead. All of the examples on this page work with MediaElement as well.

When should you customize the template? MediaPlayerElement has built-in transport controls that are designed to work well without modification in most video and audio playback apps. They’re provided by the MediaTransportControls class and include buttons to play, stop, and navigate media, adjust volume, toggle full screen, cast to a second device, enable captions, switch audio tracks, and adjust the playback rate. MediaTransportControls has properties that let you control whether each button is shown and enabled. You can also set the IsCompact property to specify whether the controls are shown in one row or two. However, there may be scenarios where you need to further customize the look of the control or change its behavior. Here are some examples: Change the icons, slider behavior, and colors. Move less commonly used command buttons into an overflow menu. Change the order in which commands drop out when the control is resized. Provide a command button that’s not in the default set.

NOTE The buttons visible on screen will drop out of the built-in transport controls in a predefined order if there is not enough room on screen. To change this ordering or put commands that don't fit into an overflow menu, you will need to customize the controls.

You can customize the appearance of the control by modifying the default template. To modify the control's behavior or add new commands, you can create a custom control that's derived from MediaTransportControls. TIP Customizable control templates are a powerful feature of the XAML platform, but there are also consequences that you should take into consideration. When you customize a template, it becomes a static part of your app and therefore will not receive any platform updates that are made to the template by Microsoft. If template updates are made by Microsoft, you should take the new template and re-modify it in order to get the benefits of the updated template.

Template structure The ControlTemplate is part of the default style. The transport control's default style is shown in the MediaTransportControls class reference page. You can copy this default style into your project to modify it. The ControlTemplate is divided into sections similar to other XAML control templates. The first section of the template contains the Style definitions for the various components of the MediaTransportControls. The second section defines the various visual states that are used by the MediaTransportControls. The third section contains the Grid that holds that various MediaTransportControls elements together and defines how the components are laid out. NOTE For more info about modifying templates, see [Control templates](). You can use a text editor or similar editors in your IDE to open the XAML files in (Program Files)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\(SDK version)\Generic. The default style and template for each control is defined in the generic.xaml file. You can find the MediaTransportControls template in generic.xaml by searching for "MediaTransportControls".

In the following sections, you learn how to customize several of the main elements of the transport controls: Slider: allows a user to scrub through their media and also displays progress CommandBar: contains all of the buttons. For more info, see the Anatomy section of the MediaTransportControls reference topic.

Customize the transport controls If you want to modify only the appearance of the MediaTransportControls, you can create a copy of the default control style and template, and modify that. However, if you also want to add to or modify the functionality of the control, you need to create a new class that derives from MediaTransportControls. Re-template the control

To customize the MediaTransportControls default style and template 1. Copy the default style from MediaTransportControls styles and templates into a ResourceDictionary in your project. 2. Give the Style an x:Key value to identify it, like this.

xaml

3. Add a MediaPlayerElement with MediaTransportControls to your UI. 4. Set the Style property of the MediaTransportControls element to your custom Style resource, as shown here. xaml

For more info about modifying styles and templates, see [Styling controls]() and [Control templates](). Create a derived control

To add to or modify the functionality of the transport controls, you must create a new class that's derived from MediaTransportControls. A derived class called CustomMediaTransportControls is shown in the Media Transport Controls sample and the remaining examples on this page. To create a new class derived from MediaTransportControls 1. Add a new class file to your project. In Visual Studio, select Project > Add Class. The Add New Item dialog opens. In the Add New Item dialog, enter a name for the class file, then click Add. (In the Media Transport Controls sample, the class is named CustomMediaTransportControls .) 2. Modify the class code to derive from the MediaTransportControls class. csharp public sealed class CustomMediaTransportControls : MediaTransportControls { }

3. Copy the default style for MediaTransportControls into a ResourceDictionary in your project. This is the style and template you modify. (In the Media Transport Controls sample, a new folder called "Themes" is created, and a ResourceDictionary file called generic.xaml is added to it.) 4. Change the TargetType of the style to the new custom control type. (In the sample, the TargetType is changed to local:CustomMediaTransportControls .) xaml xmlns:local="using:CustomMediaTransportControls"> ...

5. Set the DefaultStyleKey of your custom class. This tells your custom class to use a Style with a TargetType of local:CustomMediaTransportControls . csharp public sealed class CustomMediaTransportControls : MediaTransportControls { public CustomMediaTransportControls() { this.DefaultStyleKey = typeof(CustomMediaTransportControls); } }

6. Add a MediaPlayerElement to your XAML markup and add the custom transport controls to it. One thing to note is that the APIs to hide, show, disable, and enable the default buttons still work with a customized template. xaml

You can now modify the control style and template to update the look of your custom control, and the control code to update its behavior. Working with the overflow menu

You can move MediaTransportControls command buttons into an overflow menu, so that less commonly used commands are hidden until the user needs them. In the MediaTransportControls template, the command buttons are contained in a CommandBar element. The command bar has the concept of primary and secondary commands. The primary commands are the buttons that appear in the control by default and are always visible (unless you disable the button, hide the button or there is not enough room). The secondary commands are shown in an overflow menu that appears when a user clicks the ellipsis (…) button. For more info, see the App bars and command bars article. To move an element from the command bar primary commands to the overflow menu, you need to edit the XAML control template. To move a command to the overflow menu:

1. In the control template, find the CommandBar element named MediaControlsCommandBar . 2. Add a SecondaryCommands section to the XAML for the CommandBar. Put it after the closing tag for the PrimaryCommands. xaml ... ... ...

3. To populate the menu with commands, cut and paste the XAML for the desired AppBarButton objects from the PrimaryCommands to the SecondaryCommands. In this example, we move the PlaybackRateButton to the overflow menu. 4. Add a label to the button and remove the styling information, as shown here. Because the overflow menu is comprised of text buttons, you must add a text label to the button and also remove the style that sets the height and width of the button. Otherwise, it won't appear correctly in the overflow menu.

IMPORTANT You must still make the button visible and enable it in order to use it in the overflow menu. In this example, the PlaybackRateButton element isn't visible in the overflow menu unless the IsPlaybackRateButtonVisible property is true. It's not enabled unless the IsPlaybackRateEnabled property is true. Setting these properties is shown in the previous section.

Adding a custom button

One reason you might want to customize MediaTransportControls is to add a custom command to the control. Whether you add it as a primary command or a secondary command, the procedure for creating the command button and modifying its behavior is the same. In the Media Transport Controls sample, a "rating" button is added to the primary commands. To add a custom command button 1. Create an AppBarButton object and add it to the CommandBar in the control template.

You must add it to the CommandBar in the appropriate location. (For more info, see the Working with the overflow menu section.) How it's positioned in the UI is determined by where the button is in the markup. For example, if you want this button to appear as the last element in the primary commands, add it at the very end of the primary commands list. You can also customize the icon for the button. For more info, see the AppBarButton reference. 2. In the OnApplyTemplate override, get the button from the template and register a handler for its Click event. This code goes in the CustomMediaTransportControls class.

public sealed class CustomMediaTransportControls : MediaTransportControls { // ... protected override void OnApplyTemplate() { // Find the custom button and create an event handler for its Click event. var likeButton = GetTemplateChild("LikeButton") as Button; likeButton.Click += LikeButton_Click; base.OnApplyTemplate(); } //... }

3. Add code to the Click event handler to perform the action that occurs when the button is clicked. Here's the complete code for the class. public sealed class CustomMediaTransportControls : MediaTransportControls { public event EventHandler< EventArgs> Liked; public CustomMediaTransportControls() { this.DefaultStyleKey = typeof(CustomMediaTransportControls); } protected override void OnApplyTemplate() { // Find the custom button and create an event handler for its Click event. var likeButton = GetTemplateChild("LikeButton") as Button; likeButton.Click += LikeButton_Click; base.OnApplyTemplate(); } private void LikeButton_Click(object sender, RoutedEventArgs e) { // Raise an event on the custom control when 'like' is clicked. var handler = Liked; if (handler != null) { handler(this, EventArgs.Empty); } } }

Custom media transport controls with a "Like" button added

Modifying the slider

The "seek" control of the MediaTransportControls is provided by a Slider element. One way you can customize it is to change the granularity of the seek behavior. The default seek slider is divided into 100 parts, so the seek behavior is limited to that many sections. You can change the granularity of the seek slider by getting the Slider from the XAML visual tree in your MediaOpened event handler on MediaPlayerElement.MediaPlayer. This example shows how to use VisualTreeHelper to get a reference to the Slider, then change the default step frequency of the slider from 1% to 0.1% (1000 steps) if the

media is longer than 120 minutes. The MediaPlayerElement is named

MediaPlayerElement1

.

protected override void OnNavigatedTo(NavigationEventArgs e) { MediaPlayerElement1.MediaPlayer.MediaOpened += MediaPlayerElement_MediaPlayer_MediaOpened; base.OnNavigatedTo(e); } private void MediaPlayerElement_MediaPlayer_MediaOpened(object sender, RoutedEventArgs e) { FrameworkElement transportControlsTemplateRoot = (FrameworkElement)VisualTreeHelper.GetChild(MediaPlayerElement1.TransportControls, 0); Slider sliderControl = (Slider)transportControlsTemplateRoot.FindName("ProgressSlider"); if (sliderControl != null && MediaPlayerElement1.NaturalDuration.TimeSpan.TotalMinutes > 120) { // Default is 1%. Change to 0.1% for more granular seeking. sliderControl.StepFrequency = 0.1; } }

Related articles Media playback

Menus and context menus 3/6/2017 • 3 min to read • Edit on GitHub

Menus and context menus display a list of commands or options when the user requests them.

Important APIs MenuFlyout class ContextFlyout property FlyoutBase.AttachedFlyout property

Is this the right control? Menus and context menus save space by organizing commands and hiding them until the user needs them. If a particular command will be used frequently and you have the space available, consider placing it directly in its own element, rather than in a menu, so that users don't have to go through a menu to get to it. Menus and context menus are for organizing commands; to display arbitrary content, such as an notification or to request confirmation, use a dialog or a flyout.

Menus vs. context menus Menus and context menus are identical in how they look and what they can contain. In fact, you use the same control, MenuFlyout, to create them. The only difference is how you let the user access it. When should you use a menu or a context menu? If the host element is a button or some other command element who's primary role is to present additional commands, use a menu. If the host element is some other type of element that has another primary purpose (such as presenting text or an image), use a context menu. For example, use a menu on a button in a navigation pane to provide additional navigation options. In this scenario, the primary purpose of the button control is to provide access to a menu. If you want to add commands (such as cut, copy, and paste) to a text element, use a context menu instead of a menu. In this scenario, the primary role of the text element is to present and edit text; additional commands (such as cut, copy, and paste) are secondary and belong in a context menu.

Menus Have a single entry point (a File menu at the top of the screen, for example) that is always displayed. Are usually attached to a button or a parent menu item. Are invoked by left-clicking (or an equivalent action, such as tapping with your finger). Are associated with an element via its Flyout or FlyoutBase.AttachedFlyout properties.

Context menus Are attched to a single element, but are only accessible when the context makes sense. Are invoked by right clicking (or an equavent action, such as pressing and holding with your finger). Are associated with an element via its ContextFlyout property.

Create a menu or a context menu To create a menu or a content menu, you use the MenuFlyout class. You define the contents of the menu by adding MenuFlyoutItem, ToggleMenuFlyoutItem, and MenuFlyoutSeparator objects to the MenuFlyout. These objects are for: MenuFlyoutItem—Performing an immediate action. ToggleMenuFlyoutItem—Switching an option on or off. MenuFlyoutSeparator—Visually separating menu items. This example creates a MenuFlyout class and uses the ContextFlyout property, a property available to most controls, to show the MenuFlyout class as a context menu.

private void ChangeColorItem_Click(object sender, RoutedEventArgs e) { // Change the color from red to blue or blue to red. if (rectangleFill.Color == Windows.UI.Colors.Red) { rectangleFill.Color = Windows.UI.Colors.Blue; } else { rectangleFill.Color = Windows.UI.Colors.Red; } }

The next example is nearly identical, but instead of using the ContextFlyout property to show the MenuFlyout class as a context menu, the example uses the FlyoutBase.ShowAttachedFlyout property to show it as a menu.

private void Rectangle_Tapped(object sender, TappedRoutedEventArgs e) { FlyoutBase.ShowAttachedFlyout((FrameworkElement)sender); } private void ChangeColorItem_Click(object sender, RoutedEventArgs e) { // Change the color from red to blue or blue to red. if (rectangleFill.Color == Windows.UI.Colors.Red) { rectangleFill.Color = Windows.UI.Colors.Blue; } else { rectangleFill.Color = Windows.UI.Colors.Red; } }

Light dismiss controls, such as menus, context menus, and other flyouts, trap keyboard and gamepad focus inside the transient UI until dismissed. To provide a visual cue for this behavior, light dismiss controls on Xbox will draw an overlay that dims the visibility of out of scope UI. This behavior can be modified with the new LightDismissOverlayMode property. By default, transient UIs will draw the light dismiss overlay on Xbox but not other device families, but apps can choose to force the overlay to be always On or always Off.

Get the sample code XAML UI basics sample

See all of the XAML controls in an interactive format.

Related articles MenuFlyout class

Nav panes 3/6/2017 • 4 min to read • Edit on GitHub

A navigation pane (or just "nav" pane) is a pattern that allows for many top-level navigation items while conserving screen real estate. The nav pane is widely used for mobile apps, but also works well on larger screens. When used as an overlay, the pane remains collapsed and out-of-the way until the user presses the button, which is handy for smaller screens. When used in its docked mode, the pane remains open, which allows greater utility if there's enough screen real estate.

Important APIs SplitView class

Is this the right pattern? The nav pane works well for: Apps with many top-level navigation items that are of similar type. For example, a sports app with categories like Football, Baseball, Basketball, Soccer, and so on. Providing a consistent navigational experience across apps. Nav pane should include only navigational elements, not actions. A medium-to-high number (5-10+) of top-level navigational categories. Preserving screen real estate (as an overlay). Navigation items that are infrequently accessed. (as an overlay).

Building a nav pane The nav pane pattern consists of a pane for navigation categories, a content area, and an optional button to open or close the pane. The easiest way to build a nav pane is with a split view control, which comes with an empty pane and a content area that's always visible. To try out code implementing this pattern, download the XAML Navigation solution from GitHub. Pane

Headers for navigational categories go in the pane. Entry points to app settings and account management, if applicable, also go in the pane. Navigation headers are usually a list of items for the user to choose from.

Content area

The content area is where information for the selected nav location is displayed. It can contain individual elements or other sub-level navigation. Button

When present, the button allows users to open and close the pane. The button remains visible in a fixed position and does not move with the pane. We recommend placing the button in the upper-left corner of your app. The nav pane button is visualized as three stacked horizontal lines and is commonly referred to as the "hamburger" button.

The button is usually associated with a text string. At the top level of the app, the app title can be displayed next to the button. At lower levels of the app, the text string may be the title of the page that the user is currently on.

Nav pane variations The nav pane has three modes: overlay, compact and inline. An overlay collapses and expands as needed. When compact, the pane always shows as a narrow sliver which can be expanded. An inline pane remains open by default.

Overlay

An overlay can be used on any screen size and in either portrait or landscape orientation. In its default (collapsed) state, the overlay takes up no real-estate, with only the button shown. Provides on-demand navigation that conserves screen real estate. Ideal for apps on phones and phablets. The pane is hidden by default, with only the button visible. Pressing the nav pane button opens and closes the overlay. The expanded state is transient and is dismissed when a selection is made, when the back button is used, or when the user taps outside of the pane. The overlay draws over the top of content and does not reflow content. Compact

Compact mode can be specified as CompactOverlay , which overlays content when opened, or CompactInline , which pushes content out of its way. We recommend using CompactOverlay. Compact panes provide some indication of the selected location while using a small amount of screen realestate. This mode is better suited for medium screens like tablets. By default, the pane is closed with only navigation icons and the button visible. Pressing the nav pane button opens and closes the pane, which behaves like overlay or inline depending on the specified display mode. The selection should be shown on the list icons to highlight where the user is in the navigation tree. Inline

The navigation pane remains open. This mode is better suited for larger screens. Supports drag-and-drop scenarios to and from the pane. The nav pane button is not required for this state. If the button is used, then the content area is pushed out and the content within that area will reflow. The selection should be shown on the list items to highlight where the user is in the navigation tree.

Adaptability To maximize usability on a variety of devices, we recommend utilizing break points and adjusting nav pane's mode based on the width of its app window. Small window Less than or equal to 640px wide. Nav pane should be in overlay mode, closed by default. Medium window Greater than 640px and less than or equal to 1007px wide. Nav pane should be in sliver mode, closed by default. Large window Greater than 1007px wide. Nav pane should be in docked mode, opened by default.

Tailoring To optimize your app's 10ft experience, consider tailoring nav pane by altering the visual appearance of its navigational elements. Depending on the interaction context, it may be more important to call the user's attention to either the selected nav item or to the focused nav item. For 10ft experience, where gamepad is the most common input device, ensuring that the user can easily keep track of the currently focused item's location on screen is particularly important.

Related topics Split view control Master/details Navigation basics

Progress controls 3/6/2017 • 5 min to read • Edit on GitHub

A progress control provides feedback to the user that a long-running operation is underway. It can mean that the user cannot interact with the app when the progress indicator is visible, and can also indicate how long the wait time might be, depending on the indicator used. Important APIs ProgressBar class IsIndeterminate property ProgressRing class IsActive property

Types of progress There are two controls to show the user that an operation is underway – either through a ProgressBar or through a ProgressRing. The ProgressBar determinate state shows the percentage completed of a task. This should be used during an operation whose duration is known, but it's progress should not block the user's interaction with the app. The ProgressBar indeterminate state shows that an operation is underway, does not block user interaction with the app, and its completion time is unknown. The ProgressRing only has an indeterminate state, and should be used when any further user interaction is blocked until the operation has completed. Additionally, a progress control is read only, and not interactive. Meaning that the user cannot invoke or use these controls directly.

Top to bottom - Indeterminate ProgressBar and a determinate ProgressBar

An indeterminate ProgressRing

When to use each control It's not always obvious what control or what state (determinate vs indeterminate) to use when trying to show something is happening. Sometimes a task is obvious enough that it doesn’t require a progress control at all – and sometimes even if a progress control is used, a line of text is still necessary in order to explain to the user what operation is underway. ProgressBar

Does the control have a defined duration or predictable end? Use a determinate ProgressBar then, and update the percentage or value accordingly. Can the user continue without having to monitor the operation’s progress? When a ProgressBar is in use, interaction is non-modal, typically meaning that the user is not blocked by that operation’s completion, and can continue to use the app in other ways until that aspect has completed. Keywords If your operation falls around these keywords, or if you’re showing text that alongside the progress operation that matches these keywords; consider using a ProgressBar: Loading... Retrieving Working... ProgressRing

Will the operation cause the user to wait to continue? If an operation requires all (or a large portion of) interaction with the app to wait until it has been completed, then the ProgressRing is the better choice. The ProgressRing control is used for modal interactions, meaning that the user is blocked until the ProgressRing disappears. Is the app waiting for the user to complete a task? If so, use a ProgressRing, as they’re meant to indicate an unknown wait time for the user. Keywords If your operation falls around these keywords, or if you’re showing text alongside the progress operation that matches these keywords; consider using a ProgressRing: Refreshing Signing in... Connecting... No progress indication necessary

Does the user need to know that something is happening? For example, if the app is downloading something in the background and the user didn’t initiate the download, the user doesn’t necessarily need to know about it. Is the operation a background activity that doesn't block user activity and is of minimal (but still some) interest to the user? Use text when your app is performing tasks that don't have to be visible all the time, but you still need to show the status. Does the user only care about the completion of the operation? Sometimes it’s best to show a notice only when the operation is completed, or give a visual that the operation has been completed immediately, and run the finishing touches in the background.

Progress controls best practices Sometimes it’s best to see some visual representations of when and where to use these different progress controls:

ProgressBar - Determinate

The first example is the determinate ProgressBar. When the duration of the operation is known, when installing, downloading, setting up, etc; a determinate ProgressBar is best. ProgressBar - Indeterminate

When it is not known how long the operation will take, use an indeterminate ProgressBar. Indeterminate ProgressBars are also good when filling a virtualized list, and creating a smooth visual transition between an indeterminate to determinate ProgressBar. Is the operation in a virtualized collection? If so, do not put a progress indicator on each list item as they appear. Instead, use a ProgressBar and place it at the top of the collection of items being loaded in, to show that the items are being fetched. ProgressRing - Indeterminate

The indeterminate ProgressRing is used when any further user interaction with the app is halted, or the app is waiting for the user’s input to continue. The “signing in…” example above is a perfect scenario for the ProgressRing, the user cannot continue using the app until the sign is has completed.

Customizing a progress control

Both progress controls are rather simple; but some visual features of the controls are not obvious to customize. Sizing the ProgressRing The ProgressRing can be sized as large as you want, but can only be as small as 20x20epx. In order to resize a ProgressRing, you must set its height and width. If only height or width are set, the control will assume minimum sizing (20x20epx) – conversely if the height and width are set to two different sizes, the smaller of the sizes will be assumed. To ensure your ProgressRing is correct for your needs, set bother the height and the width to the same value:

To make your ProgressRing visible, and animate, you must set the IsActive property to true:

progressRing.IsActive = true;

Coloring the progress controls By default, the main coloring of the progress controls is set to the accent color of the system. To override this brush simply change the foreground property on either control.

Changing the foreground color for the ProgressRing will change the colors of the dots. The foreground property for the ProgressBar will change the fill color of the bar – to alter the unfilled portion of the bar, simply override the background property. Showing a wait cursor Sometimes it’s best to just show a brief wait cursor, when the app or operation needs time to think, and you need to indicate to the user that the app or area where the wait cursor is visible should not be interacted with until the wait cursor has disappeared. Window.Current.CoreWindow.PointerCursor = new Windows.UI.Core.CoreCursor(Windows.UI.Core.CoreCursorType.Wait, 10);

Related articles ProgressBar class ProgressRing class For developers (XAML) Adding progress controls How to create a custom indeterminate progress bar for Windows Phone

Radio buttons 3/6/2017 • 5 min to read • Edit on GitHub

Radio buttons let users select one option from two or more choices. Each option is represented by one radio button; a user can select only one radio button in a radio button group. (If you're curious about the name, radio buttons are named for the channel preset buttons on a radio.)

Important APIs RadioButton class Checked event IsChecked property

Is this the right control? Use radio buttons to present users with two or more mutually exclusive options, as here.

Radio buttons add clarity and weight to very important options in your app. Use radio buttons when the options being presented are important enough to command more screen space and where the clarity of the choice demands very explicit options. Radio buttons emphasize all options equally, and that may draw more attention to the options than necessary. Consider using other controls, unless the options deserve extra attention from the user. For example, if the default option is recommended for most users in most situations, use a drop-down list instead. If there are only two mutually exclusive options, combine them into a single checkbox or toggle switch. For example, use a checkbox for "I agree" instead of two radio buttons for "I agree" and "I don't agree."

When the user can select multiple options, use a checkbox or list box control instead.

Don't use radio buttons when the options are numbers that have fixed steps, like 10, 20, 30. Use a slider control instead. If there are more than 8 options, use a drop-down list, a single-select list box, or a list box instead. If the available options are based on the app’s current context, or can otherwise vary dynamically, use a singleselect list box instead.

Example Radio buttons in the Microsoft Edge browser settings.

Create a radio button Radio buttons work in groups. There are 2 ways you can group radio button controls: Put them inside the same parent container. Set the GroupName property on each radio button to the same value. Note A group of radio buttons behaves like a single control when accessed via the keyboard. Only the selected choice is accessible using the Tab key but users can cycle through the group using arrow keys. In this example, the first group of radio buttons is implicitly grouped by being in the same stack panel. The second group is divided between 2 stack panels, so they're explicitly grouped by GroupName.



private void BGRadioButton_Checked(object sender, RoutedEventArgs e) { RadioButton rb = sender as RadioButton; if (rb != null && BorderExample1 != null) { string colorName = rb.Tag.ToString(); switch (colorName) { case "Yellow": BorderExample1.Background = new SolidColorBrush(Colors.Yellow); break; case "Green": BorderExample1.Background = new SolidColorBrush(Colors.Green); break; case "Blue": BorderExample1.Background = new SolidColorBrush(Colors.Blue); break; case "White": BorderExample1.Background = new SolidColorBrush(Colors.White); break; } } } private void BorderRadioButton_Checked(object sender, RoutedEventArgs e) { RadioButton rb = sender as RadioButton; if (rb != null && BorderExample1 != null) { string colorName = rb.Tag.ToString(); switch (colorName) { case "Yellow": BorderExample1.BorderBrush = new SolidColorBrush(Colors.Gold); break; case "Green": BorderExample1.BorderBrush = new SolidColorBrush(Colors.DarkGreen); break; case "Blue": BorderExample1.BorderBrush = new SolidColorBrush(Colors.DarkBlue); break; case "White": BorderExample1.BorderBrush = new SolidColorBrush(Colors.White); break; } } }

The radio button groups look like this.

A radio button has two states: selected or cleared. When a radio button is selected, its IsChecked property is true. When a radio button is cleared, its IsChecked property is false. A radio button can be cleared by clicking

another radio button in the same group, but it cannot be cleared by clicking it again. However, you can clear a radio button programmatically by setting its IsChecked property to false.

Recommendations Make sure that the purpose and current state of a set of radio buttons is clear. Always give visual feedback when the user taps a radio button. Give visual feedback as the user interacts with radio buttons. Normal, pressed, checked, and disabled are examples of radio button states. A user taps a radio button to activate the related option. Tapping an activated option doesn’t deactivate it, but tapping another option transfers activation to that option. Reserve visual effects and animations for touch feedback, and for the checked state; in the unchecked state, radio button controls should appear unused or inactive (but not disabled). Limit the radio button’s text content to a single line. You can customize the radio button’s visuals to display a description of the option in smaller font size below the main line of text. If the text content is dynamic, consider how the button will resize and what will happen to visuals around it. Use the default font unless your brand guidelines tell you to use another. Enclose the radio button in a label element so that tapping the label selects the radio button. Place the label text after the radio button control, not before or above it. Consider customizing your radio buttons. By default, a radio button consists of two concentric circles—the inner one filled (and shown when the radio button is checked), the outer one stroked—and some text content. But we encourage you to be creative. Users are comfortable interacting directly with the content of an app. So you may choose to show the actual content on offer, whether that’s presented with graphics or as subtle textual toggle buttons. Don't put more than 8 options in a radio button group. When you need to present more options, use a dropdown list, list box, or a list view instead. Don't put two radio button groups next to each other. When two radio button groups are right next to each other, it's difficult to determine which buttons belong to which group. Use group labels to separate them.

Additional usage guidance This illustration shows the proper way to position and space radio buttons.

Related topics For designers Guidelines for buttons Guidelines for toggle switches Guidelines for checkboxes Guidelines for drop-down lists Guidelines for list view and grid view controls Guidelines for sliders

Guidelines for the select control For developers (XAML) Windows.UI.Xaml.Controls RadioButton class

Scroll bars 3/6/2017 • 4 min to read • Edit on GitHub

Panning and scrolling allows users to reach content that extends beyond the bounds of the screen. A scroll viewer control is composed of as much content as will fit in the viewport, and either one or two scroll bars. Touch gestures can be used to pan and zoom (the scroll bars fade in only during manipulation), and the pointer can be used to scroll. The flick gesture pans with inertia. Note Windows has two scroller visualizations, which are based on the user's input mode: scroll indicators when using touch or gamepad; and interactive scroll bars for other input devices including mouse, keyboard, and pen.

Important APIs ScrollViewer class ScrollBar class

Examples A ScrollViewer enables content to be displayed in a smaller area than its actual size. When the content of the scroll viewer is not entirely visible, the scroll viewer displays scrollbars that the user can use to move the content area that is visible. The area that includes all of the content of the scroll viewer is the extent. The visible area of the content is the viewport.

Create a scroll viewer To add vertical scrolling to your page, wrap the page content in a scroll viewer.



This XAML shows how to place an image in a scroll viewer and enable zooming.

ScrollViewer in a control template It's typical for a ScrollViewer control to exist as a composite part of other controls. A ScrollViewer part, along with the ScrollContentPresenter class for support, will display a viewport along with scrollbars only when the host control's layout space is being constrained smaller than the expanded content size. This is often the case for lists, so ListView and GridView templates always include a ScrollViewer. TextBox and RichEditBox also include a ScrollViewer in their templates. When a ScrollViewer part exists in a control, the host control often has built-in event handling for certain input events and manipulations that enable the content to scroll. For example, a GridView interprets a swipe gesture and this causes the content to scroll horizontally. The input events and raw manipulations that the host control receives are considered handled by the control, and lower-level events such as PointerPressed won't be raised and won't bubble to any parent containers either. You can change some of the built-in control handling by overriding a control class and the On* virtual methods for events, or by retemplating the control. But in either case it's not trivial to reproduce the original default behavior, which is typically there so that the control reacts in expected ways to events and to a user's input actions and gestures. So you should consider whether you really need that input event to fire. You might want to investigate whether there are other input events or gestures that are not being handled by the control, and use those in your app or control interaction design. To make it possible for controls that include a ScrollViewer to influence some of the behavior and properties that are from within the ScrollViewer part, ScrollViewer defines a number of XAML attached properties that can be set in styles and used in template bindings. For more info about attached properties, see Attached properties overview. ScrollViewer XAML attached properties ScrollViewer defines the following XAML attached properties: ScrollViewer.BringIntoViewOnFocusChange ScrollViewer.HorizontalScrollBarVisibility ScrollViewer.HorizontalScrollMode ScrollViewer.IsDeferredScrollingEnabled ScrollViewer.IsHorizontalRailEnabled ScrollViewer.IsHorizontalScrollChainingEnabled ScrollViewer.IsScrollInertiaEnabled

ScrollViewer.IsVerticalRailEnabled ScrollViewer.IsVerticalScrollChainingEnabled ScrollViewer.IsZoomChainingEnabled ScrollViewer.IsZoomInertiaEnabled ScrollViewer.VerticalScrollBarVisibility ScrollViewer.VerticalScrollMode ScrollViewer.ZoomMode These XAML attached properties are intended for cases where the ScrollViewer is implicit, such as when the ScrollViewer exists in the default template for a ListView or GridView, and you want to be able to influence the scrolling behavior of the control without accessing template parts. For example, here's how to make the vertical scroll bars always visible for a ListView's built in scroll viewer.

For cases where a ScrollViewer is explicit in your XAML, as is shown in the example code, you don't need to use attached property syntax. Just use attribute syntax, for example .

Do's and don'ts Whenever possible, design for vertical scrolling rather than horizontal. Use one-axis panning for content regions that extend beyond one viewport boundary (vertical or horizontal). Use two-axis panning for content regions that extend beyond both viewport boundaries (vertical and horizontal). Use the built-in scroll functionality in the list view, grid view, combo box, list box, text input box, and hub controls. With those controls, if there are too many items to show all at once, the user is able to scroll either horizontally or vertically over the list of items. If you want the user to pan in both directions around a larger area, and possibly to zoom, too, for example, if you want to allow the user to pan and zoom over a full-sized image (rather than an image sized to fit the screen) then place the image inside a scroll viewer. If the user will scroll through a long passage of text, configure the scroll viewer to scroll vertically only. Use a scroll viewer to contain one object only. Note that the one object can be a layout panel, in turn containing any number of objects of its own. Don't place a Pivot control inside a scroll viewer to avoid conflicts with pivot's scrolling logic.

Related topics For developers (XAML) ScrollViewer class

Search and find-in-page 3/6/2017 • 7 min to read • Edit on GitHub

Search is one of the top ways users can find content in your app. The guidance in this article covers elements of the search experience, search scopes, implementation, and examples of search in context. Important APIs AutoSuggestBox class (XAML)

Elements of the search experience Input. Text is the most common mode of search input and is the focus of this guidance. Other common input modes include voice and camera, but these typically require the ability to interface with device hardware and may require additional controls or custom UI within the app. Zero input. Once the user has activated the input field, but before the user has entered text, you can display what's called a "zero input canvas." The zero input canvas will commonly appear in the app canvas, so that autosuggest replaces this content when the user begins to input their query. Recent search history, trending searches, contextual search suggestions, hints and tips are all good candidates for the zero input state.

Query formulation/auto-suggest. Query formulation replaces zero input content as soon as the user begins to enter input. As the user enters a query string, they are provided with a continuously updated set of query suggestions or disambiguation options to help them expedite the input process and formulate an effective query. This behavior of query suggestions is built into the auto-suggest control, and is also a way to show the icon inside the search (like a microphone or a commit icon). Any behavior outside of this falls to the app.

Results set. Search results commonly appear directly under the search input field. While this isn't a requirement, the juxtaposition of input and results maintains context and provides the user with immediate access to edit the previous query or enter a new query. This connection can be further communicated by replacing the hint text with the query that created the results set. One method to enable efficient access to both edit the previous query and enter a new query is to highlight the previous query when the field is reactivated. This way, any keystroke will replace the previous string, but the string is maintained so that the user can position a cursor to edit or append the previous string. The results set can appear in any form that best communicates the content. A list view provides a good deal of flexibility and is well-suited to most searches. A grid view works well for images or other media, and a map can be used to communicate spatial distribution.

Search scopes Search is a common feature, and users will encounter search UI in the shell and within many apps. Although search entry points tend to be similarly visualized, they can provide access to results that range from broad (web or device searches) to narrow (a user's contact list). The search entry point should be juxtaposed against the content being searched. Some common search scopes include: Global and contextual/refine. Search across multiple sources of cloud and local content. Varied results include URLs, documents, media, actions, apps, and more. Web. Search a web index. Results include pages, entities, and answers. My stuff. Search across device(s), cloud, social graphs, and more. Results are varied, but are constrained by the connection to user account(s). Use hint text to communicate search scope. Examples include: "Search Windows and the Web" "Search contacts list" "Search mailbox" "Search settings" "Search for a place"

By effectively communicating the scope of a search input point, you can help to ensure that the user expectation will be met by the capabilities of the search you are performing and reduce the possibility of frustration.

Implementation For most apps, it's best to have a text input field as the search entry point, which provides a prominent visual footprint. In addition, hint text helps with discoverability and communicating the search scope. When search is a more secondary action, or when space is constrained, the search icon can serve as an entry point without the accompanying input field. When visualized as an icon, be sure that there's room for a modal search box, as seen in the below examples. Before clicking search icon:

After clicking search icon:

Search always uses a right-pointing magnifying glass glyph for the entry point. The glyph to use is Segoe UI Symbol, hex character code 0xE0094, and usually at 15 epx font size. The search entry point can be placed in a number of different areas, and its placement communicates both search scope and context. Searches that gather results from across an experience or external to the app are typically located within top-level app chrome, such as global command bars or navigation. As the search scope becomes more narrow or contextual, the placement will typically be more directly associated with the content to be searched, such as on a canvas, as a list header, or within contextual command bars. In all cases, the connection between search input and results or filtered content should be visually clear. In the case of scrollable lists, it's helpful to always have search input be visible. We recommend making the search input sticky and have content scroll behind it. Zero input and query formulation functionality is optional for contextual/refine searches in which the list will be filtered in real-time by user input. Exceptions include cases where query formatting suggestions may be available, such as inbox filtering options (to:, from: , subject: , and so on).

Example The examples in this section show search placed in context. Search as an action in the Windows tool bar:

Search as an input on the app canvas:

Search in a navigation pane:

Inline search is best reserved for cases where search is infrequently accessed or is highly contextual:

Guidelines for find-in-page Find-in-page enables users to find text matches in the current body of text. Document viewers, readers, and browsers are the most typical apps that provide find-in-page.

Do's and don'ts Place a command bar in your app with find-in-page functionality to let the user search for on-page text. For placement details, see the Examples section. Apps that provide find-in-page should have all necessary controls in a command bar. If your app includes a lot of functionality beyond find-in-page, you can provide a Find button in the toplevel command bar as an entry point to another command bar that contains all of your find-in-page controls. The find-in-page command bar should remain visible when the user is interacting with the touch keyboard. The touch keyboard appears when a user taps the input box. The find-in-page command bar should move up, so it's not obscured by the touch keyboard. Find-in-page should remain available while the user interacts with the view. Users need to interact with the in-view text while using find-in-page. For example, users may want to zoom in or out of a document or pan the view to read the text. Once the user starts using find-in-page, the command bar should remain available with a Close button to exit find-in-page. Enable the keyboard shortcut (CTRL+F). Implement the keyboard shortcut CTRL+F to enable the user to invoke the find-in-page command bar quickly. Include the basics of find-in-page functionality. These are the UI elements that you need in order to implement find-in-page: Input box Previous and Next buttons A match count Close (desktop-only) The view should highlight matches and scroll to show the next match on screen. Users can move quickly through the document by using the Previous and Next buttons and by using scroll bars or direct manipulation with touch.

Find-and-replace functionality should work alongside the basic find-in-page functionality. For apps that have find-and-replace, ensure that find-in-page doesn't interfere with find-and-replace functionality. Include a match counter to indicate to the user the number of text matches there are on the page. Enable the keyboard shortcut (CTRL+F).

Examples Provide an easy way to access the find-in-page feature. In this example on a mobile UI, "Find on page" appears after two "Add to..." commands in an expandable menu:

After selecting find-in-page, the user enters a search term. Text suggestions can appear when a search term is being entered:

If there isn't a text match in the search, a "No results" text string should appear in the results box:

If there is a text match in the search, the first term should be highlighted in a distinct color, with succeeding matches in a more subtle tone of that same color palette, as seen in this example:

Find-in-page has a match counter:

Implementing find-in-page Document viewers, readers, and browsers are the likeliest app types to provide find-in-page, and enable the user to have a full screen viewing/reading experience. Find-in-page functionality is secondary and should be located in a command bar. For more info about adding commands to your command bar, see Command bar.

Related articles Auto-suggest box

Semantic zoom 3/6/2017 • 5 min to read • Edit on GitHub

Semantic zoom lets the user switch between two different views of the same content so that they can quickly navigate through a large set of grouped data. The zoomed-in view is the main view of the content. This is the main view where you show individual data items. The zoomed-out view is a higher-level view of the same content. You typically show the group headers for a grouped data set in this view. For example, when viewing an address book, the user could zoom out to quickly jump to the letter "W", and zoom in on that letter to see the names associated with it. Important APIs SemanticZoom class ListView class GridView class

Features: The size of the zoomed-out view is constrained by the bounds of the semantic zoom control. Tapping on a group header toggles views. Pinching as a way to toggle between views can be enabled. Active headers switch between views.

Is this the right control? Use a SemanticZoom control when you need to show a grouped data set that's large enough that it can’t all be shown on one or two pages. Don't confuse semantic zooming with optical zooming. While they share both the same interaction and basic behavior (displaying more or less detail based on a zoom factor), optical zoom refers to the adjustment of magnification for a content area or object such as a photograph. For info about a control that performs optical zooming, see the ScrollViewer control.

Examples Photos app Here's a semantic zoom used in the Photos app. Photos are grouped by month. Selecting a month header in the default grid view zooms out to the month list view for quicker navigation.

Address book An address book is another example of a data set that can be much easier to navigate using semantic zoom. You can use the zoomed-out view to quickly jump to the letter you need (left image), while the zoomed-in view displays the individual data items (right image).

Create a semantic zoom The SemanticZoom control doesn’t have any visual representation of its own. It’s a host control that manages the transition between 2 other controls that provide the views of your content, typically ListView or GridView controls. You set the view controls to the ZoomedInView and ZoomedOutView properties of the SemanticZoom. The 3 elements you need for a semantic zoom are: A grouped data source A zoomed-in view that shows the item-level data. A zoomed-out view that shows the group-level data. Before you use a semantic zoom, you should understand how to use a list view with grouped data. For more info, see List view and grid view and [Grouping items in a list]().

Note To define the zoomed-in view and the zoomed-out view of the SemanticZoom control, you can use any two controls that implement the [ISemanticZoomInformation]() interface. The XAML framework provides 3 controls that implement this interface: ListView, GridView, and Hub. This XAML shows the structure of the SemanticZoom control. You assign other controls to the ZoomedInView and ZoomedOutView properties. XAML

The examples here are taken from the SemanticZoom page of the XAML UI Basics sample. You can download the sample to see the complete code incuding the data source. This semantic zoom uses a GridView to supply the zoomed-in view and a ListView for the zoomed-out view. Define the zoomed-in view Here's the GridView control for the zoomed-in view. The zoomed-in view should display the individual data items in groups. This example shows how to display the items in a grid with an image and text. XAML

The look of the group headers is defined in the defined in the ZoomedInTemplate resource. XAML

ZoomedInGroupHeaderTemplate

recsource. The look of the items is



Define the zoomed-out view This XAML defines a ListView control for the zoomed-out view. This example shows how to display the group headers as text in a list. XAML

The look is defined in the

ZoomedOutTemplate

resource.

XAML

Synchronize the views The zoomed-in view and zoomed-out view should be synchronized, so if a user selects a group in the zoomed-out view, the details of that same group are shown in the zoomed-in view. You can use a CollectionViewSource or add code to synchronize the views. Any controls that you bind to the same CollectionViewSource always have the same current item. If both views use the same CollectionViewSource as their data source, the CollectionViewSource synchronizes the views automatically. For more info, see CollectionViewSource. If you don't use a CollectionViewSource to synchronize the views, you should handle the ViewChangeStarted event and synchronize the items in the event handler, as shown here. XAML

C#

private void SemanticZoom_ViewChangeStarted(object sender, SemanticZoomViewChangedEventArgs e) { if (e.IsSourceZoomedInView == false) { e.DestinationItem.Item = e.SourceItem.Item; } }

Recommendations When using semantic zoom in your app, be sure that the item layout and panning direction don't change based on the zoom level. Layouts and panning interactions should be consistent and predictable across zoom levels. Semantic zoom enables the user to jump quickly to content, so limit the number of pages/screens to three in the zoomed-out mode. Too much panning diminishes the practicality of semantic zoom. Avoid using semantic zoom to change the scope of the content. For example, a photo album shouldn't switch to a folder view in File Explorer. Use a structure and semantics that are essential to the view. Use group names for items in a grouped collection. Use sort ordering for a collection that is ungrouped but sorted, such as chronological for dates or alphabetical for a list of names.

Get the sample code XAML UI Basics sample

Related articles Navigation design basics List view and grid view List view item templates

Sliders 3/6/2017 • 7 min to read • Edit on GitHub

A slider is a control that lets the user select from a range of values by moving a thumb control along a track.

Important APIs Slider class Value property ValueChanged event

Is this the right control? Use a slider when you want your users to be able to set defined, contiguous values (such as volume or brightness) or a range of discrete values (such as screen resolution settings). A slider is a good choice when you know that users think of the value as a relative quantity, not a numeric value. For example, users think about setting their audio volume to low or medium—not about setting the value to 2 or 5. Don't use a slider for binary settings. Use a toggle switch instead. Here are some additional factors to consider when deciding whether to use a slider: Does the setting seem like a relative quantity? If not, use radio buttons or a list box. Is the setting an exact, known numeric value? If so, use a numeric text box. Would a user benefit from instant feedback on the effect of setting changes? If so, use a slider. For example, users can choose a color more easily by immediately seeing the effect of changes to hue, saturation, or luminosity values. Does the setting have a range of four or more values? If not, use radio buttons. Can the user change the value? Sliders are for user interaction. If a user can't ever change the value, use read-only text instead. If you are deciding between a slider and a numeric text box, use a numeric text box if: Screen space is tight. The user is likely to prefer using the keyboard. Use a slider if: Users will benefit from instant feedback.

Examples A slider to control the volume on Windows Phone.

A slider to change text size in Windows display settings.

Create a slider Here's how to create a slider in XAML.

Here's how to create a slider in code. Slider volumeSlider = new Slider(); volumeSlider.Header = "Volume"; volumeSlider.Width = 200; volumeSlider.ValueChanged += Slider_ValueChanged; // Add the slider to a parent container in the visual tree. stackPanel1.Children.Add(volumeSlider);

You get and set the value of the slider from the Value property. To respond to value changes, you can use data binding to bind to the Value property, or handle the ValueChanged event.

private void Slider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e) { Slider slider = sender as Slider; if (slider != null) { media.Volume = slider.Value; } }

Recommendations Size the control so that users can easily set the value they want. For settings with discrete values, make sure the user can easily select any value using the mouse. Make sure the endpoints of the slider always fit within the bounds of a view. Give immediate feedback while or after a user makes a selection (when practical). For example, the Windows volume control beeps to indicate the selected audio volume. Use labels to show the range of values. Exception: If the slider is vertically oriented and the top label is Maximum, High, More, or equivalent, you can omit the other labels because the meaning is clear. Disable all associated labels or feedback visuals when you disable the slider. Consider the direction of text when setting the flow direction and/or orientation of your slider. Script flows from left to right in some languages, and from right to left in others. Don't use a slider as a progress indicator. Don't change the size of the slider thumb from the default size. Don't create a continuous slider if the range of values is large and users will most likely select one of several representative values from the range. Instead, use those values as the only steps allowed. For example if time value might be up to 1 month but users only need to pick from 1 minute, 1 hour, 1 day or 1 month, then create a slider with only 4 step points.

Additional usage guidance Choosing the right layout: horizontal or vertical

You can orient your slider horizontally or vertically. Use these guidelines to determine which layout to use. Use a natural orientation. For example, if the slider represents a real-world value that is normally shown vertically (such as temperature), use a vertical orientation. If the control is used to seek within media, like in a video app, use a horizontal orientation. When using a slider in page that can be panned in one direction (horizontally or vertically), use a different orientation for the slider than the panning direction. Otherwise, users might swipe the slider and change its value accidentally when they try to pan the page. If you're still not sure which orientation to use, use the one that best fits your page layout. Range direction

The range direction is the direction you move the slider when you slide it from its current value to its max value. For vertical slider, put the largest value at the top of the slider, regardless of reading direction. For example, for a volume slider, always put the maximum volume setting at the top of the slider. For other types of values (such as days of the week), follow the reading direction of the page. For horizontal styles, put the lower value on the left side of the slider for left-to-right page layout, and on the right for right-to-left page layout. The one exception to the previous guideline is for media seek bars: always put the lower value on the left side of the slider. Steps and tick marks

Use step points if you don't want the slider to allow arbitrary values between min and max. For example, if you use a slider to specify the number of movie tickets to buy, don't allow floating point values. Give it a step value of 1. If you specify steps (also known as snap points), make sure that the final step aligns to the slider's max value. Use tick marks when you want to show users the location of major or significant values. For example, a slider that controls a zoom might have tick marks for 50%, 100%, and 200%. Show tick marks when users need to know the approximate value of the setting. Show tick marks and a value label when users need to know the exact value of the setting they choose, without interacting with the control. Otherwise, they can use the value tooltip to see the exact value. Always show tick marks when step points aren't obvious. For example, if the slider is 200 pixels wide and has 200 snap points, you can hide the tick marks because users won't notice the snapping behavior. But if there are only 10 snap points, show tick marks. Labels

Slider labels The slider label indicates what the slider is used for. Use a label with no ending punctuation (this is the convention for all control labels). Position labels above the slider when the slider is in a form that places most of its labels above their controls. Position labels to the sides when the slider is in a form that places most of its labels to the side of their controls. Avoid placing labels below the slider because the user's finger might occlude the label when the user touches the slider. Range labels The range, or fill, labels describe the slider's minimum and maximum values. Label the two ends of the slider range, unless a vertical orientation makes this unnecessary. Use only one word, if possible, for each label. Don't use ending punctuation. Make sure these labels are descriptive and parallel. Examples: Maximum/Minimum, More/Less, Low/High, Soft/Loud. Value labels A value label displays the current value of the slider. If you need a value label, display it below the slider. Center the text relative to the control and include the units (such as pixels). Since the slider’s thumb is covered during scrubbing, consider showing the current value some other way, with a label or other visual. A slider setting text size could render some sample text of the right size beside the slider. Appearance and interaction

A slider is composed of a track and a thumb. The track is a bar (which can optionally show various styles of tick marks) representing the range of values that can be input. The thumb is a selector, which the user can position by either tapping the track or by scrubbing back and forth on it. A slider has a large touch target. To maintain touch accessibility, a slider should be positioned far enough away from the edge of the display. When you’re designing a custom slider, consider ways to present all the necessary info to the user with as little clutter as possible. Use a value label if a user needs to know the units in order to understand the setting; find

creative ways to represent these values graphically. A slider that controls volume, for example, could display a speaker graphic without sound waves at the minimum end of the slider, and a speaker graphic with sound waves at the maximum end.

Related topics Toggle switches Slider class

Split view control 3/6/2017 • 1 min to read • Edit on GitHub

A split view control has an expandable/collapsible pane and a content area. Important APIs SplitView class

Here is an example of the Microsoft Edge app using SplitView to show its Hub.

A split view's content area is always visible. The pane can expand and collapse or remain in an open state, and can present itself from either the left side or right side of an app window. The pane has four modes: Overlay The pane is hidden until opened. When open, the pane overlays the content area. Inline The pane is always visible and doesn't overlay the content area. The pane and content areas divide the available screen real estate. CompactOverlay A narrow portion of the pane is always visible in this mode, which is just wide enough to show icons. The default closed pane width is 48px, which can be modified with CompactPaneLength . If the pane is opened, it will overlay the content area. CompactInline A narrow portion of the pane is always visible in this mode, which is just wide enough to show icons. The default closed pane width is 48px, which can be modified with CompactPaneLength . If the pane is opened, it will reduce the space available for content, pushing the content out of its way.

Is this the right control? The split view control can be used to make a navigation pane. To build this pattern, add an expand/collapse button (the "hamburger" button) and a list view representing the nav items.

The split view control can also be used to create any "drawer" experience where users can open and close the supplemental pane.

Create a split view Here's a SplitView control with an open Pane appearing inline next to the Content.

Related topics Nav pane pattern List view

Pivot and tabs 3/6/2017 • 3 min to read • Edit on GitHub

The Pivot control and related tabs pattern are used for navigating frequently accessed, distinct content categories. Pivots allow for navigation between two or more content panes and relies on text headers to articulate the different sections of content.

Tabs are a visual variant of Pivot that use a combination of icons and text or just icons to articulate section content. Tabs are built using the Pivot control. The Pivot sample shows how to customize the Pivot control into the tabs pattern. Important APIs Pivot class

The pivot pattern When building an app with pivot, there are a few key design variables to consider. Header labels. Headers can have an icon with text, icon only, or text only. Header alignment. Headers can be left-justified or centered. Top-level or sub-level navigation. Pivots can be used for either level of navigation. Optionally, navigation pane can serve as the primary level with pivot acting as secondary. Touch gesture support. For devices that support touch gestures, you can use one of two interaction sets to navigate between content categories: 1. Tap on a tab/pivot header to navigate to that category. 2. Swipe left or right on the content area to navigate to the adjacent category.

Examples Pivot control on phone.

Tabs pattern in the Alarms & Clock app.

Create a pivot control The Pivot control comes with the basic functionality described in this section. This XAML creates a basic pivot control with 3 sections of content.



Pivot items

Pivot is an ItemsControl, so it can contain a collection of items of any type. Any item you add to the Pivot that is not explicitly a PivotItem is implicitly wrapped in a PivotItem. Because a Pivot is often used to navigate between pages of content, it's common to populate the Items collection directly with XAML UI elements. Or, you can set the ItemsSource property to a data source. Items bound in the ItemsSource can be of any type, but if they aren't explicitly PivotItems, you must define an ItemTemplate and HeaderTemplate to specify how the items are displayed. You can use the SelectedItem property to get or set the Pivot's active item. Use the SelectedIndex property to get or set the index of the active item. Pivot headers

You can use the LeftHeader and RightHeader properties to add other controls to the Pivot header. Pivot interaction

The control features these touch gesture interactions: Tapping on a pivot item header navigates to that header's section content. Swiping left or right on a pivot item header navigates to the adjacent section. Swiping left or right on section content navigates to the adjacent section.

The control comes in two modes: Stationary

Pivots are stationary when all pivot headers fit within the allowed space. Tapping on a pivot label navigates to the corresponding page, though the pivot itself will not move. The active pivot is highlighted. Carousel Pivots carousel when all pivot headers don't fit within the allowed space. Tapping a pivot label navigates to the corresponding page, and the active pivot label will carousel into the first position. Pivot items in a carousel loop from last to first pivot section.

Recommendations Base the alignment of tab/pivot headers on screen size. For screen widths below 720 epx, center-aligning usually works better, while left-aligning for screen widths above 720 epx is recommended in most cases. Avoid using more than 5 headers when using carousel (round-trip) mode, as looping more than 5 can become confusing. Use the tabs pattern only if your pivot items have distinct icons. Include text in pivot item headers to help users understand the meaning of each pivot section. Icons are not necessarily self-explanatory to all users.

Get the sample code Pivot sample See how to customize the Pivot control into the tabs pattern. XAML UI basics sample See all of the XAML controls in an interactive format.

Related topics Navigation design basics Pivot sample

Text controls 3/6/2017 • 8 min to read • Edit on GitHub

Text controls consist of text input boxes, password boxes, auto-suggest boxes, and text blocks. The XAML framework provides several controls for rendering, entering, and editing text, and a set of properties for formatting the text. The controls for displaying read-only text are TextBlock and RichTextBlock. The controls for text entry and editing are: TextBox, AutoSuggestBox, PasswordBox, and RichEditBox. Important APIs AutoSuggestBox class PasswordBox class RichEditBox class RichTextBlock class TextBlock class TextBox class

Is this the right control? The text control you use depends on your scenario. Use this info to pick the right text control to use in your app. Render read-only text

Use a TextBlock to display most read-only text in your app. You can use it to display single-line or multi-line text, inline hyperlinks, and text with formatting like bold, italic, or underlined. TextBlock is typically easier to use and provides better text rendering performance than RichTextBlock, so it's preferred for most app UI text. You can easily access and use text from a TextBlock in your app by getting the value of the Text property. It also provides many of the same formatting options for customizing how your text is rendered. Although you can put line breaks in the text, TextBlock is designed to display a single paragraph and doesn’t support text indentation. Use a RichTextBlock when you need support for multiple paragraphs, multi-column text or other complex text layouts, or inline UI elements like images. RichTextBlock provides several features for advanced text layout. The content property of RichTextBlock is the Blocks property, which supports paragraph based text via the Paragraph element. It doesn't have a Text property that you can use to easily access the control's text content in your app. Text input

Use a TextBox control to let a user enter and edit unformatted text, such as in a form. You can use the Text property to get and set the text in a TextBox. You can make a TextBox read-only, but this should be a temporary, conditional state. If the text is never editable, consider using a TextBlock instead.

Use a PasswordBox control to collect a password or other private data, such as a Social Security number. A password box is a text input box that conceals the characters typed in it for the sake of privacy. A password box looks like a text input box, except that it renders bullets in place of the text that has been entered. The bullet character can be customized. Use an AutoSuggestBox control to show the user a list of suggestions to choose from as they type. An autosuggest box is a text entry box that triggers a list of basic search suggestions. Suggested terms can draw from a combination of popular search terms and historical user-entered terms. You should also use an AutoSuggestBox control to implement a search box. Use a RichEditBox to display and edit text files. You don't use a RichEditBox to get user input into your app the way you use other standard text input boxes. Rather, you use it to work with text files that are separate from your app. You typically save text entered into a RichEditBox to a .rtf file. Is text input the best option? There are many ways you can get user input in your app. These questions will help answer whether one of the standard text input boxes or another control is the best fit for getting user input. Is it practical to efficiently enumerate all valid values? If so, consider using one of the selection controls, such as a check box, drop-down list, list box, radio button, slider, toggle switch, date picker, or time picker. Is there a fairly small set of valid values? If so, consider a drop-down list or a list box, especially if the values are more than a few characters long. Is the valid data completely unconstrained? Or is the valid data only constrained by format (constrained length or character types)? If so, use a text input control. You can limit the number of characters that can be entered, and you can validate the format in your app code. Does the value represent a data type that has a specialized common control? If so, use the appropriate control instead of a text input control. For example, use a DatePicker instead of a text input control to accept a date entry. If the data is strictly numeric: Is the value being entered approximate and/or relative to another quantity on the same page? If so, use a slider. Would the user benefit from instant feedback on the effect of setting changes? If so, use a slider, possibly with an accompanying control. Is the value entered likely to be adjusted after the result is observed, such as with volume or screen brightness? If so, use a slider.

Examples Text box

Auto suggest box

Password box

Create a text control See these articles for info and examples specific to each text control. AutoSuggestBox PasswordBox RichEditBox RichTextBlock TextBlock TextBox

Font and style guidelines See these articles for font guidelines: Font guidelines Segoe MDL2 icon list and guidelines

Choose the right keyboard for your text control Applies to: TextBox, PasswordBox RichEditBox To help users to enter data using the touch keyboard, or Soft Input Panel (SIP), you can set the input scope of the text control to match the kind of data the user is expected to enter. Tip This info applies only to the SIP. It does not apply to hardware keyboards or the On-Screen Keyboard available in the Windows Ease of Access options. The touch keyboard can be used for text entry when your app runs on a device with a touch screen. The touch keyboard is invoked when the user taps on an editable input field, such as a TextBox or RichEditBox. You can make it much faster and easier for users to enter data in your app by setting the input scope of the text control to match the kind of data you expect the user to enter. The input scope provides a hint to the system about the type of text input expected by the control so the system can provide a specialized touch keyboard layout for the input type. For example, if a text box is used only to enter a 4-digit PIN, set the InputScope property to Number. This tells the system to show the number keypad layout, which makes it easier for the user to enter the PIN.

Important The input scope does not cause any input validation to be performed, and does not prevent the user from providing any input through a hardware keyboard or other input device. You are still responsible for validating the input in your code as needed. For more info, see Use input scope to change the touch keyboard.

Color fonts Applies to: TextBlock, RichTextBlock, TextBox, RichEditBox Windows has the ability for fonts to include multiple colored layers for each glyph. For example, the Segoe UI Emoji font defines color versions of the Emoticon and other Emoji characters. The standard and rich text controls support display color fonts. By default, the IsColorFontEnabled property is true and fonts with these additional layers are rendered in color. The default color font on the system is Segoe UI Emoji and the controls will fall back to this font to display the glyphs in color. Hello ☺



The rendered text looks like this:

For more info, see the IsColorFontEnabled property.

Guidelines for line and paragraph separators Applies to: TextBlock, RichTextBlock, multi-line TextBox, RichEditBox Use the line separator character (0x2028) and the paragraph separator character (0x2029) to divide plain text. A new line is begun after each line separator. A new paragraph is begun after each paragraph separator. It isn't necessary to start the first line or paragraph in a file with these characters or to end the last line or paragraph with them; doing so indicates that there is an empty line or paragraph in that location. Your app can use the line separator to indicate an unconditional end of line. However, line separators do not correspond to the separate carriage return and linefeed characters, or to a combination of these characters. Line separators must be processed separately from carriage return and linefeed characters. Your app can insert a paragraph separator between paragraphs of text. Use of this separator allows creation of plain text files that can be formatted with different line widths on different operating systems. The target system can ignore any line separators and break paragraphs only at the paragraph separators.

Guidelines for spell checking Applies to: TextBox, RichEditBox During text entry and editing, spell checking informs the user that a word is misspelled by highlighting it with a red squiggle and provides a way for the user to correct the misspelling. Here's an example of the built-in spell checker:

Use spell checking with text input controls for these two purposes: To auto-correct misspellings The spell checking engine automatically corrects misspelled words when it's confident about the correction. For example, the engine automatically changes "teh" to "the." To show alternate spellings When the spell checking engine is not confident about the corrections, it adds a red line under the misspelled word and displays the alternates in a context menu when you tap or right-click the word. Use spell checking to help users as they enter words or sentences into text input controls. Spell checking works with touch, mouse, and keyboard inputs. Don't use spell checking when a word is not likely to be in the dictionary or if users wouldn't value spell checking. For example, don't turn it on if the text box is intended to capture a telephone number or name. Don't disable spell checking just because the current spell checking engine doesn't support your app language. When the spell checker doesn't support a language, it doesn't do anything, so there's no harm in leaving the option on. Also, some users might use an Input Method Editor (IME) to enter another language into your app, and that language might be supported. For example, when building a Japanese language app, even though the spell checking engine might not currently recognize that language, don't turn spell checking off. The user may switch to an English IME and type English into the app; if spell checking is enabled, the English will get spell checked. For TextBox and RichEditBox controls, spell checking is turned on by default. You can turn it off by setting the IsSpellCheckEnabled property to false.

Related articles For designers Font guidelines Segoe MDL2 icon list and guidelines Adding search For developers (XAML) TextBox class Windows.UI.Xaml.Controls PasswordBox class String.Length property

Labels 3/6/2017 • 1 min to read • Edit on GitHub

A label is the name or title of a control or a group of related controls. Important APIs Header property TextBlock class

In XAML, many controls have a built-in Header property that you use to display the label. For controls that don't have a Header property, or to label groups of controls, you can use a TextBlock instead.

Example

Recommendations Use a label to indicate to the user what they should enter into an adjacent control. You can also label a group of related controls, or display instructional text near a group of related controls. When labeling controls, write the label as a noun or a concise noun phrase, not as a sentence, and not as instructional text. Avoid colons or other punctuation. When you do have instructional text in a label, you can be more generous with text-string length and also use punctuation.

Get the sample code XAML UI basics sample

Related topics Text controls For developers TextBox.Header property PasswordBox.Header property ToggleSwitch.Header property DatePicker.Header property

TimePicker.Header property Slider.Header property ComboBox.Header property RichEditBox.Header property TextBlock class

Password box 3/6/2017 • 5 min to read • Edit on GitHub

A password box is a text input box that conceals the characters typed into it for the purpose of privacy. A password box looks like a text box, except that it renders placeholder characters in place of the text that has been entered. You can configure the placeholder character. By default, the password box provides a way for the user to view their password by holding down a reveal button. You can disable the reveal button, or provide an alternate mechanism to reveal the password, such as a check box. Important APIs PasswordBox class Password property PasswordChar property PasswordRevealMode property PasswordChanged event

Is this the right control? Use a PasswordBox control to collect a password or other private data, such as a Social Security number. For more info about choosing the right text control, see the Text controls article.

Examples The password box has several states, including these notable ones. A password box at rest can show hint text so that the user knows its purpose:

When the user types in a password box, the default behavior is to show bullets that hide the text being entered:

Pressing the "reveal" button on the right gives a peek at the password text being entered:

Create a password box Use the Password property to get or set the contents of the PasswordBox. You can do this in the handler for the PasswordChanged event to perform validation while the user enters the password. Or, you can use another event, like a button Click, to perform validation after the user completes the text entry.

Here's the XAML for a password box control that demonstrates the default look of the PasswordBox. When the user enters a password, you check to see if it's the literal value, "Password". If it is, you display a message to the user.

private void passwordBox_PasswordChanged(object sender, RoutedEventArgs e) { if (passwordBox.Password == "Password") { statusText.Text = "'Password' is not allowed as a password."; } else { statusText.Text = string.Empty; } }

Here's the result when this code runs and the user enters "Password".

Password character

You can change the character used to mask the password by setting the PasswordChar property. Here, the default bullet is replaced with an asterisk.

The result looks like this.

Headers and placeholder text

You can use the Header and PlaceholderText properties to provide context for the PasswordBox. This is especially useful when you have multiple boxes, such as on a form to change a password.

Maximum length

Specify the maximum number of characters that the user can enter by setting the MaxLength property. There is no property to specify a minimum length, but you can check the password length, and perform any other validation, in your app code.

Password reveal mode The PasswordBox has a built-in button that the user can press to display the password text. Here's the result of the user's action. When the user releases it, the password is automatically hidden again.

Peek mode

By default, the password reveal button (or "peek" button) is shown. The user must continuously press the button to view the password, so that a high level of security is maintained. The value of the PasswordRevealMode property is not the only factor that determines whether a password reveal button is visible to the user. Other factors include whether the control is displayed above a minimum width, whether the PasswordBox has focus, and whether the text entry field contains at least one character. The password reveal button is shown only when the PasswordBox receives focus for the first time and a character is entered. If the PasswordBox loses focus and then regains focus, the reveal button is not shown again unless the password is cleared and character entry starts over. Caution Prior to Windows 10, the password reveal button was not shown by default. If the security of your app requires that the password is always obscured, be sure to set PasswordRevealMode to Hidden. Hidden and Visible modes

The other PasswordRevealMode enumeration values, Hidden and Visible, hide the password reveal button and let you programmatically manage whether the password is obscured. To always obscure the password, set PasswordRevealMode to Hidden. Unless you need the password to be always obscured, you can provide a custom UI to let the user toggle the PasswordRevealMode between Hidden and Visible. In previous versions of Windows Phone, PasswordBox used a check box to toggle whether the password was obscured. You can create a similar UI for your app, as shown in the following example. You can also use other controls, like ToggleButton, to let the user switch modes. This example shows how to use a CheckBox to let a user switch the reveal mode of a PasswordBox.

private void CheckBox_Changed(object sender, RoutedEventArgs e) { if (revealModeCheckBox.IsChecked == true) { passwordBox1.PasswordRevealMode = PasswordRevealMode.Visible; } else { passwordBox1.PasswordRevealMode = PasswordRevealMode.Hidden; } }

This PasswordBox looks like this.

Choose the right keyboard for your text control To help users to enter data using the touch keyboard, or Soft Input Panel (SIP), you can set the input scope of the text control to match the kind of data the user is expected to enter. PasswordBox supports only the Password and NumericPin input scope values. Any other value is ignored. For more info about how to use input scopes, see Use input scope to change the touch keyboard.

Recommendations Use a label or placeholder text if the purpose of the password box isn't clear. A label is visible whether or not the text input box has a value. Placeholder text is displayed inside the text input box and disappears once a value has been entered. Give the password box an appropriate width for the range of values that can be entered. Word length varies between languages, so take localization into account if you want your app to be world-ready. Don't put another control right next to a password input box. The password box has a password reveal button for users to verify the passwords they have typed, and having another control right next to it might make users accidentally reveal their passwords when they try to interact with the other control. To prevent this from happening, put some spacing between the password in put box and the other control, or put the other control on the next line. Consider presenting two password boxes for account creation: one for the new password, and a second to confirm the new password. Only show a single password box for logins. When a password box is used to enter a PIN, consider providing an instant response as soon as the last number is entered instead of using a confirmation button.

Related articles Text controls Guidelines for spell checking Adding search Guidelines for text input TextBox class Windows.UI.Xaml.Controls PasswordBox class String.Length property

Rich edit box 3/6/2017 • 4 min to read • Edit on GitHub

You can use a RichEditBox control to enter and edit rich text documents that contain formatted text, hyperlinks, and images. You can make a RichEditBox read-only by setting its IsReadOnly property to true. Important APIs RichEditBox class Document property IsReadOnly property IsSpellCheckEnabled property

Is this the right control? Use a RichEditBox to display and edit text files. You don't use a RichEditBox to get user input into you app the way you use other standard text input boxes. Rather, you use it to work with text files that are separate from your app. You typically save text entered into a RichEditBox to a .rtf file. If the primary purpose of the multi-line text box is for creating documents (such as blog entries or the contents of an email message), and those documents require rich text, use a rich text box. If you want users to be able to format their text, use a rich text box. When capturing text that will only be consumed and not redisplayed to users, use a plain text input control. For all other scenarios, use a plain text input control. For more info about choosing the right text control, see the Text controls article.

Examples This rich edit box has a rich text document open in it. The formatting and file buttons aren't part of the rich edit box, but you should provide at least a minimal set of styling buttons and implement their actions.

Create a rich edit box By default, the RichEditBox supports spell checking. To disable the spell checker, set the IsSpellCheckEnabled property to false. For more info, see the Guidelines for spell checking article. You use the Document property of the RichEditBox to get its content. The content of a RichEditBox is a

Windows.UI.Text.ITextDocument object, unlike the RichTextBlock control, which uses Windows.UI.Xaml.Documents.Block objects as its content. The ITextDocument interface provides a way to load and save the document to a stream, retrieve text ranges, get the active selection, undo and redo changes, set default formatting attributes, and so on. This example shows how to edit, load, and save a Rich Text Format (.rtf) file in a RichEditBox.

private async void OpenButton_Click(object sender, RoutedEventArgs e) { // Open a text file. Windows.Storage.Pickers.FileOpenPicker open = new Windows.Storage.Pickers.FileOpenPicker(); open.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.DocumentsLibrary; open.FileTypeFilter.Add(".rtf"); Windows.Storage.StorageFile file = await open.PickSingleFileAsync(); if (file != null) { try { Windows.Storage.Streams.IRandomAccessStream randAccStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read); // Load the file into the Document property of the RichEditBox. editor.Document.LoadFromStream(Windows.UI.Text.TextSetOptions.FormatRtf, randAccStream); } catch (Exception) { ContentDialog errorDialog = new ContentDialog() { Title = "File open error", Content = "Sorry, I couldn't open the file.", PrimaryButtonText = "Ok" }; await errorDialog.ShowAsync(); } } }

private async void SaveButton_Click(object sender, RoutedEventArgs e) { Windows.Storage.Pickers.FileSavePicker savePicker = new Windows.Storage.Pickers.FileSavePicker(); savePicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.DocumentsLibrary; // Dropdown of file types the user can save the file as savePicker.FileTypeChoices.Add("Rich Text", new List() { ".rtf" }); // Default file name if the user does not type one in or select a file to replace savePicker.SuggestedFileName = "New Document"; Windows.Storage.StorageFile file = await savePicker.PickSaveFileAsync(); if (file != null) { // Prevent updates to the remote version of the file until we // finish making changes and call CompleteUpdatesAsync. Windows.Storage.CachedFileManager.DeferUpdates(file); // write to file Windows.Storage.Streams.IRandomAccessStream randAccStream = await file.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite); editor.Document.SaveToStream(Windows.UI.Text.TextGetOptions.FormatRtf, randAccStream); // Let Windows know that we're finished changing the file so the // other app can update the remote version of the file. Windows.Storage.Provider.FileUpdateStatus status = await Windows.Storage.CachedFileManager.CompleteUpdatesAsync(file); if (status != Windows.Storage.Provider.FileUpdateStatus.Complete) { Windows.UI.Popups.MessageDialog errorBox = new Windows.UI.Popups.MessageDialog("File " + file.Name + " couldn't be saved."); await errorBox.ShowAsync(); } } } private void BoldButton_Click(object sender, RoutedEventArgs e) { Windows.UI.Text.ITextSelection selectedText = editor.Document.Selection; if (selectedText != null) { Windows.UI.Text.ITextCharacterFormat charFormatting = selectedText.CharacterFormat; charFormatting.Bold = Windows.UI.Text.FormatEffect.Toggle; selectedText.CharacterFormat = charFormatting; } } private void ItalicButton_Click(object sender, RoutedEventArgs e) { Windows.UI.Text.ITextSelection selectedText = editor.Document.Selection; if (selectedText != null) { Windows.UI.Text.ITextCharacterFormat charFormatting = selectedText.CharacterFormat; charFormatting.Italic = Windows.UI.Text.FormatEffect.Toggle; selectedText.CharacterFormat = charFormatting; } } private void UnderlineButton_Click(object sender, RoutedEventArgs e) { Windows.UI.Text.ITextSelection selectedText = editor.Document.Selection; if (selectedText != null) { Windows.UI.Text.ITextCharacterFormat charFormatting = selectedText.CharacterFormat; if (charFormatting.Underline == Windows.UI.Text.UnderlineType.None) { charFormatting.Underline = Windows.UI.Text.UnderlineType.Single; } else { charFormatting.Underline = Windows.UI.Text.UnderlineType.None;

} selectedText.CharacterFormat = charFormatting; } }

Choose the right keyboard for your text control To help users to enter data using the touch keyboard, or Soft Input Panel (SIP), you can set the input scope of the text control to match the kind of data the user is expected to enter. The default keyboard layout is usually appropriate for working with rich text documents. For more info about how to use input scopes, see Use input scope to change the touch keyboard.

Do's and don'ts When you create a rich text box, provide styling buttons and implement their actions. Use a font that's consistent with the style of your app. Make the height of the text control tall enough to accommodate typical entries. Don't let your text input controls grow in height while users type. Don't use a multi-line text box when users only need a single line. Don't use a rich text control if a plain text control is adequate.

Related articles Text controls Guidelines for spell checking Adding search Guidelines for text input TextBox class Windows.UI.Xaml.Controls PasswordBox class

Rich text block 3/6/2017 • 3 min to read • Edit on GitHub

Rich text blocks provide several features for advanced text layout that you can use when you need support for paragraphs, inline UI elements, or complex text layouts. Important APIs RichTextBlock class RichTextBlockOverflow class Paragraph class Typography class

Is this the right control? Use a RichTextBlock when you need support for multiple paragraphs, multi-column or other complex text layouts, or inline UI elements like images. Use a TextBlock to display most read-only text in your app. You can use it to display single-line or multi-line text, inline hyperlinks, and text with formatting like bold, italic, or underlined. TextBlock provides a simpler content model, so it’s typically easier to use, and it can provide better text rendering performance than RichTextBlock. It's preferred for most app UI text. Although you can put line breaks in the text, TextBlock is designed to display a single paragraph and doesn’t support text indentation. For more info about choosing the right text control, see the Text controls article.

Create a rich text block The content property of RichTextBlock is the Blocks property, which supports paragraph based text via the Paragraph element. It doesn't have a Text property that you can use to easily access the control's text content in your app. However, RichTextBlock provides several unique features that TextBlock doesn’t provide. RichTextBlock supports: Multiple paragraphs. Set the indentation for paragraphs by setting the TextIndent property. Inline UI elements. Use an InlineUIContainer to display UI elements, such as images, inline with your text. Overflow containers. Use RichTextBlockOverflow elements to create multi-column text layouts. Paragraphs

You use Paragraph elements to define the blocks of text to display within a RichTextBlock control. Every RichTextBlock should include at least one Paragraph. You can set the indent amount for all paragraphs in a RichTextBlock by setting the RichTextBlock.TextIndent property. You can override this setting for specific paragraphs in a RichTextBlock by setting the Paragraph.TextIndent property to a different value.

First paragraph. Second paragraph. Third paragraph. With an inline.

Inline UI elements

The InlineUIContainer class lets you embed any UIElement inline with your text. A common scenario is to place an Image inline with your text, but you can also use interactive elements, like a Button or CheckBox. If you want to embed more than one element inline in the same position, consider using a panel as the single InlineUIContainer child, and then place the multiple elements within that panel. This example shows how to use an InlineUIContainer to insert an image into a RichTextBlock. This is an inline image. Mauris auctor tincidunt auctor.

Overflow containers You can use a RichTextBlock with RichTextBlockOverflow elements to create multi-column or other advanced page layouts. The content for a RichTextBlockOverflow element always comes from a RichTextBlock element. You link RichTextBlockOverflow elements by setting them as the OverflowContentTarget of a RichTextBlock or another RichTextBlockOverflow. Here's a simple example that creates a two column layout. See the Examples section for a more complex example. Proin ac metus at quam luctus ultricies.

Formatting text Although the RichTextBlock stores plain text, you can apply various formatting options to customize how the text is rendered in your app. You can set standard control properties like FontFamily, FontSize, FontStyle, Foreground, and CharacterSpacing to change the look of the text. You can also use inline text elements and Typography attached properties to format your text. These options affect only how the RichTextBlock displays the text locally, so if you copy and paste the text into a rich text control, for example, no formatting is applied. Inline elements

The Windows.UI.Xaml.Documents namespace provides a variety of inline text elements that you can use to format your text, such as Bold, Italic, Run, Span, and LineBreak. A typical way to apply formatting to sections of text is to place the text in a Run or Span element, and then set properties on that element. Here's a Paragraph with the first phrase shown in bold, blue, 16pt text. Lorem ipsum dolor sit amet , consectetur adipiscing elit.

Typography

The attached properties of the Typography class provide access to a set of Microsoft OpenType typography properties. You can set these attached properties either on the RichTextBlock, or on individual inline text elements, as shown here. Lorem ipsum dolor sit amet , consectetur adipiscing elit.

Recommendations See Typography and Guidelines for fonts.

Related articles Text controls For designers Guidelines for spell checking Adding search Guidelines for text input For developers (XAML) TextBox class Windows.UI.Xaml.Controls PasswordBox class For developers (other) String.Length property

Text block 3/6/2017 • 5 min to read • Edit on GitHub

Text block is the primary control for displaying read-only text in apps. You can use it to display single-line or multi-line text, inline hyperlinks, and text with formatting like bold, italic, or underlined. Important APIs TextBlock class Text property Inlines property

Is this the right control? A text block is typically easier to use and provides better text rendering performance than a rich text block, so it's preferred for most app UI text. You can easily access and use text from a text block in your app by getting the value of the Text property. It also provides many of the same formatting options for customizing how your text is rendered. Although you can put line breaks in the text, text block is designed to display a single paragraph and doesn’t support text indentation. Use a RichTextBlock when you need support for multiple paragraphs, multi-column text or other complex text layouts, or inline UI elements like images. For more info about choosing the right text control, see the Text controls article.

Create a text block Here's how to define a simple TextBlock control and set its Text property to a string.

TextBlock textBlock1 = new TextBlock(); textBlock1.Text = "Hello, world!";

TextBlock textBlock1 = new TextBlock(); textBlock1.Text = "Hello, world!";

Content model

There are two properties you can use to add content to a TextBlock: Text and Inlines. The most common way to display text is to set the Text property to a string value, as shown in the previous example. You can also add content by placing inline flow content elements in the TextBox.Inlines property, like this.

Text can be bold, italic, or both.

Elements derived from the Inline class, such as Bold, Italic, Run, Span, and LineBreak, enable different formatting for different parts of the text. For more info, see the [Formatting text]() section. The inline Hyperlink element lets you add a hyperlink to your text. However, using Inlines also disables fast path text rendering, which is discussed in the next section.

Performance considerations Whenever possible, XAML uses a more efficient code path to layout text. This fast path both decreases overall memory use and greatly reduces the CPU time to do text measuring and arranging. This fast path applies only to TextBlock, so it should be preferred when possible over RichTextBlock. Certain conditions require TextBlock to fall back to a more feature-rich and CPU intensive code path for text rendering. To keep text rendering on the fast path, be sure to follow these guidelines when setting the properties listed here. Text: The most important condition is that the fast path is used only when you set text by explicitly setting the Text property, either in XAML or in code (as shown in the previous examples). Setting the text via TextBlock’s Inlines collection (such as Inline text ) will disable the fast path, due to the potential complexity of multiple formats. CharacterSpacing: Only the default value of 0 is fast path. TextTrimming: Only the None, CharacterEllipsis, and WordEllipsis values are fast path. The Clip value disables the fast path. Note Prior to Windows 10, version 1607, additional properties also affect the fast path. If your app is run on an earlier version of Windows, these conditions will also cause your text to render on the slow path. For more info about versions, see Version adaptive code. Typography: Only the default values for the various Typography properties are fast path. LineStackingStrategy: If LineHeight is not 0, the BaselineToBaseline and MaxHeight values disable the fast path. IsTextSelectionEnabled: Only false is fast path. Setting this property to true disables the fast path. You can set the DebugSettings.IsTextPerformanceVisualizationEnabled property to true during debugging to determine whether text is using fast path rendering. When this property is set to true, the text that is on the fast path displays in a bright green color. Tip This feature is explained in depth in this session from Build 2015- XAML Performance: Techniques for Maximizing Universal Windows App Experiences Built with XAML. You typically set debug settings in the OnLaunched method override in the code-behind page for App.xaml, like this.

protected override void OnLaunched(LaunchActivatedEventArgs e) { #if DEBUG if (System.Diagnostics.Debugger.IsAttached) { this.DebugSettings.IsTextPerformanceVisualizationEnabled = true; } #endif // ... }

In this example, the first TextBlock is rendered using the fast path, while the second is not. This text is NOT on the fast path.

When you run this XAML in debug mode with IsTextPerformanceVisualizationEnabled set to true, the result looks like this.

Caution The color of text that is not on the fast path is not changed. If you have text in your app with its color specified as bright green, it is still displayed in bright green when it's on the slower rendering path. Be careful to not confuse text that is set to green in the app with text that is on the fast path and green because of the debug settings.

Formatting text Although the Text property stores plain text, you can apply various formatting options to the TextBlock control to customize how the text is rendered in your app. You can set standard control properties like FontFamily, FontSize, FontStyle, Foreground, and CharacterSpacing to change the look of the text. You can also use inline text elements and Typography attached properties to format your text. These options affect only how the TextBlock displays the text locally, so if you copy and paste the text into a rich text control, for example, no formatting is applied. Note Remember, as noted in the previous section, inline text elements and non-default typography values are not rendered on the fast path. Inline elements

The Windows.UI.Xaml.Documents namespace provides a variety of inline text elements that you can use to format your text, such as Bold, Italic, Run, Span, and LineBreak. You can display a series of strings in a TextBlock, where each string has different formatting. You can do this by using a Run element to display each string with its formatting and by separating each Run element with a LineBreak element. Here's how to define several differently formatted text strings in a TextBlock by using Run objects separated with a LineBreak.

Courier New 24 Times New Roman Italic 18 Verdana Bold 14

Here's the result.

Typography

The attached properties of the Typography class provide access to a set of Microsoft OpenType typography properties. You can set these attached properties either on the TextBlock, or on individual inline text elements. These examples show both.

TextBlock textBlock1 = new TextBlock(); textBlock1.Text = "Hello, world!"; Windows.UI.Xaml.Documents.Typography.SetCapitals(textBlock1, FontCapitals.SmallCaps); Windows.UI.Xaml.Documents.Typography.SetStylisticSet4(textBlock1, true);

12 x 1/3 = 4.

Related articles Text controls Guidelines for spell checking Adding search Guidelines for text input TextBox class Windows.UI.Xaml.Controls PasswordBox class String.Length property

Text box 3/6/2017 • 12 min to read • Edit on GitHub

The TextBox control lets a user type text into an app. It's typically used to capture a single line of text, but can be configured to capture multiple lines of text. The text displays on the screen in a simple, uniform, plaintext format. TextBox has a number of features that can simplify text entry. It comes with a familiar, built-in context menu with support for copying and pasting text. The "clear all" button lets a user quickly delete all text that has been entered. It also has spell checking capabilities built in and enabled by default. Important APIs TextBox class Text property

Is this the right control? Use a TextBox control to let a user enter and edit unformatted text, such as in a form. You can use the Text property to get and set the text in a TextBox. You can make a TextBox read-only, but this should be a temporary, conditional state. If the text is never editable, consider using a TextBlock instead. Use a PasswordBox control to collect a password or other private data, such as a Social Security number. A password box looks like a text input box, except that it renders bullets in place of the text that has been entered. Use an AutoSuggestBox control to let the user enter search terms or to show the user a list of suggestions to choose from as they type. Use a RichEditBox to display and edit rich text files. For more info about choosing the right text control, see the Text controls article.

Examples

Create a text box Here's the XAML for a simple text box with a header and placeholder text.

TextBox textBox = new TextBox(); textBox.Width = 500; textBox.Header = "Notes"; textBox.PlaceholderText = "Type your notes here"; // Add the TextBox to the visual tree. rootGrid.Children.Add(textBox);

Here's the text box that results from this XAML.

Use a text box for data input in a form

It’s common to use a text box to accept data input on a form, and use the Text property to get the complete text string from the text box. You typically use an event like a submit button click to access the Text property, but you can handle the TextChanged or TextChanging event if you need to do something when the text changes. You can add a Header (or label) and PlaceholderText (or watermark) to the text box to give the user an indication of what the text box is for. To customize the look of the header, you can set the HeaderTemplate property instead of Header. For design info, see Guidelines for labels. You can restrict the number of characters the user can type by setting the MaxLength property. However, MaxLength does not restrict the length of pasted text. Use the Paste event to modify pasted text if this is important for your app. The text box includes a clear all button ("X") that appears when text is entered in the box. When a user clicks the "X", the text in the text box is cleared. It looks like this.

The clear all button is shown only for editable, single-line text boxes that contain text and have focus. The clear all button is not shown in any of these cases: IsReadOnly is true AcceptsReturn is true TextWrap has a value other than NoWrap Make a text box read-only

You can make a text box read-only by setting the IsReadOnly property to true. You typically toggle this property in your app code based on conditions in your app. If need text that is always read-only, consider using a TextBlock instead. You can make a TextBox read-only by setting the IsReadOnly property to true. For example, you might have a TextBox for a user to enter comments that is enabled only under certain conditions. You can make the TextBox read-only until the conditions are met. If you need only to display text, consider using a TextBlock or RichTextBlock instead. A read-only text box looks the same as a read/write text box, so it might be confusing to a user. A user can select and copy text. IsEnabled Enable multi-line input

There are two properties that you can use to control whether the text box displays text on more than one line. You typically set both properties to make a multi-line text box. To let the text box allow and display the newline or return characters, set the AcceptsReturn property to true. To enable text wrapping, set the TextWrapping property to Wrap. This causes the text to wrap when it reaches the edge of the text box, independent of line separator characters. Note TextBox and RichEditBox don't support the WrapWholeWords value for their TextWrapping properties. If you try to use WrapWholeWords as a value for TextBox.TextWrapping or RichEditBox.TextWrapping an invalid argument exception is thrown.

A multi-line text box will continue to grow vertically as text is entered unless it’s constrained by its Height or MaxHeight property, or by a parent container. You should test that a multi-line text box doesn’t grow beyond its visible area, and constrain its growth if it does. We recommend that you always specify an appropriate height for a multi-line text box, and not let it grow in height as the user types. Scrolling using a scroll-wheel or touch is automatically enabled when needed. However, the vertical scrollbars are not visible by default. You can show the vertical scrollbars by setting the ScrollViewer.VerticalScrollBarVisibility to Auto on the embedded ScrollViewer, as shown here.

TextBox textBox = new TextBox(); textBox.AcceptsReturn = true; textBox.TextWrapping = TextWrapping.Wrap; textBox.MaxHeight = 172; textBox.Width = 300; textBox.Header = "Description"; ScrollViewer.SetVerticalScrollBarVisibility(textBox, ScrollBarVisibility.Auto);

Here's what the text box looks like after text is added.

Format the text display

Use the [TextAlignment]() property to align text within a text box. To align the text box within the layout of the page, use the HorizontalAlignment and VerticalAlignment properties. While the text box supports only unformatted text, you can customize how the text is displayed in the text box to match your branding. You can set standard Control properties like FontFamily, FontSize, FontStyle, Background, Foreground, and CharacterSpacing to change the look of the text. These properties affect only how the text box displays the text locally, so if you were to copy and paste the text into a rich text control, for example, no formatting would be applied. This example shows a read-only text box with several properties set to customize the appearance of the text.

TextBox textBox = new TextBox(); textBox.Text = "Sample Text"; textBox.IsReadOnly = true; textBox.FontFamily = new FontFamily("Verdana"); textBox.FontSize = 24; textBox.FontWeight = Windows.UI.Text.FontWeights.Bold; textBox.FontStyle = Windows.UI.Text.FontStyle.Italic; textBox.CharacterSpacing = 200; textBox.Width = 300; textBox.Background = new SolidColorBrush(Windows.UI.Colors.Beige); textBox.Foreground = new SolidColorBrush(Windows.UI.Colors.Blue); // Add the TextBox to the visual tree. rootGrid.Children.Add(textBox);

The resulting text box looks like this.

Modify the context menu

By default, the commands shown in the text box context menu depend on the state of the text box. For example, the following commands can be shown when the text box is editable. COMMAND

SHOWN WHEN...

Copy

text is selected.

Cut

text is selected.

Paste

the clipboard contains text.

Select all

the TextBox contains text.

Undo

text has been changed.

To modify the commands shown in the context menu, handle the ContextMenuOpening event. For an example of this, see Scenario 2 of the ContextMenu sample. For design info, see Guidelines for context menus. Select, copy, and paste

You can get or set the selected text in a text box using the SelectedText property. Use the SelectionStart and SelectionLength properties, and the Select and SelectAll methods, to manipulate the text selection. Handle the SelectionChanged event to do something when the user selects or de-selects text. You can change the color used to highlight the selected text by setting the SelectionHighlightColor property. TextBox supports copy and paste by default. You can provide custom handling of the Paste event on editable text controls in your app. For example, you might remove the line breaks from a multi-line address when pasting it into a single-line search box. Or, you might check the length of the pasted text and warn the user if it exceeds the maximum length that can be saved to a database. For more info and examples, see the Paste event. Here, we have an example of these properties and methods in use. When you select text in the first text box, the selected text is displayed in the second text box, which is read-only. The values of the SelectionLength and SelectionStart properties are shown in two text blocks. This is done using the SelectionChanged event.



private void TextBox1_SelectionChanged(object sender, RoutedEventArgs e) { textBox2.Text = textBox1.SelectedText; label1.Text = "Selection length is " + textBox1.SelectionLength.ToString(); label2.Text = "Selection starts at " + textBox1.SelectionStart.ToString(); }

Here's the result of this code.

Choose the right keyboard for your text control To help users to enter data using the touch keyboard, or Soft Input Panel (SIP), you can set the input scope of the text control to match the kind of data the user is expected to enter. The touch keyboard can be used for text entry when your app runs on a device with a touch screen. The touch keyboard is invoked when the user taps on an editable input field, such as a TextBox or RichEditBox. You can make it much faster and easier for users to enter data in your app by setting the input scope of the text control to match the kind of data you expect the user to enter. The input scope provides a hint to the system about the type of text input expected by the control so the system can provide a specialized touch keyboard layout for the input type. For example, if a text box is used only to enter a 4-digit PIN, set the InputScope property to Number. This tells the system to show the number keypad layout, which makes it easier for the user to enter the PIN. Important The input scope does not cause any input validation to be performed, and does not prevent the user from providing any input through a hardware keyboard or other input device. You are still responsible for validating the input in your code as needed. Other properties that affect the touch keyboard are IsSpellCheckEnabled, IsTextPredictionEnabled, and PreventKeyboardDisplayOnProgrammaticFocus. (IsSpellCheckEnabled also affects the TextBox when a hardware keyboard is used.) For more info and examples, see Use input scope to change the touch keyboard and the property documentation.

Recommendations Use a label or placeholder text if the purpose of the text box isn't clear. A label is visible whether or not the text input box has a value. Placeholder text is displayed inside the text input box and disappears once a value has been entered. Give the text box an appropriate width for the range of values that can be entered. Word length varies between languages, so take localization into account if you want your app to be world-ready. A text input box is typically single-line ( TextWrap = "NoWrap" ). When users need to enter or edit a long string, set the text input box to multi-line ( TextWrap = "Wrap" ). Generally, a text input box is used for editable text. But you can make a text input box read-only so that its content can be read, selected, and copied, but not edited. If you need to reduce clutter in a view, consider making a set of text input boxes appear only when a controlling checkbox is checked. You can also bind the enabled state of a text input box to a control such as a checkbox. Consider how you want a text input box to behave when it contains a value and the user taps it. The default behavior is appropriate for editing the value rather than replacing it; the insertion point is placed between words and nothing is selected. If replacing is the most common use case for a given text input box, you can select all the text in the field whenever the control receives focus, and typing replaces the selection. Single-line input boxes Use several single-line text boxes to capture many small pieces of text information. If the text boxes are related in nature, group those together. Make the size of single-line text boxes slightly wider than the longest anticipated input. If doing so makes the control too wide, separate it into two controls. For example, you could split a single address input into "Address line 1" and "Address line 2". Set a maximum length for characters that can be entered. If the backing data source doesn't allow a long input string, limit the input and use a validation popup to let users know when they reach the limit. Use single-line text input controls to gather small pieces of text from users. The following example shows a single-line text box to capture an answer to a security question. The answer is expected to be short, and so a single-line text box is appropriate here.

Use a set of short, fixed-sized, single-line text input controls to enter data with a specific format.

Use a single-line, unconstrained text input control to enter or edit strings, combined with a command button that helps users select valid values.

Multi-line text input controls When you create a rich text box, provide styling buttons and implement their actions. Use a font that's consistent with the style of your app. Make the height of the text control tall enough to accommodate typical entries.

When capturing long spans of text with a maximum character or word count, use a plain text box and provide a live-running counter to show the user how many characters or words they have left before they reach the limit. You'll need to create the counter yourself; place it below the text box and dynamically update it as the user enters each character or word.

Don't let your text input controls grow in height while users type. Don't use a multi-line text box when users only need a single line. Don't use a rich text control if a plain text control is adequate.

Related articles Text controls Guidelines for spell checking Adding search Guidelines for text input TextBox class Windows.UI.Xaml.Controls PasswordBox class String.Length property

Tiles, badges, and notifications for UWP apps 3/6/2017 • 3 min to read • Edit on GitHub

Learn how to use tiles, badges, toasts, and notifications to provide entry points into your app and keep users upto-date. A tile is an app's representation on the Start menu. Every UWP app has a tile. You can enable different tile sizes (small, medium, wide, and large). You can use a tile notification to update the tile to communicate new information to the user, such as news headlines, or the subject of the most recent unread message. You can use a badge to provide status or summary info in the form of a systemprovided glyph or a number from 1-99. Badges also appear on the task bar icon for an app. A toast notification is a notification that your app sends to the user via a pop-up UI element called a toast (or banner). The notification can be seen whether the user is in your app or not. A push notification or raw notification is a notification sent to your app either from Windows Push Notification Services (WNS) or from a background task. Your app can respond to these notifications either by notifying the user that something of interest happened (via badge update, tile update, or toast) or it can respond in any way of your choice.

Tiles TOPIC

DESCRIPTION

Create tiles

Customize the default tile for your app and provide assets for different screen sizes.

Create adaptive tiles

Adaptive tile templates are a new feature in Windows 10, allowing you to design your own tile notification content using a simple and flexible markup language that adapts to different screen densities. This article tells you how to create adaptive live tiles for your Universal Windows Platform (UWP) app.

Adaptive tiles schema

Here are the elements and attributes you use to create adaptive tiles.

Special tile templates

Special tile templates are unique templates that are either animated, or just allow you to do things that aren't possible with adaptive tiles.

TOPIC

DESCRIPTION

App icon assets

App icon assets, which appear in a variety of forms throughout the Windows 10 operating system, are the calling cards for your Universal Windows Platform (UWP) app. These guidelines detail where app icon assets appear in the system, and provide in-depth design tips on how to create the most polished icons.

Notifications TOPIC

DESCRIPTION

Adaptive and interactive toast notifications

Adaptive and interactive toast notifications let you create flexible pop-up notifications with more content, optional inline images, and optional user interaction.

Notifications Visualizer

Notifications Visualizer is a new Universal Windows Platform (UWP) app in the Store that helps developers design adaptive live tiles for Windows 10.

Choose a notification delivery method

This article covers the four notification options—local, scheduled, periodic, and push—that deliver tile and badge updates and toast notification content.

Send a local tile notification

This article describes how to send a local tile notification to a primary tile and a secondary tile using adaptive tile templates.

Periodic notification overview

Periodic notifications, which are also called polled notifications, update tiles and badges at a fixed interval by downloading content from a cloud service.

Windows Push Notification Services (WNS) overview

The Windows Push Notification Services (WNS) enables third-party developers to send toast, tile, badge, and raw updates from their own cloud service. This provides a mechanism to deliver new updates to your users in a power-efficient and dependable way.

Code generated by the push notification wizard

By using a wizard in Visual Studio, you can generate push notifications from a mobile service that was created with Azure Mobile Services. The Visual Studio wizard generates code to help you get started. This topic explains how the wizard modifies your project, what the generated code does, how to use this code, and what you can do next to get the most out of push notifications. See Windows Push Notification Services (WNS) overview.

TOPIC

DESCRIPTION

Raw notification overview

Raw notifications are short, general purpose push notifications. They are strictly instructional and do not include a UI component. As with other push notifications, the WNS feature delivers raw notifications from your cloud service to your app.

Tiles for UWP apps 3/6/2017 • 2 min to read • Edit on GitHub

A tile is an app's representation on the Start menu. Every app has a tile. When you create a new Universal Windows Platform (UWP) app project in Microsoft Visual Studio, it includes a default tile that displays your app's name and logo. Windows displays this tile when your app is first installed. After your app is installed, you can change your tile's content through notifications; for example, you can change the tile to communicate new information to the user, such as news headlines, or the subject of the most recent unread message.

Configure the default tile When you create a new project in Visual Studio, it creates a simple default tile that displays your app's name and logo.

There are a few items you should update: DisplayName: Replace this value with the name you want to display on your tile. ShortName: Because there is limited room for your display name to fit on tiles, we recommend that you to specify a ShortName as well, to make sure your app's name doesn’t get truncated. Logo images: You should replace these images with your own. You have the option of supplying images for different visual scales, but you are not required to supply them all. To ensure that you app looks good on a range of devices, we recommend that you provide 100%, 200%, and 400% scale versions of each image. Scaled images follow this naming convention: testing .scale-. For example: SmallLogo.scale-100.png When you refer to the image, you refer to it as . ("SmallLogo.png" in this example). The system will automatically select the appropriate scaled image for the device from the images you've provided. You don't have to, but we highly recommend supplying logos for wide and large tile sizes so that the user can resize your app's tile to those sizes. To provide these additional images, you create a DefaultTile element and use the Wide310x150Logo and Square310x310Logo attributes to specify the additional images:



Use notifications to customize your tile After your app is installed, you can use notifications to customize your tile. You can do this the first time your app launches or in response to some event, such as a push notification. 1. Create an XML payload (in the form of an Windows.Data.Xml.Dom.XmlDocument) that describes the tile. Windows 10 introduces a new adaptive tile schema you can use. For instructions, see Adaptive tiles. For the schema, see the Adaptive tiles schema. You can use the Windows 8.1 tile templates to define your tile. For more info, see Creating tiles and badges (Windows 8.1). 2. Create a tile notification object and pass it the XmlDocument you created. There are several types of notification objects: A Windows.UI.NotificationsTileNotification object for updating the tile immediately. A Windows.UI.Notifications.ScheduledTileNotification object for updating the tile at some point in the future. 3. Use the Windows.UI.Notifications.TileUpdateManager.CreateTileUpdaterForApplication to create a TileUpdater object. 4. Call the TileUpdater.Update method and pass it the tile notification object you created in step 2.

Create adaptive tiles 3/6/2017 • 18 min to read • Edit on GitHub

Adaptive tile templates are a new feature in Windows 10, allowing you to design your own tile notification content using a simple and flexible markup language that adapts to different screen densities. This article tells you how to create adaptive live tiles for your Universal Windows Platform (UWP) app. For the complete list of adaptive elements and attributes, see the Adaptive tiles schema. (If you'd like, you can still use the preset templates from the Windows 8 tile template catalog when designing notifications for Windows 10.)

Getting started Install Notifications library. If you'd like to use C# instead of XML to generate notifications, install the NuGet package named Microsoft.Toolkit.Uwp.Notifications (search for "notifications uwp"). The C# samples provided in this article use version 1.0.0 of the NuGet package. Install Notifications Visualizer. This free UWP app helps you design adaptive live tiles by providing an instant visual preview of your tile as you edit it, similar to Visual Studio's XAML editor/design view. You can read this blog post for more information, and you can download Notifications Visualizer here.

How to send a tile notification Please read our Quickstart on sending local tile notifications. The documentation on this page explains all the visual UI possibilities you have with adaptive tiles.

Usage guidance Adaptive templates are designed to work across different form factors and notification types. Elements such as group and subgroup link together content and don't imply a particular visual behavior on their own. The final appearance of a notification should be based on the specific device on which it will appear, whether it's phone, tablet, or desktop, or another device. Hints are optional attributes that can be added to elements in order to achieve a specific visual behavior. Hints can be device-specific or notification-specific.

A basic example This example demonstrates what the adaptive tile templates can produce.

... Jennifer Parker Photos from our trip Check out these awesome photos I took while in New Zealand! ...

TileContent content = new TileContent() { Visual = new TileVisual() { TileMedium = ... TileWide = new TileBinding() { Content = new TileBindingContentAdaptive() { Children = { new AdaptiveText() { Text = "Jennifer Parker", HintStyle = AdaptiveTextStyle.Subtitle }, new AdaptiveText() { Text = "Photos from our trip", HintStyle = AdaptiveTextStyle.CaptionSubtle }, new AdaptiveText() { Text = "Check out these awesome photos I took while in New Zealand!", HintStyle = AdaptiveTextStyle.CaptionSubtle } } } }, TileLarge = ... } };

Result:

Tile sizes Content for each tile size is individually specified in separate elements within the XML payload. Choose the target size by setting the template attribute to one of the following values: TileSmall TileMedium TileWide TileLarge (only for desktop) For a single tile notification XML payload, provide elements for each tile size that you'd like to support, as shown in this example: Small Medium Wide Large

TileContent content = new TileContent() { Visual = new TileVisual() { TileSmall = new TileBinding() { Content = new TileBindingContentAdaptive() { Children = { new AdaptiveText() { Text = "Small" } } } }, TileMedium = new TileBinding() { Content = new TileBindingContentAdaptive() { Children = { new AdaptiveText() { Text = "Medium" } } } }, TileWide = new TileBinding() { Content = new TileBindingContentAdaptive() { Children = { new AdaptiveText() { Text = "Wide" } } } }, TileLarge = new TileBinding() { Content = new TileBindingContentAdaptive() { Children = { new AdaptiveText() { Text = "Large" } } } } } };

Result:

Branding You can control the branding on the bottom of a live tile (the display name and corner logo) by using the branding attribute on the notification payload. You can choose to display "none," only the "name," only the "logo," or both with "nameAndLogo." Note Windows Mobile doesn't support the corner logo, so "logo" and "nameAndLogo" default to "name" on Mobile. ...

new TileVisual() { Branding = TileBranding.Logo, ... }

Result:

Branding can be applied for specific tile sizes one of two ways: 1. By applying the attribute on the element 2. By applying the attribute on the element, which affects the entire notification payload If you don't specify branding for a binding, it will use the branding that's provided on the visual element. ... ...

TileContent content = new TileContent() { Visual = new TileVisual() { Branding = TileBranding.NameAndLogo, TileMedium = new TileBinding() { Branding = TileBranding.Logo, ... }, // Inherits branding from Visual TileWide = new TileBinding() { ... } } };

Default branding result:

If you don't specify the branding in your notification payload, the base tile's properties will determine the branding. If the base tile shows the display name, then the branding will default to "name." Otherwise, the branding will default to "none" if the display name isn't shown. Note This is a change from Windows 8.x, in which the default branding was "logo."

Display name You can override the display name of a notification by entering the text string of your choice with the displayName attribute. As with branding, you can specify this on the element, which affects the entire notification payload, or on the element, which only affects individual tiles. Known Issue On Windows Mobile, if you specify a ShortName for your Tile, the display name provided in your notification will not be used (the ShortName will always be displayed).

... ...

TileContent content = new TileContent() { Visual = new TileVisual() { Branding = TileBranding.NameAndLogo, DisplayName = "Wednesday 22", TileMedium = new TileBinding() { DisplayName = "Wed. 22", ... }, // Inherits DisplayName from Visual TileWide = new TileBinding() { ... } } };

Result:

Text The element is used to display text. You can use hints to modify how text appears. This is a line of text

new AdaptiveText() { Text = "This is a line of text" };

Result:

Text wrapping By default, text doesn't wrap and will continue off the edge of the tile. Use the hint-wrap attribute to set text wrapping on a text element. You can also control the minimum and maximum number of lines by using hintminLines and hint-maxLines, both of which accept positive integers. This is a line of wrapping text

new AdaptiveText() { Text = "This is a line of wrapping text", HintWrap = true };

Result:

Text styles Styles control the font size, color, and weight of text elements. There are a number of available styles, including a "subtle" variation of each style that sets the opacity to 60%, which usually makes the text color a shade of light gray. Header content Subheader content

new AdaptiveText() { Text = "Header content", HintStyle = AdaptiveTextStyle.Base }, new AdaptiveText() { Text = "Subheader content", HintStyle = AdaptiveTextStyle.CaptionSubtle }

Result:

Note The style defaults to caption if hint-style isn't specified. Basic text styles



Font height

Font weight

caption

12 effective pixels (epx)

Regular

body

15 epx

Regular

base

15 epx

Semibold

subtitle

20 epx

Regular

title

24 epx

Semilight

subheader

34 epx

Light

header

46 epx

Light

Numeral text style variations These variations reduce the line height so that content above and below come much closer to the text.

titleNumeral subheaderNumeral headerNumeral

Subtle text style variations Each style has a subtle variation that gives the text a 60% opacity, which usually makes the text color a shade of light gray.

captionSubtle bodySubtle baseSubtle subtitleSubtle titleSubtle

titleNumeralSubtle subheaderSubtle subheaderNumeralSubtle headerSubtle headerNumeralSubtle

Text alignment Text can be horizontally aligned left, center, or right. In left-to-right languages like English, text defaults to leftaligned. In right-to-left languages like Arabic, text defaults to right-aligned. You can manually set alignment with the hint-align attribute on elements. Hello

new AdaptiveText() { Text = "Hello", HintAlign = AdaptiveTextAlign.Center };

Result:

Groups and subgroups Groups allow you to semantically declare that the content inside the group is related and must be displayed in its entirety for the content to make sense. For example, you might have two text elements, a header, and a subheader, and it would not make sense for only the header to be shown. By grouping those elements inside a subgroup, the elements will either all be displayed (if they can fit) or not be displayed at all (because they can't fit). To provide the best experience across devices and screens, provide multiple groups. Having multiple groups allows your tile to adapt to larger screens. Note The only valid child of a group is a subgroup.

Jennifer Parker Photos from our trip Check out these awesome photos I took while in New Zealand! Steve Bosniak Build 2015 Dinner Want to go out for dinner after Build tonight?

TileWide = new TileBinding() { Branding = TileBranding.NameAndLogo, Content = new TileBindingContentAdaptive() { Children = { CreateGroup( from: "Jennifer Parker", subject: "Photos from our trip", body: "Check out these awesome photos I took while in New Zealand!"), // For spacing new AdaptiveText(), CreateGroup( from: "Steve Bosniak", subject: "Build 2015 Dinner", body: "Want to go out for dinner after Build tonight?") } } } ... private static AdaptiveGroup CreateGroup(string from, string subject, string body) { return new AdaptiveGroup() { Children = { new AdaptiveSubgroup() { Children = { new AdaptiveText() { Text = from, HintStyle = AdaptiveTextStyle.Subtitle }, new AdaptiveText() { Text = subject, HintStyle = AdaptiveTextStyle.CaptionSubtle }, new AdaptiveText() { Text = body, HintStyle = AdaptiveTextStyle.CaptionSubtle } } } } }; }

Result:

Subgroups (columns) Subgroups also allow you to divide data into semantic sections within a group. For live tiles, this visually translates to columns. The hint-weight attribute lets you to control the widths of columns. The value of hint-weight is expressed as a weighted proportion of available space, which is identical to GridUnitType.Star behavior. For equal-width columns, assign each weight to 1. hint-weight

Percentage of width

1

25%

1

25%

1

25%

1

25%

Total weight: 4

To make one column twice as large as another column, assign the smaller column a weight of 1 and the larger column a weight of 2. hint-weight

Percentage of width

1

33.3%

2

66.7%

Total weight: 3

If you want your first column to take up 20% of the total width and your second column to take up 80% of the

total width, assign the first weight to 20 and the second weight to 80. If your total weights equal 100, they'll act as percentages. hint-weight

Percentage of width

20

20%

80

80%

Total weight: 100

Note An 8-pixel margin is automatically added between the columns. When you have more than two subgroups, you should specify the hint-weight, which only accepts positive integers. If you don't specify hint-weight for the first subgroup, it will be assigned a weight of 50. The next subgroup that doesn't have a specified hint-weight will be assigned a weight equal to 100 minus the sum of the preceding weights, or to 1 if the result is zero. The remaining subgroups that don't have specified hint-weights will be assigned a weight of 1. Here's sample code for a weather tile that shows how you can achieve a tile with five columns of equal width:

Mon 63° 42° Tue 57° 38° Wed 59° 43° Thu 62° 42° Fri 71° 66°

TileWide = new TileBinding() { DisplayName = "Seattle", Branding = TileBranding.Name, Content = new TileBindingContentAdaptive() { Children = { new AdaptiveGroup() { Children = { CreateSubgroup("Mon", "Mostly Cloudy.png", "63°", "42°"), CreateSubgroup("Tue", "Cloudy.png", "57°", "38°"), CreateSubgroup("Wed", "Sunny.png", "59°", "43°"), CreateSubgroup("Thu", "Sunny.png", "62°", "42°"), CreateSubgroup("Fri", "Sunny.png", "71°", "66°") } } } } } ... private static AdaptiveSubgroup CreateSubgroup(string day, string image, string highTemp, string lowTemp) { return new AdaptiveSubgroup() { HintWeight = 1, Children = { new AdaptiveText() { Text = day, HintAlign = AdaptiveTextAlign.Center }, new AdaptiveImage() { Source = "Assets/Weather/" + image, HintRemoveMargin = true }, new AdaptiveText() { Text = highTemp, HintAlign = AdaptiveTextAlign.Center }, new AdaptiveText() { Text = lowTemp, HintAlign = AdaptiveTextAlign.Center, HintStyle = AdaptiveTextStyle.CaptionSubtle } } }; }

Result:

Images The element is used to display images on the tile notification. Images can be placed inline within the tile content (default), as a background image behind your content, or as a peek image that animates in from the top of the notification. Note There are restrictions on the file size and dimensions of images. With no extra behaviors specified, images will uniformly shrink or expand to fill the available width. The sample below shows a tile using two columns and inline images. The inline images stretch to fill the width of the column. Mon 63° 42° Tue 57° 38°

TileMedium = new TileBinding() { DisplayName = "Seattle", Branding = TileBranding.Name, Content = new TileBindingContentAdaptive() { Children = { new AdaptiveGroup() { Children = { CreateSubgroup("Mon", "Mostly Cloudy.png", "63°", "42°"), CreateSubgroup("Tue", "Cloudy.png", "57°", "38°") } } } } } ... private static AdaptiveSubgroup CreateSubgroup(string day, string image, string highTemp, string lowTemp) { return new AdaptiveSubgroup() { Children = { new AdaptiveText() { Text = day, HintAlign = AdaptiveTextAlign.Center }, new AdaptiveImage() { Source = "Assets/Weather/" + image, HintRemoveMargin = true }, new AdaptiveText() { Text = highTemp, HintAlign = AdaptiveTextAlign.Center }, new AdaptiveText() { Text = lowTemp, HintAlign = AdaptiveTextAlign.Center, HintStyle = AdaptiveTextStyle.CaptionSubtle } } }; }

Result:

Images placed in the root, or in the first group, will also stretch to fit the available height. Image alignment

Images can be set to align left, center, or right using the hint-align attribute. This will also cause images to display at their native resolution instead of stretching to fill width.



TileLarge = new TileBinding() { Content = new TileBindingContentAdaptive() { Children = { new AdaptiveImage() { Source = "Assets/fable.jpg", HintAlign = AdaptiveImageAlign.Center } } } }

Result:

Image margins

By default, inline images have an 8-pixel margin between any content above or below the image. This margin can be removed by using the hint-removeMargin attribute on the image. However, images always retain the 8-pixel margin from the edge of the tile, and subgroups (columns) always retain the 8-pixel padding between columns. Mon 63° 42° Tue 57° 38°

TileMedium = new TileBinding() { Branding = TileBranding.None, Content = new TileBindingContentAdaptive() { Children = { new AdaptiveGroup() { Children = { CreateSubgroup("Mon", "4.jpg", "63°", "42°"), CreateSubgroup("Tue", "3.jpg", "57°", "38°") } } } } } ... private static AdaptiveSubgroup CreateSubgroup(string day, string image, string highTemp, string lowTemp) { return new AdaptiveSubgroup() { HintWeight = 1, Children = { new AdaptiveText() { Text = day, HintAlign = AdaptiveTextAlign.Center }, new AdaptiveImage() { Source = "Assets/Numbers/" + image, HintRemoveMargin = true }, new AdaptiveText() { Text = highTemp, HintAlign = AdaptiveTextAlign.Center }, new AdaptiveText() { Text = lowTemp, HintAlign = AdaptiveTextAlign.Center, HintStyle = AdaptiveTextStyle.CaptionSubtle } } }; }

Image cropping

Images can be cropped into a circle using the hint-crop attribute, which currently only supports the values

"none" (default) or "circle." Hi, MasterHip

TileLarge = new TileBinding() { Content = new TileBindingContentAdaptive() { TextStacking = TileTextStacking.Center, Children = { new AdaptiveGroup() { Children = { new AdaptiveSubgroup() { HintWeight = 1 }, new AdaptiveSubgroup() { HintWeight = 2, Children = { new AdaptiveImage() { Source = "Assets/Apps/Hipstame/hipster.jpg", HintCrop = AdaptiveImageCrop.Circle } } }, new AdaptiveSubgroup() { HintWeight = 1 } } }, new AdaptiveText() { Text = "Hi,", HintStyle = AdaptiveTextStyle.Title, HintAlign = AdaptiveTextAlign.Center }, new AdaptiveText() { Text = "MasterHip", HintStyle = AdaptiveTextStyle.SubtitleSubtle, HintAlign = AdaptiveTextAlign.Center } } } }

Result:

Background image

To set a background image, place an image element in the root of the and set the placement attribute to "background." Mon 63° 42° ...

TileWide = new TileBinding() { Content = new TileBindingContentAdaptive() { BackgroundImage = new TileBackgroundImage() { Source = "Assets/Mostly Cloudy-Background.jpg" }, Children = { new AdaptiveGroup() { Children = { CreateSubgroup("Mon", "Mostly Cloudy.png", "63°", "42°") ... } } } } } ... private static AdaptiveSubgroup CreateSubgroup(string day, string image, string highTemp, string lowTemp) { return new AdaptiveSubgroup() { HintWeight = 1, Children = { new AdaptiveText() { Text = day, HintAlign = AdaptiveTextAlign.Center }, new AdaptiveImage() { Source = "Assets/Weather/" + image, HintRemoveMargin = true }, new AdaptiveText() { Text = highTemp, HintAlign = AdaptiveTextAlign.Center }, new AdaptiveText() { Text = lowTemp, HintAlign = AdaptiveTextAlign.Center, HintStyle = AdaptiveTextStyle.CaptionSubtle } } }; }

Result:

Peek image

You can specify an image that "peeks" in from the top of the tile. The peek image uses an animation to slide down/up from the top of the tile, peeking into view, and then later sliding back out to reveal the main content on the tile. To set a peek image, place an image element in the root of the , and set the placement attribute to "peek." New Message Hey, have you tried Windows 10 yet?

TileWide = new TileBinding() { Branding = TileBranding.Name, Content = new TileBindingContentAdaptive() { PeekImage = new TilePeekImage() { Source = "Assets/Apps/Hipstame/hipster.jpg" }, Children = { new AdaptiveText() { Text = "New Message" }, new AdaptiveText() { Text = "Hey, have you tried Windows 10 yet?", HintStyle = AdaptiveTextStyle.CaptionSubtle, HintWrap = true } } } }

Circle crop for peek and background images Use the hint-crop attribute on peek and background images to do a circle crop:

new TilePeekImage() { HintCrop = TilePeekImageCrop.Circle, Source = "Assets/Apps/Hipstame/hipster.jpg" }

The result will look like this:

Use both peek and background image To use both a peek and a background image on a tile notification, specify both a peek image and a background image in your notification payload. The result will look like this:

Peek and background image overlays

You can set a black overlay on your background and peek images using hint-overlay, which accepts integers from 0-100, with 0 being no overlay and 100 being full black overlay. You can use the overlay to help ensure that text on your tile is readable. Use hint-overlay on a background image Your background image will default to 20% overlay as long as you have some text elements in your payload (otherwise it will default to 0% overlay). ...

TileWide = new TileBinding() { Content = new TileBindingContentAdaptive() { BackgroundImage = new TileBackgroundImage() { Source = "Assets/Mostly Cloudy-Background.jpg", HintOverlay = 60 }, ... } }

hint-overlay Result:

Use hint-overlay on a peek image In Version 1511 of Windows 10, we support an overlay for your peek image too, just like your background image. Specify hint-overlay on the peek image element as an integer from 0-100. The default overlay for peek images is 0 (no overlay). ...

TileMedium = new TileBinding() { Content = new TileBindingContentAdaptive() { PeekImage = new TilePeekImage() { Source = "Assets/Map.jpg", HintOverlay = 20 }, ... } }

This example shows a peek image at 20% opacity (left) and at 0% opacity (right):

Vertical alignment (text stacking)

You can control the vertical alignment of content on your tile by using the hint-textStacking attribute on both the element and element. By default, everything is vertically aligned to the top, but you can also align content to the bottom or center. Text stacking on binding element

When applied at the level, text stacking sets the vertical alignment of the notification content as a whole, aligning in the available vertical space above the branding/badge area. Hi, MasterHip

TileMedium = new TileBinding() { Branding = TileBranding.Logo, Content = new TileBindingContentAdaptive() { TextStacking = TileTextStacking.Center, Children = { new AdaptiveText() { Text = "Hi,", HintStyle = AdaptiveTextStyle.Base, HintAlign = AdaptiveTextAlign.Center }, new AdaptiveText() { Text = "MasterHip", HintStyle = AdaptiveTextStyle.CaptionSubtle, HintAlign = AdaptiveTextAlign.Center } } } }

Text stacking on subgroup element

When applied at the level, text stacking sets the vertical alignment of the subgroup (column) content, aligning in the available vertical space within the entire group.

Hi, MasterHip

TileWide = new TileBinding() { Branding = TileBranding.NameAndLogo, Content = new TileBindingContentAdaptive() { Children = { new AdaptiveGroup() { Children = { // Image column new AdaptiveSubgroup() { HintWeight = 33, Children = { new AdaptiveImage() { Source = "Assets/Apps/Hipstame/hipster.jpg", HintCrop = AdaptiveImageCrop.Circle } } }, // Text column new AdaptiveSubgroup() { // Vertical align its contents TextStacking = TileTextStacking.Center, Children = { new AdaptiveText() { Text = "Hi,", HintStyle = AdaptiveTextStyle.Subtitle }, new AdaptiveText() { Text = "MasterHip", HintStyle = AdaptiveTextStyle.BodySubtle } } } } } } } }

Related topics Adaptive tiles schema Quickstart: Send a local tile notification Notifications library on GitHub Special tile templates catalog

Adaptive tile templates: schema and guidance 3/6/2017 • 1 min to read • Edit on GitHub

Here are the elements and attributes you use to create adaptive tiles. For instructions and examples, see Create adaptive tiles.

tile element visual

visual element binding+

binding element ( image | text | group )*

image element

text element

textStyle values: caption captionSubtle body bodySubtle base baseSubtle subtitle subtitleSubtle title titleSubtle titleNumeral subheader subheaderSubtle subheaderNumeral header headerSubtle headerNumeral

group element subgroup+

subgroup element ( text | image )*

Related topics Create adaptive tiles

Guidelines for tile and icon assets 3/6/2017 • 9 min to read • Edit on GitHub

App icon assets, which appear in a variety of forms throughout the Windows 10 operating system, are the calling cards for your Universal Windows Platform (UWP) app. These guidelines detail where app icon assets appear in the system, and provide in-depth design tips on how to create the most polished icons.

Adaptive scaling First, a brief overview on adaptive scaling to better understand how scaling works with assets. 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 UI elements across a variety of screen sizes and display resolutions. The scale factors are also compatible with the scale factors of other operating systems such as iOS and Android, which makes it easier to share assets between these platforms. The Store picks the assets to download based in part of the DPI of the device. Only the assets that best match the device are downloaded.

Tile elements The basic components of a Start tile consist of a back plate, an icon, a branding bar, margins, and an app title:

The branding bar at the bottom of a tile is where the app name, badging, and counter (if used) appear:

The height of the branding bar is based on the scale factor of the device on which it appears: SCALE FACTOR

PIXELS

100%

32

125%

40

150%

48

200%

64

400%

128

The system sets tile margins and cannot be modified. Most content appears inside the margins, as seen in this example:

Margin width is based on the scale factor of the device on which it appears: SCALE FACTOR

PIXELS

100%

8

125%

10

150%

12

200%

16

400%

32

Tile assets Each tile asset is the same size as the tile on which it is placed. You can brand your app's tiles with two different representations of an asset: 1. An icon or logo centered with padding. This lets the back plate color show through:

1. A full-bleed, branded tile without padding:

For consistency across devices, each tile size (small, medium, wide, and large) has its own sizing relationship. In order to achieve a consistent icon placement across tiles, we recommend a few basic padding guidelines for the following tile sizes. The area where the two purple overlays intersect represents the ideal footprint for an icon. Although icons won't always fit inside the footprint, the visual volume of an icon should be roughly equivalent to the provided examples. Small tile sizing:

Medium tile sizing:

Wide tile sizing:

Large tile sizing:

In this example, the icon is too large for the tile:

In this example, the icon is too small for the tile:

The following padding ratios are optimal for horizontally or vertically oriented icons. For small tiles, limit the icon width and height to 66% of the tile size:

For medium tiles, limit the icon width to 66% and height to 50% of tile size. This prevents overlapping of elements in the branding bar:

For wide tiles, limit the icon width to 66% and height to 50% of tile size. This prevents overlapping of elements in the branding bar:

For large tiles, limit the icon width and height to 50% of tile size:

Some icons are designed to be horizontally or vertically oriented, while others have more complex shapes that prevent them from fitting squarely within the target dimensions. Icons that appear to be centered can be weighted to one side. In this case, parts of an icon may hang outside the recommended footprint, provided it occupies the same visual weight as a squarely fitted icon:

With full-bleed assets, take into account elements that interact within the margins and edges of the tiles. Maintain

margins of at least 16% of the height or width of the tile. This percentage represents double the width of the margins at the smallest tile sizes:

In this example, margins are too tight:

Tile assets in list views Tiles can also appear in a list view. Sizing guidelines for tile assets that appear in list views are a bit different than tile assets previously outlined. This section details those sizing specifics.

Limit icon width and height to 75% of the tile size:

For vertical and horizontal icon formats, limit width and height to 75% of the tile size:

For full bleed artwork of important brand elements, maintain margins of at least 12.5%:

In this example, the icon is too big inside its tile:

In this example, the icon is too small inside its tile:

Target-based assets Target-based assets are for icons and tiles that appear on the Windows taskbar, task view, ALT+TAB, snap-assist, and the lower-right corner of Start tiles. You don't have to add padding to these assets; Windows adds padding if needed. These assets should account for a minimum footprint of 16 pixels. Here's an example of these assets as they appear in icons on the Windows taskbar:

Although these UI will use a target-based asset on top of a colored backplate by default, you may use a targetbased unplated asset as well. Unplated assets should be created with the possibility that they may appear on various background colors:

These are size recommendations for target-based assets, at 100% scale:

Iconic template app assets The iconic template (also known as the "IconWithBadge" template) lets you display a small image in the center of the tile. Windows 10 supports the template on both phone and tablet/desktop. (Learn about creating iconic tiles in the Special tile templates article.) Apps that use the iconic template, such as Messaging, Phone, and Store, have target-based assets that can feature a badge (with the live counter). As with other target-based assets, no padding is needed. Iconic assets aren't part of the app manifest, but are part of a live tile payload. Assets are scaled to fit and centered within a 3:2 ratio container:

For square assets, automatic centering within the container occurs:

For non-square assets, automatic horizontal/vertical centering and snapping to the width/height of the container occurs:

Splash screen assets The splash screen image can be given either as a direct path to an image file or as a resource. By using a resource reference, you can supply images of different scales so that Windows can choose the best size for the device and screen resolution. You can also supply high contrast images for accessibility and localized images to match different UI languages. If you open "Package.appxmanifest" in a text editor, the SplashScreen element appears as a child of the VisualElements element. The default splash screen markup in the manifest file looks like this in a text editor:

The splash screen asset is centered by whichever device it appears on:

High-contrast assets High-contrast mode makes use of separate sets of assets for high-contrast white (white background with black text) and high-contrast black (black background with white text). If you don't provide high-contrast assets for your app, standard assets will be used. If your app's standard assets provide an acceptable viewing experience when rendered on a black-and-white background, then your app should look at least satisfactory in high-contrast mode. If your standard assets don't afford an acceptable viewing experience when rendered on a black-and-white background, consider specifically including high-contrast assets. These examples illustrate the two types of high-contrast assets:

If you decide to provide high-contrast assets, you need to include both sets—both white-on-black and black-onwhite. When including these assets in your package, you could create a "contrast-black" folder for white-on-black assets, and a "contrast-white" folder for black-on-white assets.

Asset size tables At a bare minimum, we strongly recommend that you provide assets for the 100, 200, and 400 scale factors. Providing assets for all scale factors will provide the optimal user experience. Scale-based assets CATEGORY

ELEMENT NAME

AT 100% SCALE

AT 125% SCALE

AT 150% SCALE

AT 200% SCALE

AT 400% SCALE

Small

Square71x71L ogo

71x71

89x89

107x107

142x142

284x284

Medium

Square150x15 0Logo

150x150

188x188

225x225

300x300

600x600

Wide

Square310x15 0Logo

310x150

388x188

465x225

620x300

1240x600

CATEGORY

ELEMENT NAME

AT 100% SCALE

AT 125% SCALE

AT 150% SCALE

AT 200% SCALE

AT 400% SCALE

Large (desktop only)

Square310x31 0Logo

310x310

388x388

465x465

620x620

1240x1240

App list (icon)

Square44x44L ogo

44x44

55x55

66x66

88x88

176x176

File name examples for scale-based assets CATEGORY

ELEMENT NAME

AT 100% SCALE

AT 125% SCALE

AT 150% SCALE

Small

Square71x71Logo

AppNameSmallTile.sca le-100.png

AppNameSmallTile.sca le-125.png

AppNameSmallTile.sca le-150.png

Medium

Square150x150Logo

AppNameMedTile.scal e-100.png

AppNameMedTile.scal e-125.png

AppNameMedTile.scal e-150.png

Wide

Square310x150Logo

AppNameWideTile.sca le-100.png

AppNameWideTile.sca le-125.png

AppNameWideTile.sca le-150.png

Large (desktop only)

Square310x310Logo

AppNameLargeTile.sc ale-100.png

AppNameLargeTile.sc ale-125.png

AppNameLargeTile.sc ale-150.png

App list (icon)

Square44x44Logo

AppNameLargeTile.sc ale-100.png

AppNameLargeTile.sc ale-125.png

AppNameLargeTile.sc ale-150.png

CATEGORY

ELEMENT NAME

AT 200% SCALE

AT 400% SCALE

Small

Square71x71Logo

AppNameSmallTile.scale200.png

AppNameSmallTile.scale400.png

Medium

Square150x150Logo

AppNameMedTile.scale200.png

AppNameMedTile.scale400.png

Wide

Square310x150Logo

AppNameWideTile.scale200.png

AppNameWideTile.scale400.png

Large (desktop only)

Square310x310Logo

AppNameLargeTile.scale200.png

AppNameLargeTile.scale400.png

App list (icon)

Square44x44Logo

AppNameLargeTile.scale200.png

AppNameLargeTile.scale400.png

Target-based assets Target-based assets are used across multiple scale factors. The element name for target-based assets is Square44x44Logo. We strongly recommend submitting the following assets as a bare minimum: 16x16, 24x24, 32x32, 48x48, 256x256 The following table lists all target-based asset sizes and corresponding file name examples: ASSET SIZE

FILE NAME EXAMPLE

ASSET SIZE

FILE NAME EXAMPLE

16x16*

AppNameAppList.targetsize-16.png

24x24*

AppNameAppList.targetsize-24.png

32x32*

AppNameAppList.targetsize-32.png

48x48*

AppNameAppList.targetsize-48.png

256x256*

AppNameAppList.targetsize-256.png

20x20

AppNameAppList.targetsize-20.png

30x30

AppNameAppList.targetsize-30.png

36x36

AppNameAppList.targetsize-36.png

40x40

AppNameAppList.targetsize-40.png

60x60

AppNameAppList.targetsize-60.png

64x64

AppNameAppList.targetsize-64.png

72x72

AppNameAppList.targetsize-72.png

80x80

AppNameAppList.targetsize-80.png

96x96

AppNameAppList.targetsize-96.png

* Submit these asset sizes as a baseline

Asset types Listed here are all asset types, their uses, and recommended file names. Tile assets Centered assets are generally used on the Start to showcase your app. File name format: *Tile.scale-*.PNG Impacted apps: Every UWP app Uses: Default Start tiles (desktop and mobile) Action center (desktop and mobile) Task switcher (mobile) Share picker (mobile) Picker (mobile) Store Scalable list assets with plate These assets are used on surfaces that request scale factors. Assets either get plated by the system or come with their own background color if the app includes that.

File name format: *AppList.scale-*.PNG Impacted apps: Every UWP app Uses: Start all apps list (desktop) Start most-frequently used list (desktop) Task manager (desktop) Cortana search results Start all apps list (mobile) Settings Target-size list assets with plate These are fixed asset sizes that don't scale with plateaus. Mostly used for legacy experiences. Assets are checked by the system. File name format: *AppList.targetsize-*.PNG Impacted apps: Every UWP app Uses: Start jump list (desktop) Start lower corner of tile (desktop) Shortcuts (desktop) Control Panel (desktop) Target-size list assets without plate These are assets that don't get plated or scaled by the system. File name format: *AppList.targetsize-*_altform-unplated.PNG Impacted apps: Every UWP app Uses: Taskbar and taskbar thumbnail (desktop) Taskbar jumplist Task view ALT+TAB File extension assets These are assets specific to file extensions. They appear next to Win32-style file association icons in File Explorer and must be theme-agnostic. Sizing is different on desktop and mobile platforms. File name format: *LogoExtensions.targetsize-*.PNG Impacted apps: Music, Video, Photos, Microsoft Edge, Microsoft Office Uses: File Explorer Cortana Various UI surfaces (desktop) Splash screen The asset that appears on your app's splash screen. Automatically scales on both desktop and mobile platforms. File name format: *SplashScreen.screen-100.PNG Impacted apps: Every UWP app Uses: App's splash screen

Iconic tile assets These are assets for apps that make use of the iconic template. File name format: Not applicable Impacted apps: Messaging, Phone, Store, more Uses: Iconic tile

Related topics Special tile templates

Special tile templates 3/6/2017 • 6 min to read • Edit on GitHub

Special tile templates are unique templates that are either animated, or just allow you to do things that aren't possible with adaptive tiles. Each special tile template was specifically built for Windows 10, except for the iconic tile template, a classic special template that has been updated for Windows 10. This article covers three special tile templates: Iconic, Photos, and People.

Iconic tile template The iconic template (also known as the "IconWithBadge" template) lets you display a small image in the center of the tile. Windows 10 supports the template on both phone and tablet/desktop.

How to create an iconic tile

The following steps cover everything you need to know to create an iconic tile for Windows 10. At a high level, you need your iconic image asset, then you send a notification to the tile using the iconic template, and finally you send a badge notification that provides the number to be displayed on the tile.

Step 1: Create your image assets in PNG format

Create the icon assets for your tile and place those in your project resources with your other assets. At a bare minimum, create a 200x200 pixel icon, which works for both small and medium tiles on phone and desktop. To provide the best user experience, create an icon for each size. See sizing details in the below image. Save icon assets in PNG format and with transparency. On Windows Phone, every non-transparent pixel is displayed as white (RGB 255, 255, 255). For consistency and simplicity, use white for desktop icons as well. Windows 10 on tablet, laptop, and desktop only supports square icon assets. Phone supports both square assets and assets that are taller than they are wide, up to a 2:3 width:height ratio, which is useful for images such as a phone icon.

Step 2: Create your base tile You can use the iconic template on both primary and secondary tiles. If you're using it on a secondary tile, you'll first have to create the secondary tile or use an already-pinned secondary tile. Primary tiles are implicitly pinned and can always be sent notifications. Step 3: Send a notification to your tile Although this step can vary based on whether the notification is sent locally or via server push, the XML payload that you send remains the same. To send a local tile notification, create a TileUpdater for your tile (either primary or secondary tile), then send a notification to the tile that uses the iconic tile template as seen below. Ideally, you should also include bindings for wide and large tile sizes using adaptive tile templates. Here's sample code for the XML payload:

This iconic tile template XML payload uses an image element that points to the image that you created in Step 1. Now your tile is ready to display the badge next to your icon; all that's left is sending badge notifications. Step 4: Send a badge notification to your tile As with step 3, this step can vary based on whether the notification is sent locally or via server push, yet the XML payload that you send remains the same. To send a local badge notification, create a BadgeUpdater for your tile (either primary or secondary tile), then send a badge notification with your desired value (or clear the badge).

Here's sample code for the XML payload:

The tile's badge will update accordingly. Step 5: Putting it all together The following image illustrates how the various APIs and payloads are associated with each aspect of the iconic tile template. A tile notification (which contains those elements) is used to specify the iconic template and the image asset; a badge notification specifies the numerical value; tile properties control your tile's display name, color, and more.

Photos tile template The photos tile template lets you display a slideshow of photos on your live tile. The template is supported on all tile sizes, including small, and behaves the same on each tile size. The below example shows five frames of a medium tile that uses the photos template. The template has a zoom and cross-fade animation that cycles through selected photos and loops indefinitely.

How to use the photos template

Using the photos template is easy if you've installed the Notifications library. Although you can use raw XML, we highly recommend using the library so you don't have to worry about generating valid XML or XML-escaping content. Windows Phone displays up to 9 photos in a slideshow; tablet, laptop, and desktop display up to 12. For information about sending the tile notification, see the Send notifications article.



/* To use the Photos template... - On any TileBinding object - Set Content property to new instance of TileBindingContentPhotos - Add up to 12 images to Images property of TileBindingContentPhotos. */ TileContent content = new TileContent() { Visual = new TileVisual() { TileMedium = new TileBinding() { Content = new TileBindingContentPhotos() { Images = { new TileBasicImage() { Source = "Assets/1.jpg" }, new TileBasicImage() { Source = "ms-appdata:///local/Images/2.jpg" }, new TileBasicImage() { Source = "http://msn.com/images/3.jpg" } // TODO: Can have 12 images total } } } // TODO: Add other tile sizes } };

People tile template The People app in Windows 10 uses a special tile template that displays a collection of images in circles that slide

around vertically or horizontally on the tile. This tile template has been available since Windows 10 Build 10572, and anyone is welcome to use it in their app. The People tile template works on tiles of these sizes: Medium tile (TileMedium)

Wide tile (TileWide)

Large tile (desktop only) (TileLarge)

If you're using the Notifications library, all you have to do to make use of the People tile template is create a new TileBindingContentPeople object for your TileBinding content. The TileBindingContentPeople class has an Images property where you add your images. If you're using raw XML, set the hint-presentation to "people" and add your images as children of the binding element. The following C# code sample assumes that you're using the Notifications library.

TileContent content = new TileContent() { Visual = new TileVisual() { TileMedium = new TileBinding() { Content = new TileBindingContentPeople() { Images = { new TileBasicImage() { Source = "Assets/ProfilePics/1.jpg" }, new TileBasicImage() { Source = "Assets/ProfilePics/2.jpg" }, new TileBasicImage() { Source = "Assets/ProfilePics/3.jpg" }, new TileBasicImage() { Source = "Assets/ProfilePics/4.jpg" }, new TileBasicImage() { Source = "Assets/ProfilePics/5.jpg" }, new TileBasicImage() { Source = "Assets/ProfilePics/6.jpg" }, new TileBasicImage() { Source = "Assets/ProfilePics/7.jpg" }, new TileBasicImage() { Source = "Assets/ProfilePics/8.jpg" }, new TileBasicImage() { Source = "Assets/ProfilePics/9.jpg" } } } } } };



For the best user experience, we recommend that you provide the following number of photos for each tile size: Medium tile: 9 photos Wide tile: 15 photos Large tile: 20 photos Having that number of photos allows for a few empty circles, which means that the tile won't be too visually busy. Feel free to tweak the number of photos to get the look that works best for you. To send the notification, see Choose a notification delivery method.

Related topics Full code sample on GitHub Notifications library Tiles, badges, and notifications Create adaptive tiles

Adaptive tile templates: schema and documentation

Adaptive and interactive toast notifications 3/6/2017 • 19 min to read • Edit on GitHub

Adaptive and interactive toast notifications let you create flexible pop-up notifications with more content, optional inline images, and optional user interaction. The adaptive and interactive toast notifications model has these updates over the legacy toast template catalog: The option to include buttons and inputs on the notifications. Three different activation types for the main toast notification and for each action. The option to create a notification for certain scenarios, including alarms, reminders, and incoming calls. Note To see the legacy templates from Windows 8.1 and Windows Phone 8.1, see the legacy toast template catalog.

Getting started Install Notifications library. If you'd like to use C# instead of XML to generate notifications, install the NuGet package named Microsoft.Toolkit.Uwp.Notifications (search for "notifications uwp"). The C# samples provided in this article use version 1.0.0 of the NuGet package. Install Notifications Visualizer. This free UWP app helps you design interactive toast notifications by providing an instant visual preview of your toast as you edit it, similar to Visual Studio's XAML editor/design view. You can read this blog post for more information, and you can download Notifications Visualizer here.

Toast notification structure Toast notifications are constructed using XML, which would typically contain these key elements: covers the content available for the users to visually see, including text and images contains buttons/inputs the developer wants to add inside the notification specifies the sound played when the notification pops Here's a code example: Sample This is a simple toast notification example

ToastContent content = new ToastContent() { Launch = "app-defined-string", Visual = new ToastVisual() { BindingGeneric = new ToastBindingGeneric() { Children = { new AdaptiveText() { Text = "Sample" }, new AdaptiveText() { Text = "This is a simple toast notification example" } }, AppLogoOverride = new ToastGenericAppLogo() { Source = "oneAlarm.png" } } }, Actions = new ToastActionsCustom() { Buttons = { new ToastButton("check", "check") { ImageUri = "check.png" }, new ToastButton("cancel", "cancel") { ImageUri = "cancel.png" } } }, Audio = new ToastAudio() { Src = new Uri("ms-winsoundevent:Notification.Reminder") } };

Next we need to convert the toast into an XmlDocument object. If you defined the toast in an XML file (here named "content.xml"), use this code: string xmlText = File.ReadAllText("content.xml"); XmlDocument xmlContent = new XmlDocument(); xmlContent.LoadXml(xmlText);

Or, if you defined the toast template in C#, use this: XmlDocument xmlContent = content.GetXml();

Regardless of how you create the XMLDocument, you can then use this code to create and send the toast:

ToastNotification notification = new ToastNotification(xmlContent); ToastNotificationManager.CreateToastNotifier().Show(notification);

To see a complete app that shows toast notifications in action, see the Quickstart on Sending a local toast notifications. Here is a visual representation of the structure:

Visual

Inside the visual element, you must have exactly one binding element that contains the visual content of the toast. Tile notifications in Universal Windows Platform (UWP) apps support multiple templates that are based on different tile sizes. Toast notifications, however, have only one template name: ToastGeneric. Having just the one template name means: You can change the toast content, such as adding another line of text, adding an inline image, or changing the thumbnail image from displaying the app icon to something else, and do any of these things without worrying about changing the entire template or creating an invalid payload due to a mismatch between the template name and the content. You can use the same code to cons truct the same payload for the toast notification that targets to deliver to different types of Microsoft Windows devices, including phones, tablets, PCs, and Xbox One. Each of these devices will accept the notification and display it to the user under their UI policies with the appropriate visual affordances and interaction model. For all attributes supported in the visual section and its child elements, see the Schema section below. For more examples, see the XML examples section below. Your app's identity is conveyed via your app icon. However, if you use appLogoOverride, we will display your app name beneath your lines of text. NORMAL TOAST

TOAST WITH APPLOGOOVERRIDE

Actions

In UWP apps, you can add buttons and other inputs to your toast notifications, which lets users do more outside of the app. These actions are specified under the element, of which there are two types that you can specify: This appears as a button on desktop and mobile devices. You can specify up to five custom or system actions inside a toast notification. This allows users to provide input, such as quick replying to a message, or selecting an option from a drop-down menu. Both and are adaptive within the Windows family of devices. For example, on mobile or desktop devices, an to a user is a button on which to tap/click. A text is a box in which users can input text using either a physical keyboard or an on-screen keyboard. These elements will also adapt to future interaction scenarios, such as an action announced by voice or a text input taken by dictation. When an action is taken by the user, you can do one of the following by specifying the ActivationType attribute inside the element: Activating the app in the foreground, with an action-specific argument that can be used to navigate to a specific page/context. Activating the app's background task without affecting the user. Activating another app via protocol launch. Specify a system action to perform. The current available system actions are snoozing and dismissing scheduled alarm/reminder, which will be further explained in a section below. For all attributes supported in the visual section and its child elements, see the Schema section below. For more examples, see the XML examples section below. Audio

Custom audio has always been supported by Mobile, and is supported in Desktop Version 1511 (build 10586) or newer. Custom audio can be referenced via the following paths: ms-appx:/// ms-appdata:/// Alternatively, you can pick from the list of ms-winsoundevents, which have always been supported on both platforms. See the audio schema page for information on audio in toast notifications. To learn how to send a toast using custom audio, see this blog post.

Alarms, reminders, and incoming calls You can use toast notifications for alarms, reminders, and incoming calls. These special toasts have an appearance that's consistent with standard toasts, though special toasts feature some custom, scenario-based UI and patterns: A reminder toast notification will stay on screen until the user dismisses it or takes action. On Windows Mobile, the reminder toast notifications will also show up pre-expanded. In addition to sharing the above behaviors with reminder notifications, alarm notifications also automatically play looping audio. Incoming call notifications are displayed full screen on Windows Mobile devices. This is done by specifying the scenario attribute inside the root element of a toast notification – :

XML examples

Note The toast notification screenshots for these examples were taken from an app on desktop. On mobile devices, a toast notification may be collapsed when it pops up, with a grabber at the bottom of the toast to expand it. Notification with rich visual contents This example shows how you can have multiple lines of text, an optional small image to override the application logo, and an optional inline image thumbnail. Photo Share Andrew sent you a picture See it in full size!

ToastContent content = new ToastContent() { Launch = "app-defined-string", Visual = new ToastVisual() { BindingGeneric = new ToastBindingGeneric() { Children = { new AdaptiveText() { Text = "Photo Share" }, new AdaptiveText() { Text = "Andrew sent you a picture" }, new AdaptiveText() { Text = "See it in full size!" }, new AdaptiveImage() { Source = "https://unsplash.it/360/180?image=1043" } }, AppLogoOverride = new ToastGenericAppLogo() { Source = "https://unsplash.it/64?image=883", HintCrop = ToastGenericAppLogoCrop.Circle } } } };

Notification with actions This example creates a notification with two possible response actions. Microsoft Company Store New Halo game is back in stock!

ToastContent content = new ToastContent() { Launch = "app-defined-string", Visual = new ToastVisual() { BindingGeneric = new ToastBindingGeneric() { Children = { new AdaptiveText() { Text = "Microsoft Company Store" }, new AdaptiveText() { Text = "New Halo game is back in stock!" } } } }, Actions = new ToastActionsCustom() { Buttons = { new ToastButton("See more details", "details"), new ToastButton("Remind me later", "later") { ActivationType = ToastActivationType.Background } } } };

Notification with text input and actions, example 1 This example creates a notification that accepts text input, along with two resonse actions. Andrew B. Shall we meet up at 8?

ToastContent content = new ToastContent() { Launch = "app-defined-string", Visual = new ToastVisual() { BindingGeneric = new ToastBindingGeneric() { Children = { new AdaptiveText() { Text = "Andrew B." }, new AdaptiveText() { Text = "Shall we meet up at 8?" } }, AppLogoOverride = new ToastGenericAppLogo() { Source = "https://unsplash.it/64?image=883", HintCrop = ToastGenericAppLogoCrop.Circle } } }, Actions = new ToastActionsCustom() { Inputs = { new ToastTextBox("message") { PlaceholderContent = "Type a reply" } }, Buttons = { new ToastButton("Reply", "reply") { ActivationType = ToastActivationType.Background }, new ToastButton("Video call", "video") { ActivationType = ToastActivationType.Foreground } } } };

Notification with text input and actions, example 2 This example creates a notification that accepts text input and a single action.

Andrew B. Shall we meet up at 8?

ToastContent content = new ToastContent() { Launch = "app-defined-string", Visual = new ToastVisual() { BindingGeneric = new ToastBindingGeneric() { Children = { new AdaptiveText() { Text = "Andrew B." }, new AdaptiveText() { Text = "Shall we meet up at 8?" } }, AppLogoOverride = new ToastGenericAppLogo() { Source = "https://unsplash.it/64?image=883", HintCrop = ToastGenericAppLogoCrop.Circle } } }, Actions = new ToastActionsCustom() { Inputs = { new ToastTextBox("message") { PlaceholderContent = "Type a reply" } }, Buttons = { new ToastButton("Reply", "reply") { TextBoxId = "message", ImageUri = "Assets/Icons/send.png", ActivationType = ToastActivationType.Background } } } };

Notification with selection input and actions This example creates a notification with a drop-down selection menu, and two possible actions. Spicy Heaven When do you plan to come in tomorrow?

ToastContent content = new ToastContent() { Launch = "app-defined-string", Visual = new ToastVisual() { BindingGeneric = new ToastBindingGeneric() { Children = { new AdaptiveText() { Text = "Spicy Heaven" }, new AdaptiveText() { Text = "When do you plan to come in tomorrow?" } } } }, Actions = new ToastActionsCustom() { Inputs = { new ToastSelectionBox("time") { DefaultSelectionBoxItemId = "2", Items = { new ToastSelectionBoxItem("1", "Breakfast"), new ToastSelectionBoxItem("2", "Lunch"), new ToastSelectionBoxItem("3", "Dinner") } } }, Buttons = { new ToastButton("Reserve", "reserve") { ActivationType = ToastActivationType.Background }, new ToastButton("Call Restaurant", "call") { ActivationType = ToastActivationType.Foreground } } } };

Reminder notification Using a selection menu and two actions as in the previous example, we can create a reminder notification:

Adaptive Tiles Meeting Conf Room 2001 / Building 135 10:00 AM - 10:30 AM

ToastContent content = new ToastContent() { Launch = "action=viewEvent&eventId=1983", Scenario = ToastScenario.Reminder, Visual = new ToastVisual() { BindingGeneric = new ToastBindingGeneric() { Children = { new AdaptiveText() { Text = "Adaptive Tiles Meeting" }, new AdaptiveText() { Text = "Conf Room 2001 / Building 135" }, new AdaptiveText() { Text = "10:00 AM - 10:30 AM" } } } }, Actions = new ToastActionsCustom() { Inputs = { new ToastSelectionBox("snoozeTime") { DefaultSelectionBoxItemId = "15", Items = { new ToastSelectionBoxItem("5", "5 minutes"), new ToastSelectionBoxItem("15", "15 minutes"), new ToastSelectionBoxItem("60", "1 hour"), new ToastSelectionBoxItem("240", "4 hours"), new ToastSelectionBoxItem("1440", "1 day") } } }, Buttons = { new ToastButtonSnooze() { SelectionBoxId = "snoozeTime" }, new ToastButtonDismiss() } } };

Handling activation (foreground and background) To learn how to handle toast activations (the user clicking on your toast or buttons on the toast), see Quicstart: Sending a local toast notification and handling activation.

Schemas: and In the following XML schemas, a "?" suffix means that an attribute is optional. content

ToastContent content = new ToastContent() { Launch = ?, Duration = ?, ActivationType = ?, Scenario = ?, Visual = new ToastVisual() { Language = ?, BaseUri = ?, AddImageQuery = ?, BindingGeneric = new ToastBindingGeneric() { Children = { new AdaptiveText() { Text = ?, Language = ?, HintMaxLines = ? }, new AdaptiveGroup() { Children = { new AdaptiveSubgroup() { HintWeight = ?, HintTextStacking = ?, Children = { new AdaptiveText(), new AdaptiveImage() } } } }, new AdaptiveImage() { Source = ?, AddImageQuery = ?, AlternateText = ?, HintCrop = ? } } } }, Audio = new ToastAudio() { Src = ?, Loop = ?, Silent = ? } };

Attributes in launch? launch? = string This is an optional attribute.

A string that is passed to the application when it is activated by the toast. Depending on the value of activationType, this value can be received by the app in the foreground, inside the background task, or by another app that's protocol launched from the original app. The format and contents of this string are defined by the app for its own use. When the user taps or clicks the toast to launch its associated app, the launch string provides the context to the app that allows it to show the user a view relevant to the toast content, rather than launching in its default way. If the activation is happened because user clicked on an action, instead of the body of the toast, the developer retrieves back the "arguments" pre-defined in that tag, instead of "launch" pre-defined in the tag. duration? duration? = "short|long" This is an optional attribute. Default value is "short". This is only here for specific scenarios and appCompat. You don't need this for the alarm scenario anymore. We don't recommend using this property. activationType? activationType? = "foreground | background | protocol | system" This is an optional attribute. The default value is "foreground". scenario? scenario? = "default | alarm | reminder | incomingCall" This is an optional attribute, default value is "default". You do not need this unless your scenario is to pop an alarm, reminder, or incoming call. Do not use this just for keeping your notification persistent on screen. Attributes in lang? See this element schema article for details on this optional attribute. baseUri? See this element schema article for details on this optional attribute. addImageQuery? See this element schema article for details on this optional attribute. Attributes in template? [Important] template? = "ToastGeneric" If you are using any of the new adaptive and interactive notification features, please make sure you start using "ToastGeneric" template instead of the legacy template. Using the legacy templates with the new actions might work now, but that is not the intended use case, and we cannot guarantee that will continue working. lang? See this element schema article for details on this optional attribute.

baseUri? See this element schema article for details on this optional attribute. addImageQuery? See this element schema article for details on this optional attribute. Attributes in lang? See this element schema article for details on this optional attribute. Attributes in src See this element schema article for details on this required attribute. placement? placement? = "inline" | "appLogoOverride" This attribute is optional. This specifies where this image will be displayed. "inline" means inside the toast body, below the text; "appLogoOverride" means replace the application icon (that shows up on the top left corner of the toast). You can have up to one image for each placement value. alt? See this element schema article for details on this optional attribute. addImageQuery? See this element schema article for details on this optional attribute. hint-crop? hint-crop? = "none" | "circle" This attribute is optional. "none" is the default value which means no cropping. "circle" crops the image to a circular shape. Use this for profile images of a contact, images of a person, and so on. Attributes in src? See this element schema article for details on this optional attribute. loop? See this element schema article for details on this optional attribute. silent? See this element schema article for details on this optional attribute.

Schemas:

In the following XML schemas, a "?" suffix means that an attribute is optional.

ToastContent content = new ToastContent() { Visual = ... Actions = new ToastActionsCustom() { Inputs = { new ToastSelectionBox("id") { Title = ? DefaultSelectionBoxItemId = ?, Items = { new ToastSelectionBoxItem("id", "content") } }, new ToastTextBox("id") { Title = ?, PlaceholderContent = ?, DefaultInput = ? } }, Buttons = { new ToastButton("content", "args") { ActivationType = ?, ImageUri = ?, TextBoxId = ? }, new ToastButtonSnooze("content") { SelectionBoxId = "snoozeTime" }, new ToastButtonDismiss("content") } } };

Attributes in id id = string

This attribute is required. The id attribute is required and is used by developers to retrieve user inputs once the app is activated (in the foreground or background). type type = "text | selection" This attribute is required. It is used to specify a text input or input from a list of pre-defined selections. On mobile and desktop, this is to specify whether you want a textbox input or a listbox input. title? title? = string The title attribute is optional and is for developers to specify a title for the input for shells to render when there is affordance. For mobile and desktop, this title will be displayed above the input. placeHolderContent? placeHolderContent? = string The placeHolderContent attribute is optional and is the grey-out hint text for text input type. This attribute is ignored when the input type is not "text". defaultInput? defaultInput? = string The defaultInput attribute is optional and is used to provide a default input value. If the input type is "text", this will be treated as a string input. If the input type is "selection", this is expected to be the id of one of the available selections inside this input's elements. Attributes in id This attribute is required. It's used to identify user selections. The id is returned to your app. content This attribute is required. It provides the string to display for this selection element. Attributes in content content = string The content attribute is required. It provides the text string displayed on the button. arguments arguments = string The arguments attribute it required. It describes the app-defined data that the app can later retrieve once it is activated from user taking this action. activationType? activationType? = "foreground | background | protocol | system"

The activationType attribute is optional and its default value is "foreground". It describes the kind of activation this action will cause: foreground, background, or launching another app via protocol launch, or invoking a system action. imageUri? imageUri? = string imageUri is optional and is used to provide an image icon for this action to display inside the button alone with the text content. hint-inputId hint-inputId = string The hint-inpudId attribute is required. It's specifically used for the quick reply scenario. The value needs to be the id of the input element desired to be associated with. In mobile and desktop, this will put the button right next to the input box.

Attributes for system-handled actions The system can handle actions for snoozing and dismissing notifications if you don't want your app to handle the snoozing/rescheduling of notifications as a background task. System-handled actions can be combined (or individually specified), but we don't recommend implementing a snooze action without a dismiss action. System commands combo: SnoozeAndDismiss

ToastContent content = new ToastContent() { Visual = ... Actions = new ToastActionsSnoozeAndDismiss() };

Individual system-handled actions

ToastContent content = new ToastContent() { Visual = ... Actions = new ToastActionsCustom() { Inputs = { new ToastSelectionBox("snoozeTime") { DefaultSelectionBoxItemId = "15", Items = { new ToastSelectionBoxItem("5", "5 minutes"), new ToastSelectionBoxItem("10", "10 minutes"), new ToastSelectionBoxItem("20", "20 minutes"), new ToastSelectionBoxItem("30", "30 minutes"), new ToastSelectionBoxItem("60", "1 hour") } } }, Buttons = { new ToastButtonSnooze() { SelectionBoxId = "snoozeTime" }, new ToastButtonDismiss() } } };

To construct individual snooze and dismiss actions, do the following: Specify activationType = "system" Specify arguments = "snooze" | "dismiss" Specify content: If you want localized strings of "snooze" and "dismiss" to be displayed on the actions, specify content to be an empty string: If you want a customized string, just provide its value: Specify input: If you don't want the user to select a snooze interval and instead just want your notification to snooze only once for a system-defined time interval (that is consistent across the OS), then don't construct any at all. If you want to provide snooze interval selections: Specify hint-inputId in the snooze action Match the id of the input with the hint-inputId of the snooze action: Specify selection id to be a nonNegativeInteger which represents snooze interval in minutes: means snoozing for 4 hours Make sure that the value of defaultInput in matches with one of the ids of the children elements Provide up to (but no more than) 5 values

Related topics

Quickstart: Send a local toast and handle activation Notifications library on GitHub

Badge notifications for UWP apps 3/6/2017 • 2 min to read • Edit on GitHub

A notification badge conveys summary or status information specific to your app. They can be numeric (1-99) or one of a set of system-provided glyphs. Examples of information best conveyed through a badge include network connection status in an online game, user status in a messaging app, number of unread mails in a mail app, and number of new posts in a social media A tile with a numeric badge displaying the number 63 to indicate 63 unread mails. app. Notification badges appear on your app's taskbar icon and in the lower-right corner of its start tile, regardless of whether the app is running. Badges can be displayed on all tile sizes. NOTE You cannot provide your own badge image; only system-provided badge images can be used.

Numeric badges VALUE

BADGE

XML

A number from 1 to 99. A value of 0 is equivalent to the glyph value "none" and will clear the badge.



Any number greater than 99.



Glyph badges Instead of a number, a badge can display one of a non-extensible set of status glyphs. STATUS

GLYPH

none

(No badge shown.)

XML

activity



alarm



alert



attention



available



away



busy



error



newMessage



paused



playing



unavailable



Create a badge These examples show you how to to create a badge update. Create a numeric badge

private void setBadgeNumber(int num) { // Get the blank badge XML payload for a badge number XmlDocument badgeXml = BadgeUpdateManager.GetTemplateContent(BadgeTemplateType.BadgeNumber); // Set the value of the badge in the XML to our number XmlElement badgeElement = badgeXml.SelectSingleNode("/badge") as XmlElement; badgeElement.SetAttribute("value", num.ToString()); // Create the badge notification BadgeNotification badge = new BadgeNotification(badgeXml); // Create the badge updater for the application BadgeUpdater badgeUpdater = BadgeUpdateManager.CreateBadgeUpdaterForApplication(); // And update the badge badgeUpdater.Update(badge); }

Create a glyph badge private void updateBadgeGlyph() { string badgeGlyphValue = "alert"; // Get the blank badge XML payload for a badge glyph XmlDocument badgeXml = BadgeUpdateManager.GetTemplateContent(BadgeTemplateType.BadgeGlyph); // Set the value of the badge in the XML to our glyph value Windows.Data.Xml.Dom.XmlElement badgeElement = badgeXml.SelectSingleNode("/badge") as Windows.Data.Xml.Dom.XmlElement; badgeElement.SetAttribute("value", badgeGlyphValue); // Create the badge notification BadgeNotification badge = new BadgeNotification(badgeXml); // Create the badge updater for the application BadgeUpdater badgeUpdater = BadgeUpdateManager.CreateBadgeUpdaterForApplication(); // And update the badge badgeUpdater.Update(badge); }

Clear a badge private void clearBadge() { BadgeUpdateManager.CreateBadgeUpdaterForApplication().Clear(); }

Get the sample code Notifications sample Shows how to create live tiles, send badge updates, and display toast notifications.

Related articles Adaptive and interactive toast notifications Create tiles Create adaptive tiles

Notifications Visualizer 3/6/2017 • 1 min to read • Edit on GitHub

Notifications Visualizer is a new Universal Windows Platform (UWP) app in the Store that helps developers design adaptive live tiles for Windows 10.

Overview The Notifications Visualizer app provides instant visual previews of your tile as you edit, similar to Visual Studio's XAML editor/design view. The app also checks for errors, which ensures that you create a valid tile payload. This screenshot from the app shows the XML payload and how tile sizes appear on a selected device:

With Notifications Visualizer, you can create and test adaptive tile payloads without having to edit and deploy the app itself. Once you've created a payload with ideal visual results you can integrate that into your app. See Send a local tile notification to learn more. Note Notifications Visualizer's simulation of the Windows Start menu isn't always completely accurate, and it doesn't support some payload properties like baseUri. When you have the tile design you want, test it by pinning the tile to the actual Start menu to verify that it appears as you intend.

Features Notifications Visualizer comes with a number of sample payloads to showcase what's possible with adaptive live tiles and to help you get started. You can experiment with all the different text options, groups/subgroups, background images, and you can see how the tile adapts to different devices and screens. Once you've made changes, you can save your updated payload to a file for future use. The editor provides real-time errors and warnings. For example, if your app payload is limited to less than 5 KB (a platform limitation), Notifications Visualizer warns you if your payload exceeds that limit. It gives you warnings for incorrect attribute names or values, which helps you debug visual issues. You can control tile properties like display name, color, logos, ShowName, badge value. These options help you instantly understand how your tile properties and tile notification payloads interact, and the results they produce.

This screenshot from the app shows the tile editor:

Related topics Get Notifications Visualizer in the Store Create adaptive tiles Adaptive tile templates: schema and documentation Tiles and toasts (MSDN blog)

Choose a notification delivery method 3/6/2017 • 5 min to read • Edit on GitHub

This article covers the four notification options—local, scheduled, periodic, and push—that deliver tile and badge updates and toast notification content. A tile or a toast notification can get information to your user even when the user is not directly engaged with your app. The nature and content of your app and the information that you want to deliver can help you determine which notification method or methods is best for your scenario.

Notification delivery methods overview There are four mechanisms that an app can use to deliver a notification: Local Scheduled Periodic Push This table summarizes the notification delivery types. DELIVERY METHOD

USE WITH

DESCRIPTION

EXAMPLES

Local

Tile, Badge, Toast

A set of API calls that send notifications while your app is running, directly updating the tile or badge, or sending a toast notification.

A music app updates its tile to show what's "Now Playing". A game app updates its tile with the user's high score when the user leaves the game. A badge whose glyph indicates that there's new info int the app is cleared when the app is activated.

Scheduled

Tile, Toast

A set of API calls that schedule a notification in advance, to update at the time you specify.

A calendar app sets a toast notification reminder for an upcoming meeting.

DELIVERY METHOD

USE WITH

DESCRIPTION

EXAMPLES

Periodic

Tile, Badge

Notifications that update tiles and badges regularly at a fixed time interval by polling a cloud service for new content.

A weather app updates its tile, which shows the forecast, at 30-minute intervals. A "daily deals" site updates its deal-ofthe-day every morning. A tile that displays the days until an event updates the displayed countdown each day at midnight.

Push

Tile, Badge, Toast, Raw

Notifications sent from a cloud server, even if your app isn't running.

A shopping app sends a toast notification to let a user know about a sale on an item that they're watching. A news app updates its tile with breaking news as it happens. A sports app keeps its tile up-to-date during an ongoing game. A communication app provides alerts about incoming messages or phone calls.

Local notifications Updating the app tile or badge or raising a toast notification while the app is running is the simplest of the notification delivery mechanisms; it only requires local API calls. Every app can have useful or interesting information to show on the tile, even if that content only changes after the user launches and interacts with the app. Local notifications are also a good way to keep the app tile current, even if you also use one of the other notification mechanisms. For instance, a photo app tile could show photos from a recently added album. We recommended that your app update its tile locally on first launch, or at least immediately after the user makes a change that your app would normally reflect on the tile. That update isn't seen until the user leaves the app, but by making that change while the app is being used ensures that the tile is already up-to-date when the user departs. While the API calls are local, the notifications can reference web images. If the web image is not available for download, is corrupted, or doesn't meet the image specifications, tiles and toast respond differently: Tiles: The update is not shown Toast: The notification is displayed, but your image is dropped By default, local toast notifications expire in three days, and local tile notifications never expire. We recommend

overriding these defaults with an explicit expiration time that makes sense for your notifications (toasts have a max of three days). For more information, see these topics: Send a local tile notification Send a local toast notification Universal Windows Platform (UWP) notifications code samples

Scheduled notifications Scheduled notifications are the subset of local notifications that can specify the precise time when a tile should be updated or a toast notification should be shown. Scheduled notifications are ideal in situations where the content to be updated is known in advance, such as a meeting invitation. If you don't have advance knowledge of the notification content, you should use a push or periodic notification. Note that scheduled notifications cannot be used for badge notifications; badge notifications are best served by local, periodic, or push notifications. By default, scheduled notifications expire three days from the time they are delivered. You can override this default expiration time on scheduled tile notifications, but you cannot override the expiration time on scheduled toasts. For more information, see these topics: Universal Windows Platform (UWP) notifications code samples

Periodic notifications Periodic notifications give you live tile updates with a minimal cloud service and client investment. They are also an excellent method of distributing the same content to a wide audience. Your client code specifies the URL of a cloud location that Windows polls for tile or badge updates, and how often the location should be polled. At each polling interval, Windows contacts the URL to download the specified XML content and display it on the tile. Periodic notifications require the app to host a cloud service, and this service will be polled at the specified interval by all users who have the app installed. Note that periodic updates cannot be used for toast notifications; toast notifications are best served by scheduled or push notifications. By default, periodic notifications expire three days from the time polling occurs. If needed, you can override this default with an explicit expiration time. For more information, see these topics: Periodic notification overview Universal Windows Platform (UWP) notifications code samples

Push notifications Push notifications are ideal to communicate real-time data or data that is personalized for your user. Push notifications are used for content that is generated at unpredictable times, such as breaking news, social network updates, or instant messages. Push notifications are also useful in situations where the data is time-sensitive in a way that would not suit periodic notifications, such as sports scores during a game. Push notifications require a cloud service that manages push notification channels and chooses when and to whom to send notifications. By default, push notifications expire three days from the time they are received by the device. If needed, you can override this default with an explicit expiration time (toasts have a max of three days).

For more information, see: Windows Push Notification Services (WNS) overview Guidelines for push notifications Universal Windows Platform (UWP) notifications code samples

Related topics Send a local tile notification Send a local toast notification Guidelines for push notifications Guidelines for toast notifications Periodic notification overview Windows Push Notification Services (WNS) overview Universal Windows Platform (UWP) notifications code samples on GitHub

Send a local tile notification 3/6/2017 • 6 min to read • Edit on GitHub

Primary app tiles in Windows 10 are defined in your app manifest, while secondary tiles are programmatically created and defined by your app code. This article describes how to send a local tile notification to a primary tile and a secondary tile using adaptive tile templates. (A local notification is one that's sent from app code as opposed to one that's pushed or pulled from a web server.)

NOTE Learn about creating adaptive tiles and adaptive tile template schema.

Install the NuGet package We recommend installing the Notifications library NuGet package, which simplifies things by generating tile payloads with objects instead of raw XML. The inline code examples in this article are for C# using the Notifications library. (If you'd prefer to create your own XML, you can find code examples without the Notifications library toward the end of the article.)

Add namespace declarations To access the tile APIs, include the Windows.UI.Notifications namespace. We also recommend including the NotificationsExtensions.Tiles namespace so that you can take advantage of our tile helper APIs (you must install the Notifications library NuGet package to access these APIs). using Windows.UI.Notifications; using Microsoft.Toolkit.Uwp.Notifications; // Notifications library

Create the notification content In Windows 10, tile payloads are defined using adaptive tile templates, which allow you to create custom visual layouts for your notifications. (To learn what's possible with adaptive tiles, see the Create adaptive tiles and Adaptive tile templates articles.) This code example creates adaptive tile content for medium and wide tiles.

// In a real app, these would be initialized with actual data string from = "Jennifer Parker"; string subject = "Photos from our trip"; string body = "Check out these awesome photos I took while in New Zealand!";

// Construct the tile content TileContent content = new TileContent() { Visual = new TileVisual() { TileMedium = new TileBinding() { Content = new TileBindingContentAdaptive() { Children = { new AdaptiveText() { Text = from }, new AdaptiveText() { Text = subject, HintStyle = AdaptiveTextStyle.CaptionSubtle }, new AdaptiveText() { Text = body, HintStyle = AdaptiveTextStyle.CaptionSubtle } } } }, TileWide = new TileBinding() { Content = new TileBindingContentAdaptive() { Children = { new AdaptiveText() { Text = from, HintStyle = AdaptiveTextStyle.Subtitle }, new AdaptiveText() { Text = subject, HintStyle = AdaptiveTextStyle.CaptionSubtle }, new AdaptiveText() { Text = body, HintStyle = AdaptiveTextStyle.CaptionSubtle } } } } } };

The notification content looks like the following when displayed on a medium tile:

Create the notification Once you have your notification content, you'll need to create a new TileNotification. The TileNotification constructor takes a Windows Runtime XmlDocument object, which you can obtain from the TileContent.GetXml method if you're using the Notifications library. This code example creates a notification for a new tile. // Create the tile notification var notification = new TileNotification(content.GetXml());

Set an expiration time for the notification (optional) By default, local tile and badge notifications don't expire, while push, periodic, and scheduled notifications expire after three days. Because tile content shouldn't persist longer than necessary, it's a best practice to set an expiration time that makes sense for your app, especially on local tile and badge notifications. This code example creates a notification that expires and will be removed from the tile after ten minutes. tileNotification.ExpirationTime = DateTimeOffset.UtcNow.AddMinutes(10);

Send the notification Although locally sending a tile notification is simple, sending the notification to a primary or secondary tile is a bit different. Primary tile To send a notification to a primary tile, use the TileUpdateManager to create a tile updater for the primary tile, and send the notification by calling "Update". Regardless of whether it's visible, your app's primary tile always exists, so you can send notifications to it even when it's not pinned. If the user pins your primary tile later, the notifications that you sent will appear then. This code example sends a notification to a primary tile. // Send the notification to the primary tile TileUpdateManager.CreateTileUpdaterForApplication().Update(notification);

Secondary tile To send a notification to a secondary tile, first make sure that the secondary tile exists. If you try to create a tile updater for a secondary tile that doesn't exist (for example, if the user unpinned the secondary tile), an exception will be thrown. You can use SecondaryTile.Exists(tileId) to discover if your secondary tile is pinned, and then create a tile updater for the secondary tile and send the notification. This code example sends a notification to a secondary tile.

// If the secondary tile is pinned if (SecondaryTile.Exists("MySecondaryTile")) { // Get its updater var updater = TileUpdateManager.CreateTileUpdaterForSecondaryTile("MySecondaryTile"); // And send the notification updater.Update(notification); }

Clear notifications on the tile (optional) In most cases, you should clear a notification once the user has interacted with that content. For example, when the user launches your app, you might want to clear all the notifications from the tile. If your notifications are time-bound, we recommend that you set an expiration time on the notification instead of explicitly clearing the notification. This code example clears the tile notification for the primary tile. You can do the same for secondary tiles by creating a tile updater for the secondary tile. TileUpdateManager.CreateTileUpdaterForApplication().Clear();

For a tile with the notification queue enabled and notifications in the queue, calling the Clear method empties the queue. You can't, however, clear a notification via your app's server; only the local app code can clear notifications. Periodic or push notifications can only add new notifications or replace existing notifications. A local call to the Clear method will clear the tile whether or not the notifications themselves came via push, periodic, or local. Scheduled notifications that haven't yet appeared are not cleared by this method.

Next steps Using the notification queue Now that you have done your first tile update, you can expand the functionality of the tile by enabling a notification queue. Other notification delivery methods This article shows you how to send the tile update as a notification. To explore other methods of notification delivery, including scheduled, periodic, and push, see Delivering notifications. XmlEncode delivery method

If you're not using the Notifications library, this notification delivery method is another alternative. public string XmlEncode(string text) { StringBuilder builder = new StringBuilder(); using (var writer = XmlWriter.Create(builder)) { writer.WriteString(text); } return builder.ToString(); }

Code examples without Notifications library If you prefer to work with raw XML instead of the Notifications library NuGet package, use these alternate code examples to first three examples provided in this article. The rest of the code examples can be used either with the Notifications library or with raw XML. Add namespace declarations using Windows.UI.Notifications; using Windows.Data.Xml.Dom;

Create the notification content // In a real app, these would be initialized with actual data string from = "Jennifer Parker"; string subject = "Photos from our trip"; string body = "Check out these awesome photos I took while in New Zealand!";

// TODO - all values need to be XML escaped

// Construct the tile content as a string string content = $@" {from} {subject} {body} {from} {subject} {body} ";

Create the notification

// Load the string into an XmlDocument XmlDocument doc = new XmlDocument(); doc.LoadXml(content); // Then create the tile notification var notification = new TileNotification(doc);

Related topics Create adaptive tiles Adaptive tile templates: schema and documentation Notifications library Full code sample on GitHub Windows.UI.Notifications namespace How to use the notification queue (XAML) Delivering notifications

Periodic notification overview 3/6/2017 • 6 min to read • Edit on GitHub

Periodic notifications, which are also called polled notifications, update tiles and badges at a fixed interval by downloading content from a cloud service. To use periodic notifications, your client app code needs to provide two pieces of information: The Uniform Resource Identifier (URI) of a web location for Windows to poll for tile or badge updates for your app How often that URI should be polled Periodic notifications enable your app to get live tile updates with minimal cloud service and client investment. Periodic notifications are a good delivery method for distributing the same content to a wide audience. Note You can learn more by downloading the Push and periodic notifications sample for Windows 8.1 and reusing its source code in your Windows 10 app.

How it works Periodic notifications require that your app hosts a cloud service. The service will be polled periodically by all users who have the app installed. At each polling interval, such as once an hour, Windows sends an HTTP GET request to the URI, downloads the requested tile or badge content (as XML) that is supplied in response to the request, and displays the content on the app's tile. Note that periodic updates cannot be used with toast notifications. Toast is best delivered through scheduled or push notifications.

URI location and XML content Any valid HTTP or HTTPS web address can be used as the URI to be polled. The cloud server's response includes the downloaded content. The content returned from the URI must conform to the Tile or Badge XML schema specification, and must be UTF-8 encoded. You can use defined HTTP headers to specify the expiration time or tag for the notification.

Polling Behavior Call one of these methods to begin polling: StartPeriodicUpdate (Tile) StartPeriodicUpdate (Badge) StartPeriodicUpdateBatch (Tile) When you call one of these methods, the URI is immediately polled and the tile or badge is updated with the received contents. After this initial poll, Windows continues to provide updates at the requested interval. Polling continues until you explicitly stop it (with TileUpdater.StopPeriodicUpdate), your app is uninstalled, or, in the case of a secondary tile, the tile is removed. Otherwise, Windows continues to poll for updates to your tile or badge even if your app is never launched again. The recurrence interval

You specify the recurrence interval as a parameter of the methods listed above. Note that while Windows makes a best effort to poll as requested, the interval is not precise. The requested poll interval can be delayed by up to 15

minutes at the discretion of Windows. The start time

You optionally can specify a particular time of day to begin polling. Consider an app that changes its tile content just once a day. In such a case, we recommend that you poll close to the time that you update your cloud service. For example, if a daily shopping site publishes the day's offers at 8 AM, poll for new tile content shortly after 8 AM. If you provide a start time, the first call to the method polls for content immediately. Then, regular polling starts within 15 minutes of the provided start time. Automatic retry behavior

The URI is polled only if the device is online. If the network is available but the URI cannot be contacted for any reason, this iteration of the polling interval is skipped, and the URI will be polled again at the next interval. If the device is in an off, sleep, or hibernated state when a polling interval is reached, the URI is polled when the device returns from its off or sleep state. Handling app updates

If you release an app update that changes your polling URI, you should add a daily time trigger background task which calls StartPeriodicUpdate with the new URI to ensure your tiles are using the new URI. Otherwise, if users receive your app update but don't launch your app, their tiles will still be using the old URI, which may fail to display if the URI is now invalid or if the returned payload references local images that no longer exist.

Expiration of tile and badge notifications By default, periodic tile and badge notifications expire three days from the time they are downloaded. When a notification expires, the content is removed from the badge, tile, or queue and is no longer shown to the user. It is a best practice to set an explicit expiration time on all periodic tile and badge notifications, using a time that makes sense for your app or notification, to ensure that the content does not persist longer than it is relevant. An explicit expiration time is essential for content with a defined life span. It also assures the removal of stale content if your cloud service becomes unreachable, or if the user disconnects from the network for an extended period of time. Your cloud service sets an expiration date and time for a notification by including the X-WNS-Expires HTTP header in the response payload. The X-WNS-Expires HTTP header conforms to the HTTP-date format. For more information, see StartPeriodicUpdate or StartPeriodicUpdateBatch. For example, during a stock market's active trading day, you can set the expiration for a stock price update to twice that of your polling interval (such as one hour after receipt if you are polling every half-hour). As another example, a news app might determine that one day is an appropriate expiration time for a daily news tile update.

Periodic notifications in the notification queue You can use periodic tile updates with notification cycling. By default, a tile on the Start screen shows the content of a single notification until it is replaced by a new notification. When you enable cycling, up to five notifications are maintained in a queue and the tile cycles through them. If the queue has reached its capacity of five notifications, the next new notification replaces the oldest notification in the queue. However, by setting tags on your notifications, you can affect the queue's replacement policy. A tag is an app-specific, case-insensitive string of up to 16 alphanumeric characters, specified in the X-WNS-Tag HTTP header in the response payload. Windows compares the tag of an incoming notification with the tags of all notifications already in the queue. If a match is found, the new notification replaces the queued notification with the same tag. If no match is found, the default replacement rule is applied and the new notification replaces the oldest notification in the queue. You can use notification queuing and tagging to implement a variety of rich notification scenarios. For example, a stock app could send five notifications, each about a different stock and each tagged with a stock name. This

prevents the queue from ever containing two notifications for the same stock, the older of which is out of date. For more information, see Using the notification queue. Enabling the notification queue

To implement a notification queue, first enable the queue for your tile (see How to use the notification queue with local notifications). The call to enable the queue needs to be done only once in your app's lifetime, but there is no harm in calling it each time your app is launched. Polling for more than one notification at a time

You must provide a unique URI for each notification that you'd like Windows to download for your tile. By using the StartPeriodicUpdateBatch method, you can provide up to five URIs at once for use with the notification queue. Each URI is polled for a single notification payload, at or near the same time. Each polled URI can return its own expiration and tag value.

Related topics Guidelines for periodic notifications How to set up periodic notifications for badges How to set up periodic notifications for tiles

Windows Push Notification Services (WNS) overview 3/6/2017 • 12 min to read • Edit on GitHub

The Windows Push Notification Services (WNS) enables third-party developers to send toast, tile, badge, and raw updates from their own cloud service. This provides a mechanism to deliver new updates to your users in a power-efficient and dependable way.

How it works The following diagram shows the complete data flow for sending a push notification. It involves these steps: 1. Your app requests a push notification channel from the Universal Windows Platform. 2. Windows asks WNS to create a notification channel. This channel is returned to the calling device in the form of a Uniform Resource Identifier (URI). 3. The notification channel URI is returned by Windows to your app. 4. Your app sends the URI to your own cloud service. You then store the URI on your own cloud service so that you can access the URI when you send notifications. The URI is an interface between your own app and your own service; it's your responsibility to implement this interface with safe and secure web standards. 5. When your cloud service has an update to send, it notifies WNS using the channel URI. This is done by issuing an HTTP POST request, including the notification payload, over Secure Sockets Layer (SSL). This step requires authentication. 6. WNS receives the request and routes the notification to the appropriate device.

Registering your app and receiving the credentials for your cloud service Before you can send notifications using WNS, your app must be registered with the Store Dashboard. This will provide you with credentials for your app that your cloud service will use in authenticating with WNS. These credentials consist of a Package Security Identifier (SID) and a secret key. To perform this registration, go to the Windows Dev Center and select Dashboard. Each app has its own set of credentials for its cloud service. These credentials cannot be used to send notifications to any other app. For more details on how to register your app, please see How to authenticate with the Windows Notification Service (WNS).

Requesting a notification channel When an app that is capable of receiving push notifications runs, it must first request a notification channel through the CreatePushNotificationChannelForApplicationAsync. For a full discussion and example code, see How to request, create, and save a notification channel. This API returns a channel URI that is uniquely linked to the calling application and its tile, and through which all notification types can be sent. After the app has successfully created a channel URI, it sends it to its cloud service, together with any app-specific metadata that should be associated with this URI. Important notes

We do not guarantee that the notification channel URI for an app will always remain the same. We advise that the app requests a new channel every time it runs and updates its service when the URI changes. The developer should never modify the channel URI and should consider it as a black-box string. At this time, channel URIs expire after 30 days. If your Windows 10 app will periodically renew its channel in the background then you can download the Push and periodic notifications sample for Windows 8.1 and re-use its source code and/or the pattern it demonstrates. The interface between the cloud service and the client app is implemented by you, the developer. We recommend that the app go through an authentication process with its own service and transmit data over a secure protocol such as HTTPS. It is important that the cloud service always ensures that the channel URI uses the domain "notify.windows.com". The service should never push notifications to a channel on any other domain. If the callback for your app is ever compromised, a malicious attacker could submit a channel URI to spoof WNS. Without inspecting the domain, your cloud service could be potentially disclose information to this attacker unknowingly. If your cloud service attempts to deliver a notification to an expired channel, WNS will return response code 410. In response to that code, your service should no longer attempt to send notifications to that URI.

Authenticating your cloud service To send a notification, the cloud service must be authenticated through WNS. The first step in this process occurs when you register your app with the Windows Store Dashboard. During the registration process, your app is given a Package security identifier (SID) and a secret key. This information is used by your cloud service to authenticate with WNS. The WNS authentication scheme is implemented using the client credentials profile from the OAuth 2.0 protocol. The cloud service authenticates with WNS by providing its credentials (Package SID and secret key). In return, it receives an access token. This access token allows a cloud service to send a notification. The token is required with every notification request sent to the WNS. At a high level, the information chain is as follows: 1. The cloud service sends its credentials to WNS over HTTPS following the OAuth 2.0 protocol. This authenticates the service with WNS. 2. WNS returns an access token if the authentication was successful. This access token is used in all subsequent notification requests until it expires.

In the authentication with WNS, the cloud service submits an HTTP request over Secure Sockets Layer (SSL). The parameters are supplied in the "application/x-www-for-urlencoded" format. Supply your Package SID in the

"client_id" field and your secret key in the "client_secret" field. For syntax details, see the access token request reference. Note This is just an example, not cut-and-paste code that you can successfully use in your own code. POST /accesstoken.srf HTTP/1.1 Content-Type: application/x-www-form-urlencoded Host: https://login.live.com Content-Length: 211 grant_type=client_credentials&client_id=ms-app%3a%2f%2fS-1-15-2-2972962901-2322836549-3722629029-1345238579-3987825745-2155616079650196962&client_secret=Vex8L9WOFZuj95euaLrvSH7XyoDhLJc7&scope=notify.windows.com

The WNS authenticates the cloud service and, if successful, sends a response of "200 OK". The access token is returned in the parameters included in the body of the HTTP response, using the "application/json" media type. After your service has received the access token, you are ready to send notifications. The following example shows a successful authentication response, including the access token. For syntax details, see Push notification service request and response headers. HTTP/1.1 200 OK Cache-Control: no-store Content-Length: 422 Content-Type: application/json { "access_token":"EgAcAQMAAAAALYAAY/c+Huwi3Fv4Ck10UrKNmtxRO6Njk2MgA=", "token_type":"bearer" }

Important notes

The OAuth 2.0 protocol supported in this procedure follows draft version V16. The OAuth Request for Comments (RFC) uses the term "client" to refer to the cloud service. There might be changes to this procedure when the OAuth draft is finalized. The access token can be reused for multiple notification requests. This allows the cloud service to authenticate just once to send many notifications. However, when the access token expires, the cloud service must authenticate again to receive a new access token.

Sending a notification Using the channel URI, the cloud service can send a notification whenever it has an update for the user. The access token described above can be reused for multiple notification requests; the cloud server is not required to request a new access token for every notification. If the access token has expired, the notification request will return an error. We recommended that you do not try to re-send your notification more than once if the access token is rejected. If you encounter this error, you will need to request a new access token and resend the notification. For the exact error code, see Push notification response codes. 1. The cloud service makes an HTTP POST to the channel URI. This request must be made over SSL and contains the necessary headers and the notification payload. The authorization header must include the acquired access token for authorization. An example request is shown here. For syntax details, see Push notification response codes. For details on composing the notification payload, see Quickstart: Sending a push notification. The payload of a tile, toast, or badge push notification is supplied as XML content that adheres to their respective defined Adaptive tiles schema or Legacy tiles schema. The payload of a raw notification does not have a

specified structure. It is strictly app-defined. POST https://cloud.notify.windows.com/?token=AQE%bU%2fSjZOCvRjjpILow%3d%3d HTTP/1.1 Content-Type: text/xml X-WNS-Type: wns/tile Authorization: Bearer EgAcAQMAAAAALYAAY/c+Huwi3Fv4Ck10UrKNmtxRO6Njk2MgA= Host: cloud.notify.windows.com Content-Length: 24 ....

2. WNS responds to indicate that the notification has been received and will be delivered at the next available opportunity. However, WNS does not provide end-to-end confirmation that your notification has been received by the device or application. This diagram illustrates the data flow:

Important notes

WNS does not guarantee the reliability or latency of a notification. Notifications should never include confidential or sensitive data. To send a notification, the cloud service must first authenticate with WNS and receive an access token. An access token only allows a cloud service to send notifications to the single app for which the token was created. One access token cannot be used to send notifications across multiple apps. Therefore, if your cloud service supports multiple apps, it must provide the correct access token for the app when pushing a notification to each channel URI. When the device is offline, by default WNS will store up to five tile notifications (if queuing is enabled; otherwise, one tile notification) and one badge notification for each channel URI, and no raw notifications. This default caching behavior can be changed through the X-WNS-Cache-Policy header. Note that toast notifications are never stored when the device is offline. In scenarios where the notification content is personalized to the user, WNS recommends that the cloud service immediately send those updates when those are received. Examples of this scenario include social media feed updates, instant communication invitations, new message notifications, or alerts. As an alternative, you can have scenarios in which the same generic update is frequently delivered to a large subset of your users; for example, weather, stock, and news updates. WNS guidelines specify that the frequency of these updates should be at most one every 30 minutes. The end user or WNS may determine more frequent routine updates to be abusive.

Expiration of tile and badge notifications By default, tile and badge notifications expire three days after being downloaded. When a notification expires, the

content is removed from the tile or queue and is no longer shown to the user. It's a best practice to set an expiration (using a time that makes sense for your app) on all tile and badge notifications so that your tile's content doesn't persist longer than it is relevant. An explicit expiration time is essential for content with a defined lifespan. This also assures the removal of stale content if your cloud service stops sending notifications, or if the user disconnects from the network for an extended period. Your cloud service can set an expiration for each notification by setting the X-WNS-Expires HTTP header to specify the time (in seconds) that your notification will remain valid after it is sent. For more information, see Push notification service request and response headers. For example, during a stock market's active trading day, you can set the expiration for a stock price update to twice that of your sending interval (such as one hour after receipt if you are sending notifications every half-hour). As another example, a news app might determine that one day is an appropriate expiration time for a daily news tile update.

Push notifications and battery saver Battery saver extends battery life by limiting background activity on the device. Windows 10 lets the user set battery saver to turn on automatically when the battery drops below a specified threshold. When battery saver is on, the receipt of push notifications is disabled to save energy. But there are a couple exceptions to this. The following Windows 10 battery saver settings (found in the Settings app) allow your app to receive push notifications even when battery saver is on. Allow push notifications from any app while in battery saver: This setting lets all apps receive push notifications while battery saver is on. Note that this setting applies only to Windows 10 for desktop editions (Home, Pro, Enterprise, and Education). Always allowed: This setting lets specific apps run in the background while battery saver is on - including receiving push notifications. This list is maintained manually by the user. There is no way to check the state of these two settings, but you can check the state of battery saver. In Windows 10, use the EnergySaverStatus property to check battery saver state. Your app can also use the EnergySaverStatusChanged event to listen for changes to battery saver. If your app depends heavily on push notifications, we recommend notifying users that they may not receive notifications while battery saver is on and to make it easy for them to adjust battery saver settings. Using the battery saver settings URI scheme in Windows 10, ms-settings:batterysaver-settings , you can provide a convenient link to the Settings app. Tip When notifying the user about battery saver settings, we recommend providing a way to suppress the message in the future. For example, the dontAskMeAgainBox checkbox in the following example persists the user's preference in LocalSettings. Here's an example of how to check if battery saver is turned on in Windows 10. This example notifies the user and launches the Settings app to battery saver settings. The dontAskAgainSetting lets the user suppress the message if they don't want to be notified again.

using System; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Navigation; using Windows.System; using Windows.System.Power; ... ... async public void CheckForEnergySaving() { //Get reminder preference from LocalSettings bool dontAskAgain; var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings; object dontAskSetting = localSettings.Values["dontAskAgainSetting"]; if (dontAskSetting == null) { // Setting does not exist dontAskAgain = false; } else { // Retrieve setting value dontAskAgain = Convert.ToBoolean(dontAskSetting); } // Check if battery saver is on and that it's okay to raise dialog if ((PowerManager.EnergySaverStatus == EnergySaverStatus.On) && (dontAskAgain == false)) { // Check dialog results ContentDialogResult dialogResult = await saveEnergyDialog.ShowAsync(); if (dialogResult == ContentDialogResult.Primary) { // Launch battery saver settings (settings are available only when a battery is present) await Launcher.LaunchUriAsync(new Uri("ms-settings:batterysaver-settings")); } // Save reminder preference if (dontAskAgainBox.IsChecked == true) { // Don't raise dialog again localSettings.Values["dontAskAgainSetting"] = "true"; } } }

This is the XAML for the ContentDialog featured in this example. Battery saver is on and you may not receive push notifications. You can choose to allow this app to work normally while in battery saver, including receiving push notifications.

NOTE This article is for Windows 10 developers writing Universal Windows Platform (UWP) apps. If you’re developing for Windows 8.x or Windows Phone 8.x, see the archived documentation.

Related topics Send a local tile notification Quickstart: Sending a push notification How to update a badge through push notifications How to request, create, and save a notification channel How to intercept notifications for running applications How to authenticate with the Windows Push Notification Service (WNS) Push notification service request and response headers Guidelines and checklist for push notifications Raw notifications

Code generated by the push notification wizard 3/6/2017 • 7 min to read • Edit on GitHub

By using a wizard in Visual Studio, you can generate push notifications from a mobile service that was created with Azure Mobile Services. The Visual Studio wizard generates code to help you get started. This topic explains how the wizard modifies your project, what the generated code does, how to use this code, and what you can do next to get the most out of push notifications. See Windows Push Notification Services (WNS) overview.

How the wizard modifies your project The push notification wizard modifies your project in the following ways: Adds a reference to Mobile Services Managed Client (MobileServicesManagedClient.dll). Not applicable to JavaScript projects. Adds a file in a subfolder under services, and names the file push.register.cs, push.register.vb, push.register.cpp, or push.register.js. Creates a channels table on the database server for the mobile service. The table contains information that's required to send push notifications to app instances. Creates scripts for four functions: delete, insert, read and update. Creates a script with a custom API, notifyallusers.js, which sends a push notification to all clients. Adds a declaration to your App.xaml.cs, App.xaml.vb, or App.xaml.cpp file, or adds a declaration to a new file, service.js, for JavaScript projects. The declaration declares a MobileServiceClient object, which contains the information that's required to connect to the mobile service. You can access this MobileServiceClient object, which is named MyServiceNameClient, from any page in your app by using the name App.MyServiceNameClient. The services.js file contains the following code: var Client = new Microsoft.WindowsAzure.MobileServices.MobileServiceClient( "https://.azure-mobile.net/", "");

Registration for push notifications In push.register.*, the UploadChannel method registers the device to receive push notifications. The Store tracks installed instances of your app and provides the push notification channel. See PushNotificationChannelManager. The client code is similar for both the JavaScript backend and the .NET backend. By default, when you add push notifications for a JavaScript backend service, a sample call to notifyAllUsers custom API is inserted into the UploadChannel method.

using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Text; using System.Threading.Tasks; using Microsoft.WindowsAzure.MobileServices; using Newtonsoft.Json.Linq; namespace App2 { internal class mymobileservice1234Push { public async static void UploadChannel() { var channel = await Windows.Networking.PushNotifications.PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync(); try { await App.mymobileservice1234Client.GetPush().RegisterNativeAsync(channel.Uri); await App.mymobileservice1234Client.InvokeApiAsync("notifyAllUsers"); } catch (Exception exception) { HandleRegisterException(exception); } } private static void HandleRegisterException(Exception exception) { } } }

Imports Microsoft.WindowsAzure.MobileServices Imports Newtonsoft.Json.Linq Friend Class mymobileservice1234Push Public Shared Async Sub UploadChannel() Dim channel = Await Windows.Networking.PushNotifications.PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync() Try Await App.mymobileservice1234Client.GetPush().RegisterNativeAsync(channel.Uri) Await App.mymobileservice1234Client.GetPush().RegisterNativeAsync(channel.Uri, New String() {"tag1", "tag2"}) Await App.mymobileservice1234Client.InvokeApiAsync("notifyAllUsers") Catch exception As Exception HandleRegisterException(exception) End Try End Sub Private Shared Sub HandleRegisterException(exception As Exception) End Sub End Class

#include "pch.h" #include "services\mobile services\mymobileservice1234\mymobileservice1234Push.h" using namespace AzureMobileHelper; using namespace web; using namespace concurrency; using namespace Windows::Networking::PushNotifications; void mymobileservice1234Push::UploadChannel() { create_task(PushNotificationChannelManager::CreatePushNotificationChannelForApplicationAsync()). then([] (PushNotificationChannel^ newChannel) { return mymobileservice1234MobileService::GetClient().get_push().register_native(newChannel-&gt;Uri-&gt;Data()); }).then([]() { return mymobileservice1234MobileService::GetClient().invoke_api(L"notifyAllUsers"); }).then([](task&lt;json::value&gt; result) { try { result.wait(); } catch(...) { HandleExceptionsComingFromTheServer(); } }); } void mymobileservice1234Push::HandleExceptionsComingFromTheServer() { }

(function () { "use strict"; var app = WinJS.Application; var activation = Windows.ApplicationModel.Activation; app.addEventListener("activated", function (args) { if (args.detail.kind == activation.ActivationKind.launch) { Windows.Networking.PushNotifications.PushNotificationChannelManager.createPushNotificationChannelForApplicationAsync() .then(function (channel) { mymobileserviceclient1234Client.push.registerNative(channel.Uri, new Array("tag1", "tag2")) return mymobileservice1234Client.push.registerNative(channel.uri); }) .done(function (registration) { return mymobileservice1234Client.invokeApi("notifyAllUsers"); }, function (error) { // Error }); } }); })();

Push notification tags provide a way to restrict notifications to a subset of clients. You can use the for the registerNative method (or RegisterNativeAsync) method to either register for all push notifications without specifying tags, or you can register with tags by providing the second argument, an array of tags. If you register with one or more tags, you only receive notifications that match those tags.

Server-side scripts (JavaScript backend only) For mobile services that use the JavaScript backend, the server-side scripts run when delete, insert, read, or update operations occur. The scripts don't implement these operations, but they run when a call from the client to the Windows Mobile REST API triggers these events. The scripts then pass control onto the operations themselves by calling request.execute or request.respond to issue a response to the calling context. See Azure Mobile Services REST API Reference. A variety of functions are available in the server-side script. See Register table operations in Azure Mobile Services. For a reference to all available functions, see Mobile Services server script reference. The following custom API code in Notifyallusers.js is also created: exports.post = function(request, response) { response.send(statusCodes.OK,{ message : 'Hello World!' }) // The following call is for illustration purpose only // The call and function body should be moved to a script in your app // where you want to send a notification sendNotifications(request); }; // The following code should be moved to appropriate script in your app where notification is sent function sendNotifications(request) { var payload = '' + 'Sample Toast'; var push = request.service.push; push.wns.send(null, payload, 'wns/toast', { success: function (pushResponse) { console.log("Sent push:", pushResponse); } }); }

The sendNotifications function sends a single notification as a toast notification. You can also use other types of push notifications. Tip For information about how to get help while editing scripts, see Enabling IntelliSense for server-side JavaScript.

Push notification types Windows supports notifications that aren't push notifications. For general information about notifications, see Delivering scheduled, periodic, and push notifications. Toast notifications are easy to use, and you can review an example in the Insert.js code on the channel's table that's generated for you. If you plan to use tile or badge notifications, you must create an XML template for the tile and badge, and you must specify the encoding of packaged information in the template. See Working with tiles, badges, and toast notifications. Because Windows responds to push notifications, it can handle most of these notifications when the app isn't running. For example, a push notification could let a user know when a new mail message is available even when the local mail app isn't running. Windows handles a toast notification by displaying a message, such as the first line of a text message. Windows handles a tile or badge notification by updating an app's live tile to reflect the number of new mail messages. In this way, you can prompt users of your app to check it for new information. Your app can receive raw notifications when it's running, and you can use them to send data to your app. If your app isn't running, you can set up a background task to monitor push notifications. You should use push notifications according to the guidelines for Universal Windows Platform (UWP) apps,

because those notifications use up a user's resources and can be distracting if overused. See Guidelines and checklist for push notifications. If you're updating live tiles with push notifications, you should also follow the guidelines in Guidelines and checklist for tiles and badges.

Next steps Using the Windows Push Notification Services (WNS)

You can call Windows Push Notification Services (WNS) directly if Mobile Services doesn't provide enough flexibility, if you want to write your server code in C# or Visual Basic, or if you already have a cloud service and you want to send push notifications from it. By calling WNS directly, you can send push notifications from your own cloud service, such as a worker role that monitors data from a database or another web service. Your cloud service must authenticate with WNS to send push notifications to your apps. See How to authenticate with the Windows Push Notification Service (JavaScript) or (C#/C++/VB). You can also send push notifications by running a scheduled task in your mobile service. See Schedule recurring jobs in Mobile Services. Warning Once you've run the push notification wizard once, don't run the wizard a second time to add registration code for another mobile service. Running the wizard more than once per project generates code that results in overlapping calls to the CreatePushNotificationChannelForApplicationAsync method, which leads to a runtime exception. If you want to register for push notifications for more than one mobile service, run the wizard once and then rewrite the registration code to ensure that calls to CreatePushNotificationChannelForApplicationAsync do not run at the same time. For example, you can accomplish this by moving the wizard-generated code in push.register.* (including the call to CreatePushNotificationChannelForApplicationAsync) outside of the OnLaunched event, but the specifics of this will depend on your app's architecture.

Related topics Windows Push Notification Services (WNS) overview Raw notification overview Connecting to Windows Azure Mobile Services (JavaScript) Connecting to Windows Azure Mobile Services (C#/C++/VB) Quickstart: Adding push notifications for a mobile service (JavaScript)

3/6/2017 • 8 min to read • Edit on GitHub

Raw notification overview Raw notifications are short, general purpose push notifications. They are strictly instructional and do not include a UI component. As with other push notifications, the Windows Push Notification Services (WNS) feature delivers raw notifications from your cloud service to your app. You can use raw notifications for a variety of purposes, including to trigger your app to run a background task if the user has given the app permission to do so. By using WNS to communicate with your app, you can avoid the processing overhead of creating persistent socket connections, sending HTTP GET messages, and other service-toapp connections. IMPORTANT To understand raw notifications, it's best to be familiar with the concepts discussed in the Windows Push Notification Services (WNS) overview.

As with toast, tile, and badge push notifications, a raw notification is pushed from your app's cloud service over an assigned channel Uniform Resource Identifier (URI) to WNS. WNS, in turn, delivers the notification to the device and user account associated with that channel. Unlike other push notifications, raw notifications don't have a specified format. The content of the payload is entirely app-defined. As an illustration of an app that could benefit from raw notifications, let's look at a theoretical document collaboration app. Consider two users who are editing the same document at the same time. The cloud service, which hosts the shared document, could use raw notifications to notify each user when changes are made by the other user. The raw notifications would not necessarily contain the changes to the document, but instead would signal each user's copy of the app to contact the central location and sync the available changes. By using raw notifications, the app and the its cloud service can save the overhead of maintaining persistent connections the entire time the document is open.

How raw notifications work All raw notifications are push notifications. Therefore, the setup required to send and receive push notifications applies to raw notifications as well: You must have a valid WNS channel to send raw notifications. For more information about acquiring a push notification channel, see How to request, create, and save a notification channel. You must include the Internet capability in your app's manifest. In the Microsoft Visual Studio manifest editor, you will find this option under the Capabilities tab as Internet (Client). For more information, see Capabilities. The body of the notification is in an app-defined format. The client receives the data as a null-terminated string (HSTRING) that only needs to be understood by the app. If the client is offline, raw notifications will be cached by WNS only if the X-WNS-Cache-Policy header is included in the notification. However, only one raw notification will be cached and delivered once the device comes back online. There are only three possible paths for a raw notification to take on the client: they will be delivered to your

running app through a notification delivery event, sent to a background task, or dropped. Therefore, if the client is offline and WNS attempts to deliver a raw notification, the notification is dropped.

Creating a raw notification Sending a raw notification is similar to sending a tile, toast, or badge push notification, with these differences: The HTTP Content-Type header must be set to "application/octet-stream". The HTTP X-WNS-Type header must be set to "wns/raw". The notification body can contain any string payload smaller than 5 KB in size. Raw notifications are intended to be used as short messages that trigger your app to take an action, such as to directly contact the service to sync a larger amount of data or to make a local state modification based on the notification content. Note that WNS push notifications cannot be guaranteed to be delivered, so your app and cloud service must account for the possibility that the raw notification might not reach the client, such as when the client is offline. For more information on sending push notifications, see Quickstart: Sending a push notification.

Receiving a raw notification There are two avenues through which your app can be receive raw notifications: Through notification delivery events while your application is running. Through background tasks triggered by the raw notification if your app is enabled to run background tasks. An app can use both mechanisms to receive raw notifications. If an app implements both the notification delivery event handler and background tasks that are triggered by raw notifications, the notification delivery event will take priority when the app is running. If the app is running, the notification delivery event will take priority over the background task and the app will have the first opportunity to process the notification. The notification delivery event handler can specify, by setting the event's PushNotificationReceivedEventArgs.Cancel property to true, that the raw notification should not be passed to its background task once the handler exits. If the Cancel property is set to false or is not set (the default value is false), the raw notification will trigger the background task after the notification delivery event handler has done its work. Notification delivery events

Your app can use a notification delivery event (PushNotificationReceived) to receive raw notifications while the app is in use. When the cloud service sends a raw notification, the running app can receive it by handling the notification delivery event on the channel URI. If your app is not running and does not use background tasks, any raw notification sent to that app is dropped by WNS on receipt. To avoid wasting your cloud service's resources, you should consider implementing logic on the service to track whether the app is active. There are two sources of this information: an app can explicitly tell the service that it's ready to start receiving notifications, and WNS can tell the service when to stop. The app notifies the cloud service: The app can contact its service to let it know that the app is running in the foreground. The disadvantage of this approach is that the app can end up contacting your service very frequently. However, it has the advantage that the service will always know when the app is ready to receive incoming raw notifications. Another advantage is that when the app contacts its service, the service then knows to send raw notifications to the specific instance of that app rather than broadcast. The cloud service responds to WNS response messages : Your app service can use the X-WNSNotificationStatus and X-WNS-DeviceConnectionStatus information returned by WNS to determine when

to stop sending raw notifications to the app. When your service sends a notification to a channel as an HTTP POST, it can receive one of these messages in the response: X-WNS-NotificationStatus: dropped: This indicates that the notification was not received by the client. It's a safe assumption that the dropped response is caused by your app no longer being in the foreground on the user's device. X-WNS-DeviceConnectionStatus: disconnected or X-WNS-DeviceConnectionStatus: tempconnected: This indicates that the Windows client no longer has a connection to WNS. Note that to receive this message from WNS, you have to ask for it by setting the X-WNS-RequestForStatus header in the notification's HTTP POST. Your app's cloud service can use the information in these status messages to cease communication attempts through raw notifications. The service can resume sending raw notifications once it is contacted by the app, when the app switches back into the foreground. Note that you should not rely on X-WNS-NotificationStatus to determine whether the notification was successfully delivered to the client. For more information, see Push notification service request and response headers Background tasks triggered by raw notifications IMPORTANT Before using raw notification background tasks, an app must be granted background access via BackgroundExecutionManager.RequestAccessAsync.

Your background task must be registered with a PushNotificationTrigger. If it is not registered, the task will not run when a raw notification is received. A background task that is triggered by a raw notification enables your app's cloud service to contact your app, even when the app is not running (though it might trigger it to run). This happens without the app having to maintain a continuous connection. Raw notifications are the only notification type that can trigger background tasks. However, while toast, tile, and badge push notifications cannot trigger background tasks, background tasks triggered by raw notifications can update tiles and invoke toast notifications through local API calls. As an illustration of how background tasks that are triggered by raw notifications work, let's consider an app used to read e-books. First, a user purchases a book online, possibly on another device. In response, the app's cloud service can send a raw notification to each of the user's devices, with a payload that states that the book was purchased and the app should download it. The app then directly contacts the app's cloud service to begin a background download of the new book so that later, when the user launches the app, the book is already there and ready for reading. To use a raw notification to trigger a background task, your app must: 1. Request permission to run tasks in the background (which the user can revoke at any time) by using BackgroundExecutionManager.RequestAccessAsync. 2. Implement the background task. For more information, see Supporting your app with background tasks Your background task is then invoked in response to the PushNotificationTrigger, each time a raw notification is received for your app. Your background task interprets the raw notification's app-specific payload and acts on it. For each app, only one background task can run at a time. If a background task is triggered for an app for which a background task is already running, the first background task must complete before the new one is run.

Other resources

You can learn more by downloading the Raw notifications sample for Windows 8.1, and the Push and periodic notifications sample for Windows 8.1, and re-using their source code in your Windows 10 app.

Related topics Guidelines for raw notifications Quickstart: Creating and registering a raw notification background task Quickstart: Intercepting push notifications for running apps RawNotification BackgroundExecutionManager.RequestAccessAsync

Toggle switches 3/6/2017 • 3 min to read • Edit on GitHub

The toggle switch represents a physical switch that allows users to turn things on or off. Use ToggleSwitch controls to present users with exactly two mutually exclusive options (like on/off), where choosing an option results in an immediate action. Important APIs ToggleSwitch class IsOn property Toggled event

Is this the right control? Use a toggle switch for binary operations that take effect right after the user flips the toggle switch. For example, use a toggle switch to turn services or hardware components on or off, such as WiFi:

If a physical switch would work for the action, a toggle switch is probably the best control to use. After the user toggles the switch on or off, we recommend that the corresponding action is immediately performed. Choosing between toggle switch and check box

For some actions, either a toggle switch or a check box might work. To decide which control would work better, follow these tips: Use a toggle switch for binary settings when changes become effective immediately after the user changes them.

In the above example, it's clear with the toggle switch that the wireless is set to "On." But with the checkbox, the user needs to think about whether the wireless is on now or whether they need to check the box to turn wireless on. Use a checkbox when the user has to perform extra steps for changes to be effective. For example, if the

user must click a "submit" or "next" button to apply changes, use a check box.

Use check boxes or a list box when the user can select multiple items:

Examples Toggle switches in the general settings of the News app.

Toggle switches in the start menu settings in Windows.

Create a toggle switch Here's how to create a simple toggle switch. This XAML creates the WiFi toggle switch shown previously.

Here's how to create the same toggle switch in code. ToggleSwitch wiFiToggle = new ToggleSwitch(); wiFiToggle.Header = "WiFi"; // Add the toggle switch to a parent container in the visual tree. stackPanel1.Children.Add(wiFiToggle);

IsOn

The switch can be either on or off. Use the IsOn property to determine the state of the switch. When the switch is used to control the state of another binary property, you can use a binding as shown here.

Toggled

In other cases, you can handle the Toggled event to respond to changes in the state. This example shows how to add a Toggled event handler in XAML and in code. The Toggled event is handled to turn a progress ring on or off, and change its visibility.

Here's how to create the same toggle switch in code. // Create a new toggle switch and add a Toggled event handler. ToggleSwitch toggleSwitch1 = new ToggleSwitch(); toggleSwitch1.Toggled += ToggleSwitch_Toggled; // Add the toggle switch to a parent container in the visual tree. stackPanel1.Children.Add(toggleSwitch1);

Here's the handler for the Toggled event. private void ToggleSwitch_Toggled(object sender, RoutedEventArgs e) { ToggleSwitch toggleSwitch = sender as ToggleSwitch; if (toggleSwitch != null) { if (toggleSwitch.IsOn == true) { progress1.IsActive = true; progress1.Visibility = Visibility.Visible; } else { progress1.IsActive = false; progress1.Visibility = Visibility.Collapsed; } } }

On/Off labels

By default, the toggle switch includes literal On and Off labels, which are localized automatically. You can replace these labels by setting the OnContent, and OffContent properties. This example replaces the On/Off labels with Show/Hide labels.

You can also use more complex content by setting the OnContentTemplate and OffContentTemplate properties.

Recommendations Replace the On and Off labels when there are more specific labels for the setting. If there are short (3-4 characters) labels that represent binary opposites that are more appropriate for a particular setting, use those. For example, you could use "Show/Hide" if the setting is "Show images." Using more specific labels can help when localizing the UI.

Avoid replacing the On and Off labels unless you must; stick with the default labels unless the situation calls for custom ones. Labels should be no more than 4 characters long.

Related articles ToggleSwitch class Radio buttons Toggle switches Check boxes

Tooltips 3/6/2017 • 2 min to read • Edit on GitHub

A tooltip is a short description that is linked to another control or object. Tooltips help users understand unfamiliar objects that aren't described directly in the UI. They display automatically when the user moves focus to, presses and holds, or hovers the mouse pointer over a control. The tooltip disappears after a few seconds, or when the user moves the finger, pointer or keyboard/gamepad focus.

Important APIs ToolTip class ToolTipService class

Is this the right control? Use a tooltip to reveal more info about a control before asking the user to perform an action. Tooltips should be used sparingly, and only when they are adding distinct value for the user who is trying to complete a task. One rule of thumb is that if the information is available elsewhere in the same experience, you do not need a tooltip. A valuable tooltip will clarify an unclear action. When should you use a tooltip? To decide, consider these questions: Should info become visible based on pointer hover? If not, use another control. Display tips only as the result of user interaction, never display them on their own. Does a control have a text label? If not, use a tooltip to provide the label. It is a good UX design practice to label most controls inline and for these you don't need tooltips. Toolbar controls and command buttons showing only icons need tooltips. Does an object benefit from a description or further info? If so, use a tooltip. But the text must be supplemental — that is, not essential to the primary tasks. If it is essential, put it directly in the UI so that users don't have to discover or hunt for it. Is the supplemental info an error, warning, or status? If so, use another UI element, such as a flyout. Do users need to interact with the tip? If so, use another control. Users can't interact with tips because moving the mouse makes them disappear. Do users need to print the supplemental info? If so, use another control. Will users find the tips annoying or distracting? If so, consider using another solution — including doing nothing at all. If you do use tips where they might be distracting, allow users to turn them off.

Example A tooltip in the Bing Maps app.

Recommendations Use tooltips sparingly (or not at all). Tooltips are an interruption. A tooltip can be as distracting as a pop-up, so don't use them unless they add significant value. Keep the tooltip text concise. Tooltips are perfect for short sentences and sentence fragments. Large blocks of text can be overwhelming and the tooltip may time out before the user has finished reading. Create helpful, supplemental tooltip text. Tooltip text must be informative. Don't make it obvious or just repeat what is already on the screen. Because tooltip text isn't always visible, it should be supplemental info that users don't have to read. Communicate important info using self-explanatory control labels or in-place supplemental text. Use images when appropriate. Sometimes it's better to use an image in a tooltip. For example, when the user hovers over a hyperlink, you can use a tooltip to show a preview of the linked page. Don't use a tooltip to display text already visible in the UI. For example, don't put a tooltip on a button that shows the same text of the button. Don't put interactive controls inside the tooltip. Don't put images that look like they are interactive inside the tooltip. Related topics ToolTip class

Web view 3/6/2017 • 12 min to read • Edit on GitHub

A web view control embeds a view into your app that renders web content using the Microsoft Edge rendering engine. Hyperlinks can also appear and function in a web view control. Important APIs WebView class

Is this the right control? Use a web view control to display richly formatted HTML content from a remote web server, dynamically generated code, or content files in your app package. Rich content can also contain script code and communicate between the script and your app's code.

Create a web view Modify the appearance of a web view WebView is not a Control subclass, so it doesn't have a control template. However, you can set various properties to control some visual aspects of the web view. To constrain the display area, set the Width and Height properties. To translate, scale, skew, and rotate a web view, use the RenderTransform property. To control the opacity of the web view, set the Opacity property. To specify a color to use as the web page background when the HTML content does not specify a color, set the DefaultBackgroundColor property. Get the web page title You can get the title of the HTML document currently displayed in the web view by using the DocumentTitle property. Input events and tab order Although WebView is not a Control subclass, it will receive keyboard input focus and participate in the tab sequence. It provides a Focus method, and GotFocus and LostFocus events, but it has no tab-related properties. Its position in the tab sequence is the same as its position in the XAML document order. The tab sequence includes all elements in the web view content that can receive input focus. As indicated in the Events table on the WebView class page, web view doesn’t support most of the user input events inherited from UIElement, such as KeyDown, KeyUp, and PointerPressed. Instead, you can use InvokeScriptAsync with the JavaScript eval function to use the HTML event handlers, and to use window.external.notify from the HTML event handler to notify the application using WebView.ScriptNotify. Navigating to content

Web view provides several APIs for basic navigation: GoBack, GoForward, Stop, Refresh, CanGoBack, and CanGoForward. You can use these to add typical web browsing capabilities to your app. To set the initial content of the web view, set the Source property in XAML. The XAML parser automatically converts the string to a Uri.



The Source property can be set in code, but rather than doing so, you typically use one of the Navigate methods to load content in code. To load web content, use the Navigate method with a Uri that uses the http or https scheme. webView1.Navigate("http://www.contoso.com");

To navigate to a URI with a POST request and HTTP headers, use the NavigateWithHttpRequestMessage method. This method supports only HttpMethod.Post and HttpMethod.Get for the HttpRequestMessage.Method property value. To load uncompressed and unencrypted content from your app’s [LocalFolder]() or [TemporaryFolder]() data stores, use the Navigate method with a Uri that uses the [ms-appdata scheme](). The web view support for this scheme requires you to place your content in a subfolder under the local or temporary folder. This enables navigation to URIs such as ms-appdata:///local/folder/file.html and ms-appdata:///temp/folder/file.html . (To load compressed or encrypted files, see NavigateToLocalStreamUri.) Each of these first-level subfolders is isolated from the content in other first-level subfolders. For example, you can navigate to ms-appdata:///temp/folder1/file.html, but you can’t have a link in this file to msappdata:///temp/folder2/file.html. However, you can still link to HTML content in the app package using the msappx-web scheme, and to web content using the http and https URI schemes. webView1.Navigate("ms-appdata:///local/intro/welcome.html");

To load content from the your app package, use the Navigate method with a Uri that uses the ms-appx-web scheme. webView1.Navigate("ms-appx-web:///help/about.html");

You can load local content through a custom resolver using the NavigateToLocalStreamUri method. This enables advanced scenarios such as downloading and caching web-based content for offline use, or extracting content from a compressed file. Responding to navigation events

The web view control provides several events that you can use to respond to navigation and content loading states. The events occur in the following order for the root web view content: NavigationStarting, ContentLoading, DOMContentLoaded, NavigationCompleted NavigationStarting - Occurs before the web view navigates to new content. You can cancel navigation in a handler for this event by setting the WebViewNavigationStartingEventArgs.Cancel property to true.

webView1.NavigationStarting += webView1_NavigationStarting; private void webView1_NavigationStarting(object sender, WebViewNavigationStartingEventArgs args) { // Cancel navigation if URL is not allowed. (Implemetation of IsAllowedUri not shown.) if (!IsAllowedUri(args.Uri)) args.Cancel = true; }

ContentLoading - Occurs when the web view has started loading new content. webView1.ContentLoading += webView1_ContentLoading; private void webView1_ContentLoading(WebView sender, WebViewContentLoadingEventArgs args) { // Show status. if (args.Uri != null) { statusTextBlock.Text = "Loading content for " + args.Uri.ToString(); } }

DOMContentLoaded - Occurs when the web view has finished parsing the current HTML content. webView1.DOMContentLoaded += webView1_DOMContentLoaded; private void webView1_DOMContentLoaded(WebView sender, WebViewDOMContentLoadedEventArgs args) { // Show status. if (args.Uri != null) { statusTextBlock.Text = "Content for " + args.Uri.ToString() + " has finished loading"; } }

NavigationCompleted - Occurs when the web view has finished loading the current content or if navigation has failed. To determine whether navigation has failed, check the IsSuccess and WebErrorStatus properties of the WebViewNavigationCompletedEventArgs class. webView1.NavigationCompleted += webView1_NavigationCompleted; private void webView1_NavigationCompleted(WebView sender, WebViewNavigationCompletedEventArgs args) { if (args.IsSuccess == true) { statusTextBlock.Text = "Navigation to " + args.Uri.ToString() + " completed successfully."; } else { statusTextBlock.Text = "Navigation to: " + args.Uri.ToString() + " failed with error " + args.WebErrorStatus.ToString(); } }

Similar events occur in the same order for each iframe in the web view content: FrameNavigationStarting - Occurs before a frame in the web view navigates to new content. FrameContentLoading - Occurs when a frame in the web view has started loading new content. FrameDOMContentLoaded - Occurs when a frame in the web view has finished parsing its current HTML

content. FrameNavigationCompleted - Occurs when a frame in the web view has finished loading its content. Responding to potential problems

You can respond to potential problems with the content such as long running scripts, content that web view can't load, and warnings of unsafe content. Your app might appear unresponsive while scripts are running. The LongRunningScriptDetected event occurs periodically while the web view executes JavaScript and provides an opportunity to interrupt the script. To determine how long the script has been running, check the ExecutionTime property of the WebViewLongRunningScriptDetectedEventArgs. To halt the script, set the event args StopPageScriptExecution property to true. The halted script will not execute again unless it is reloaded during a subsequent web view navigation. The web view control cannot host arbitrary file types. When an attempt is made to load content that the web view can't host, the UnviewableContentIdentified event occurs. You can handle this event and notify the user, or use the Launcher class to redirect the file to an external browser or another app. Similarly, the UnsupportedUriSchemeIdentified event occurs when a URI scheme that's not supported is invoked in the web content, such as fbconnect:// or mailto://. You can handle this event to provide custom behavior instead of allowing the default system launcher to launch the URI. The UnsafeContentWarningDisplayingevent occurs when the web view shows a warning page for content that was reported as unsafe by the SmartScreen Filter. If the user chooses to continue the navigation, subsequent navigation to the page will not display the warning nor fire the event. Handling special cases for web view content

You can use the ContainsFullScreenElement property and ContainsFullScreenElementChanged event to detect, respond to, and enable full-screen experiences in web content, such as full-screen video playback. For example, you may use the ContainsFullScreenElementChanged event to resize the web view to occupy the entirety of your app view, or, as the following example illustrates, put a windowed app in full screen mode when a full screen web experience is desired. // Assume webView is defined in XAML webView.ContainsFullScreenElementChanged += webView_ContainsFullScreenElementChanged; private void webView_ContainsFullScreenElementChanged(WebView sender, object args) { var applicationView = ApplicationView.GetForCurrentView(); if (sender.ContainsFullScreenElement) { applicationView.TryEnterFullScreenMode(); } else if (applicationView.IsFullScreenMode) { applicationView.ExitFullScreenMode(); } }

You can use the NewWindowRequested event to handle cases where hosted web content requests a new window to be displayed, such as a popup window. You can use another WebView control to display the contents of the requested window. Use PermissionRequested event to enable web features that require special capabilities. These currently include geolocation, IndexedDB storage, and user audio and video (for example, from a microphone or webcam). If your app accesses user location or user media, you still are required to declare this capability in the app manifest. For example, an app that uses geolocation needs the following capability declarations at minimum in

Package.appxmanifest:

In addition to the app handling the PermissionRequested event, the user will have to approve standard system dialogs for apps requesting location or media capabilities in order for these features to be enabled. Here is an example of how an app would enable geolocation in a map from Bing: // Assume webView is defined in XAML webView.PermissionRequested += webView_PermissionRequested; private void webView_PermissionRequested(WebView sender, WebViewPermissionRequestedEventArgs args) { if (args.PermissionRequest.PermissionType == WebViewPermissionType.Geolocation && args.PermissionRequest.Uri.Host == "www.bing.com") { args.PermissionRequest.Allow(); } }

If your app requires user input or other asynchronous operations to respond to a permission request, use the Defer method of WebViewPermissionRequest to create a WebViewDeferredPermissionRequest that can be acted upon at a later time. See WebViewPermissionRequest.Defer. If users must securely log out of a website hosted in a web view, or in other cases when security is important, call the static method ClearTemporaryWebDataAsync to clear out all locally cached content from a web view session. This prevents malicious users from accessing sensitive data. Interacting with web view content

You can interact with the content of the web view by using the InvokeScriptAsync method to invoke or inject script into the web view content, and the ScriptNotify event to get information back from the web view content. To invoke JavaScript inside the web view content, use the InvokeScriptAsync method. The invoked script can return only string values. For example, if the content of a web view named parameters, you can invoke it like this.

webView1

contains a function named

setDate

that takes 3

string[] args = {"January", "1", "2000"}; string returnValue = await webView1.InvokeScriptAsync("setDate", args);

You can use InvokeScriptAsync with the JavaScript eval function to inject content into the web page. Here, the text of a XAML text box ( nameTextBox.Text ) is written to a div in an HTML page hosted in

webView1

.

private async void Button_Click(object sender, RoutedEventArgs e) { string functionString = String.Format("document.getElementById('nameDiv').innerText = 'Hello, {0}';", nameTextBox.Text); await webView1.InvokeScriptAsync("eval", new string[] { functionString }); }

Scripts in the web view content can use window.external.notify with a string parameter to send information back to your app. To receive these messages, handle the ScriptNotify event.

To enable an external web page to fire the ScriptNotify event when calling window.external.notify, you must include the page's URI in the ApplicationContentUriRules section of the app manifest. (You can do this in Microsoft Visual Studio on the Content URIs tab of the Package.appxmanifest designer.) The URIs in this list must use HTTPS, and may contain subdomain wildcards (for example, https://*.microsoft.com ) but they cannot contain domain wildcards (for example, https://*.com and https://*.* ). The manifest requirement does not apply to content that originates from the app package, uses an ms-local-stream:// URI, or is loaded using NavigateToString. Accessing the Windows Runtime in a web view

You can use the AddWebAllowedObject method to inject an instance of a native class from a Windows Runtime component into the JavaScript context of the web view. This allows full access to the native methods, properties, and events of that object in the JavaScript content of that web view. The class must be decorated with the AllowForWeb attribute. For example, this code injects an instance of view.

MyClass

imported from a Windows Runtime component into a web

private void webView_NavigationStarting(WebView sender, WebViewNavigationStartingEventArgs args) { if (args.Uri.Host == "www.contoso.com") { webView.AddWebAllowedObject("nativeObject", new MyClass()); } }

For more info, see WebView.AddWebAllowedObject. In addition, trusted JavaScript content in a web view can be allowed to directly access Windows Runtime APIs. This provides powerful native capabilities for web apps hosted in a web view. To enable this feature, the URI for trusted content must be whitelisted in the ApplicationContentUriRules of the app in Package.appxmanifest, with WindowsRuntimeAccess specifically set to "all". This example shows a section of the app manifest. Here, a local URI is given access to the Windows Runtime. Devices -> Wheel page, including default tools, vibration (or haptic feedback), and writing (or dominant) hand. When customizing the Surface Dial user experience, you should always ensure that a particular function or behavior is available and enabled by the user.

Custom tools Here we discuss both UX and developer guidance for customizing the tools exposed on the Surface Dial menu. UX guidance

Ensure your tools correspond to the current context When you make it clear and intuitive what a tool does and how the Surface Dial interaction works, you help users learn quickly and stay focused on their task. Minimize the number of app tools as much as possible The Surface Dial menu has room for seven items. If there are eight or more items, the user needs to turn the Dial to see which tools are available in an overflow flyout, making the menu difficult to navigate and tools difficult to discover and select. We recommend providing a single custom tool for your app or app context. Doing so enables you to set that tool based on what the user is doing without requiring them to activate the Surface Dial menu and select a tool. Dynamically update the collection of tools Because Surface Dial menu items do not support a disabled state, you should dynamically add and remove tools

(including built-in, default tools) based on user context (current view or focused window). If a tool is not relevant to the current activity or it’s redundant, remove it. IMPORTANT When you add an item to the menu, ensure the item does not already exist.

Don’t remove the built-in system volume setting tool Volume control is typically always required by user. They might be listening to music while using your app, so volume and next track tools should always be accessible from the Surface Dial menu. (The next track tool is automatically added to the menu when media is playing.) Be consistent with menu organization This helps users with discovering and learning what tools are available when using your app, and helps improve their efficiency when switching tools. Provide high-quality icons consistent with the built-in icons Icons can convey professionalism and excellence, and inspire trust in users. Provide a high-quality 64 x 64 pixel PNG image (44 x 44 is the smallest supported) Ensure the background is transparent The icon should fill most of the image A white icon should have a black outline to be visible in high contrast mode

Icon with alpha background

Icon displayed on wheel menu with default theme

Icon displayed on wheel menu with High Contrast White theme

Use concise and descriptive names The tool name is displayed in the tool menu along with the tool icon and is also used by screen readers. Names should be short to fit inside the central circle of the wheel menu Names should clearly identify the primary action (a complementary action can be implied): Scroll indicates the effect of both rotation directions Undo specifies a primary action, but redo (the complementary action) can be inferred and easily discovered by the user Developer guidance

You can customize the Surface Dial experience to complement the functionality in your apps through a comprehensive set of Windows Runtime APIs. As previously mentioned, the default Surface Dial menu is pre-populated with a set of built-in tools covering a broad range of basic system features (system volume, system brightness, scroll, zoom, undo, and media control when the system detects ongoing audio or video playback). However, these default tools might not provide the functionality required by your app. In the following sections, we describe how to add a custom tool to the Surface Dial menu and specify which built-in tools are exposed.

Add a custom tool In this example, we add a basic custom tool that passes the input data from both the rotation and click events to some XAML UI controls. 1. First, we declare our UI (just a slider and toggle button) in XAML.

The sample app UI

2. Then, in code-behind, we add a custom tool to the Surface Dial menu and declare the RadialController input handlers.

We get a reference to the RadialController object for the Surface Dial (myController) by calling CreateForCurrentView. We then create an instance of a RadialControllerMenuItem (myItem) by calling RadialControllerMenuItem.CreateFromIcon. Next, we append that item to the collection of menu items. We declare the input event handlers (ButtonClicked and RotationChanged) for the RadialController object. Finally, we define the event handlers. public sealed partial class MainPage : Page { RadialController myController; public MainPage() { this.InitializeComponent(); // Create a reference to the RadialController. myController = RadialController.CreateForCurrentView(); // Create an icon for the custom tool. RandomAccessStreamReference icon = RandomAccessStreamReference.CreateFromUri( new Uri("ms-appx:///Assets/StoreLogo.png")); // Create a menu item for the custom tool. RadialControllerMenuItem myItem = RadialControllerMenuItem.CreateFromIcon("Sample", icon); // Add the custom tool to the RadialController menu. myController.Menu.Items.Add(myItem); // Declare input handlers for the RadialController. myController.ButtonClicked += MyController_ButtonClicked; myController.RotationChanged += MyController_RotationChanged; } // Handler for rotation input from the RadialController. private void MyController_RotationChanged(RadialController sender, RadialControllerRotationChangedEventArgs args) { if (RotationSlider.Value + args.RotationDeltaInDegrees > 100) { RotationSlider.Value = 100; return; } else if (RotationSlider.Value + args.RotationDeltaInDegrees < 0) { RotationSlider.Value = 0; return; } RotationSlider.Value += args.RotationDeltaInDegrees; } // Handler for click input from the RadialController. private void MyController_ButtonClicked(RadialController sender, RadialControllerButtonClickedEventArgs args) { ButtonToggle.IsOn = !ButtonToggle.IsOn; } }

When we run the app, we use the Surface Dial to interact with it. First, we press and hold to open the menu and select our custom tool. Once the custom tool is activated, the slider control can be adjusted by rotating the Dial and the switch can be toggled by clicking the Dial.

The sample app UI activated using the Surface Dial custom tool Specify the built-in tools You can use the RadialControllerConfiguration class to customize the collection of built-in menu items for your app. For example, if your app doesn’t have any scrolling or zooming regions and doesn’t require undo/redo functionality, these tools can be removed from the menu. This opens space on the menu to add custom tools for your app. IMPORTANT The Surface Dial menu must have at least one menu item. If all default tools are removed before you add one of your custom tools, the default tools are restored and your tool is appended to the default collection.

Per the design guidelines, we do not recommend removing the media control tools (volume and previous/next track) as users often have background music playing while they perform other tasks. Here, we show how to configure the Surface Dial menu to include only media controls for volume and next/previous track.

public MainPage() { ... //Remove a subset of the default system tools RadialControllerConfiguration myConfiguration = RadialControllerConfiguration.GetForCurrentView(); myConfiguration.SetDefaultMenuItems(new[] { RadialControllerSystemMenuItemKind.Volume, RadialControllerSystemMenuItemKind.NextPreviousTrack }); }

Custom interactions As mentioned, the Surface Dial supports three gestures (press and hold, rotate, click) with corresponding default interactions. Ensure any custom interactions based on these gestures make sense for the selected action or tool. NOTE The interaction experience is dependent on the state of the Surface Dial menu. If the menu is active, it processes the input; otherwise, your app does.

Press and hold

This gesture activates and shows the Surface Dial menu, there is no app functionality associated with this gesture. By default, the menu is displayed at the center of the user’s screen. However, the user can grab it and move it anywhere they choose. NOTE When the Surface Dial is placed on the screen of the Surface Studio, the menu is centered at the on-screen location of the Surface Dial.

Rotate

The Surface Dial is primarily designed to support rotation for interactions that involve smooth, incremental adjustments to analog values or controls. The device can be rotated both clockwise and counter-clockwise, and can also provide haptic feedback to indicate discrete distances. NOTE Haptic feedback can be disabled by the user in the Windows Settings -> Devices -> Wheel page.

UX guidance

Tools with continuous or high rotational sensitivity should disable haptic feedback Haptic feedback matches the rotational sensitivity of the active tool. We recommend disabling haptic feedback for tools with continuous or high rotational sensitivity as the user experience can get uncomfortable. Dominant hand should not affect rotation-based interactions The Surface Dial cannot detect which hand is being used, but the user can set the writing (or dominant hand) in

Windows Settings -> Device -> Pen & Windows Ink. Locale should be considered for all rotation interactions Maximize customer satisfaction by accomodating and adapting your interactions to locale and right-to-left layouts. The built-in tools and commands on the Dial menu follow these guidelines for rotation-based interactions:

Left Up Out

Right Down In

CONCEPTUAL DIRECTION

MAPPING TO SURFACE DIAL

CLOCKWISE ROTATION

COUNTER-CLOCKWISE ROTATION

Horizontal

Left and right mapping based on the top of the Surface Dial

Right

Left

Vertical

Up and down mapping based on the left side of the Surface Dial

Down

Up

Z-axis

In (or nearer) mapped to up/right Out (or further) mapped to down/left

In

Out

Developer guidance

As the user rotates the device, RadialController.RotationChanged events are fired based on a delta (RadialControllerRotationChangedEventArgs.RotationDeltaInDegrees) relative to the direction of rotation. The sensitivity (or resolution) of the data can be set with the RadialController.RotationResolutionInDegrees property. NOTE By default, a rotational input event is delivered to a RadialController object only when the device is rotated a minimum of 10 degrees. Each input event causes the device to vibrate.

In general, we recommend disabling haptic feedback when the rotation resolution is set to less than 5 degrees. This provides a smoother experience for continuous interactions. You can enable and disable haptic feedback for custom tools by setting the RadialController.UseAutomaticHapticFeedback property. NOTE You cannot override the haptic behavior for system tools such as the volume control. For these tools, haptic feedback can be disabled only by the user from the Wheel settings page.

Here’s an example of how to customize the resolution of the rotation data and enable or disable haptic feedback. private void MyController_ButtonClicked(RadialController sender, RadialControllerButtonClickedEventArgs args) { ButtonToggle.IsOn = !ButtonToggle.IsOn; if(ButtonToggle.IsOn) { //high resolution mode RotationSlider.LargeChange = 1; myController.UseAutomaticHapticFeedback = false; myController.RotationResolutionInDegrees = 1; } else { //low resolution mode RotationSlider.LargeChange = 10; myController.UseAutomaticHapticFeedback = true; myController.RotationResolutionInDegrees = 10; } }

Click

Clicking the Surface Dial is similar to clicking the left mouse button (the rotation state of the device has no effect on this action). UX guidance

Do not map an action or command to this gesture if the user cannot easily recover from the result Any action taken by your app based on the user clicking the Surface Dial must be reversible. Always enable the user to easily traverse the app back stack and restore a previous app state. Binary operations such as mute/unmute or show/hide provide good user experiences with the click gesture. Modal tools should not be enabled or disabled by clicking the Surface Dial Some app/tool modes can conflict with, or disable, interactions that rely on rotation. Tools such as the ruler in the Windows Ink toolbar, should be toggled on or off through other UI affordances (the Ink Toolbar provides a built-in ToggleButton control). For modal tools, map the active Surface Dial menu item to the target tool or to the previously selected menu item. Developer guidance

When the Surface Dial is clicked, a RadialController.ButtonClicked event is fired. The RadialControllerButtonClickedEventArgs include a Contact property that contains the location and bounding area of the Surface Dial contact on the Surface Studio screen. If the Surface Dial is not in contact with the screen, this property is null. On-screen

As described earlier, the Surface Dial can be used in conjunction with the Surface Studio to display the Surface Dial menu in a special on-screen mode. When in this mode, you can integrate and customize your Dial interaction experiences with your apps even further. Examples of unique experiences only possible with the Surface Dial and Surface Studio include: Displaying contextual tools (such as a color palette) based on the position of the Surface Dial, which makes them easier to find and use Setting the active tool based on the UI the Surface Dial is placed on Magnifying a screen area based on location of the Surface Dial

Unique game interactions based on screen location UX guidance

Apps should respond when the Surface Dial is detected on-screen Visual feedback helps indicate to users that your app has detected the device on the screen of the Surface Studio. Adjust Surface Dial-related UI based on device location The device (and the user's body) can occlude critical UI depending on where the user places it. Adjust Surface Dial-related UI based on user interaction In addition to hardware occlusion, a user’s hand and arm can occlude part of the screen when using the device. The occluded area depends on which hand is being used with the device. As the device is designed to be used primarily with the non-dominant hand, Surface Dial-related UI should adjust for the opposite hand specified by the user (Windows Settings > Devices > Pen & Windows Ink > Choose which hand you write with setting). Interactions should respond to Surface Dial position rather than movement The foot of the device is designed to stick to the screen rather than slide, as it is not a precision pointing device. Therefore, we expect it to be more common for users to lift and place the Surface Dial rather than drag it across the screen. Use screen position to determine user intent Setting the active tool based on UI context, such as proximity to a control, canvas, or window, can improve the user experience by reducing the steps required to perform a task. Developer guidance

When the Surface Dial is placed onto the digitizer surface of the Surface Studio, a RadialController.ScreenContactStarted event is fired and the contact info (RadialControllerScreenContactStartedEventArgs.Contact) is provided to your app. Similarly, if the Surface Dial is clicked when in contact with the digitizer surface of the Surface Studio, a RadialController.ButtonClicked event is fired and the contact info (RadialControllerButtonClickedEventArgs.Contact) is provided to your app. The contact info (RadialControllerScreenContact) includes the X/Y coordinate of the center of the Surface Dial in the coordinate space of the app (RadialControllerScreenContact.Position), as well as the bounding rectangle (RadialControllerScreenContact.Bounds) in Device Independent Pixels (DIPs). This info is very useful for providing context to the active tool and providing device-related visual feedback to the user. In the following example, we’ve created a basic app with four different sections, each of which includes one slider and one toggle. We then use the onscreen position of the Surface Dial to dictate which set of sliders and toggles are controlled by the Surface Dial. 1. First, we declare our UI (four sections, each with a slider and toggle button) in XAML.

The sample app UI

2. Here's the code-behind with handlers defined for Surface Dial screen position. Slider ActiveSlider; ToggleSwitch ActiveSwitch; Grid ActiveGrid; public MainPage() { ... myController.ScreenContactStarted += MyController_ScreenContactStarted; myController.ScreenContactContinued += MyController_ScreenContactContinued; myController.ScreenContactEnded += MyController_ScreenContactEnded;

MyController_ScreenContactEnded; myController.ControlLost += MyController_ControlLost; //Set initial grid for Surface Dial input. ActiveGrid = Grid0; ActiveSlider = RotationSlider0; ActiveSwitch = ButtonToggle0; } private void MyController_ScreenContactStarted(RadialController sender, RadialControllerScreenContactStartedEventArgs args) { //find grid at contact location, update visuals, selection ActivateGridAtLocation(args.Contact.Position); } private void MyController_ScreenContactContinued(RadialController sender, RadialControllerScreenContactContinuedEventArgs args) { //if a new grid is under contact location, update visuals, selection if (!VisualTreeHelper.FindElementsInHostCoordinates( args.Contact.Position, RootGrid).Contains(ActiveGrid)) { ActiveGrid.Background = new SolidColorBrush(Windows.UI.Colors.White); ActivateGridAtLocation(args.Contact.Position); } } private void MyController_ScreenContactEnded(RadialController sender, object args) { //return grid color to normal when contact leaves screen ActiveGrid.Background = new SolidColorBrush(Windows.UI.Colors.White); } private void MyController_ControlLost(RadialController sender, object args) { //return grid color to normal when focus lost ActiveGrid.Background = new SolidColorBrush(Windows.UI.Colors.White); } private void ActivateGridAtLocation(Point Location) { var elementsAtContactLocation = VisualTreeHelper.FindElementsInHostCoordinates(Location, RootGrid); foreach (UIElement element in elementsAtContactLocation) { if (element as Grid == Grid0) { ActiveSlider = RotationSlider0; ActiveSwitch = ButtonToggle0; ActiveGrid = Grid0; ActiveGrid.Background = new SolidColorBrush( Windows.UI.Colors.LightGoldenrodYellow); return; } else if (element as Grid == Grid1) { ActiveSlider = RotationSlider1; ActiveSwitch = ButtonToggle1; ActiveGrid = Grid1; ActiveGrid.Background = new SolidColorBrush( Windows.UI.Colors.LightGoldenrodYellow); return; } else if (element as Grid == Grid2)

else if (element as Grid == Grid2) { ActiveSlider = RotationSlider2; ActiveSwitch = ButtonToggle2; ActiveGrid = Grid2; ActiveGrid.Background = new SolidColorBrush( Windows.UI.Colors.LightGoldenrodYellow); return; } else if (element as Grid == Grid3) { ActiveSlider = RotationSlider3; ActiveSwitch = ButtonToggle3; ActiveGrid = Grid3; ActiveGrid.Background = new SolidColorBrush( Windows.UI.Colors.LightGoldenrodYellow); return; } } }

When we run the app, we use the Surface Dial to interact with it. First, we place the device on the Surface Studio screen, which the app detects and associates with the lower right section (see image). We then press and hold the Surface Dial to open the menu and select our custom tool. Once the custom tool is activated, the slider control can be adjusted by rotating the Surface Dial and the switch can be toggled by clicking the Surface Dial.

The sample app UI activated using the Surface Dial custom tool

Summary This topic provides an overview of the Surface Dial input device with UX and developer guidance on how to customize the user experience for off-screen scenarios as well as on-screen scenarios when used with Surface Studio.

Feedback Please send your questions, suggestions, and feedback to [email protected].

Related articles API reference

RadialController class RadialControllerButtonClickedEventArgs class RadialControllerConfiguration class RadialControllerControlAcquiredEventArgs class RadialControllerMenu class RadialControllerMenuItem class RadialControllerRotationChangedEventArgs class RadialControllerScreenContact class RadialControllerScreenContactContinuedEventArgs class RadialControllerScreenContactStartedEventArgs class RadialControllerMenuKnownIcon enum RadialControllerSystemMenuItemKind enum Samples

Universal Windows Platform samples (C# and C++) Windows classic desktop sample

Cortana interactions in UWP apps 3/6/2017 • 1 min to read • Edit on GitHub

Cortana offers a robust and comprehensive extensibility framework that enables you to seamlessly incorporate functionality from your app or service into the Cortana experience.

We've moved All developer documentation for Cortana features and services is now available through the Cortana dev center. To get started, see the Overview of Cortana extensibility. To learn how to extend Cortana with functionality from a UWP app using voice commands, see Cortana voice commands.

Related articles VCD elements and attributes v1.2 Designers Speech design guidelines Cortana design guidelines for voice commands Samples Cortana voice command sample

Cortana design guidelines 1 min to read • Edit on Git Hub

This topic has been moved to https://msdn.microsoft.com/en-us/cortana/voicecommands/voicecommand-designguidelines. Github: https://github.com/Microsoft/cortana-docs/blob/master/docs/voicecommands/voicecommand-designguidelines.md

Activate a foreground app with voice commands through Cortana 1 min to read • Edit on Git Hub

This topic has been moved to https://msdn.microsoft.com/en-us/cortana/voicecommands/launch-a-foregroundapp-with-voice-commands-in-cortana. Github: https://github.com/Microsoft/cortana-docs/blob/master/docs/voicecommands/launch-a-foreground-appwith-voice-commands-in-cortana.md

Dynamically modify VCD phrase lists 1 min to read • Edit on Git Hub

This topic has been moved to https://msdn.microsoft.com/en-us/cortana/voicecommands/dynamically-modifyvoice-command-definition--vcd--phrase-lists. Github: https://github.com/Microsoft/cortana-docs/blob/master/docs/voicecommands/dynamically-modify-voicecommand-definition--vcd--phrase-lists.md

Activate a background app with voice commands through Cortana 1 min to read • Edit on Git Hub

This topic has been moved to https://msdn.microsoft.com/en-us/cortana/voicecommands/launch-a-backgroundapp-with-voice-commands-in-cortana. Github: https://github.com/Microsoft/cortana-docs/blob/master/docs/voicecommands/launch-a-background-appwith-voice-commands-in-cortana.md

Interact with a background app in Cortana 1 min to read • Edit on Git Hub

This topic has been moved to https://msdn.microsoft.com/en-us/cortana/voicecommands/interact-with-abackground-app-in-cortana. Github: https://github.com/Microsoft/cortana-docs/blob/master/docs/voicecommands/interact-with-abackground-app-in-cortana.md

Deep link from Cortana to a background app 1 min to read • Edit on Git Hub

This topic has been moved to https://msdn.microsoft.com/en-us/cortana/voicecommands/deep-link-into-your-appfrom-cortana. Github: https://github.com/Microsoft/cortana-docs/blob/master/docs/voicecommands/deep-link-into-your-appfrom-cortana.md

Support natural language voice commands in Cortana 1 min to read • Edit on Git Hub

This topic has been moved to https://msdn.microsoft.com/en-us/cortana/voicecommands/support-naturallanguage-voice-commands-in-cortana. Github: https://github.com/Microsoft/cortana-docs/blob/master/docs/voicecommands/support-natural-languagevoice-commands-in-cortana.md

Keyboard interactions 3/6/2017 • 29 min to read • Edit on GitHub

Keyboard input is an important part of the overall user interaction experience for apps. The keyboard is indispensable to people with certain disabilities or users who just consider it a more efficient way to interact with an app. For example, users should be able to navigate your app by using Tab and arrow keys, activate UI elements by using Spacebar and Enter, and access commands by using keyboard shortcuts.

Important APIs KeyDown KeyUp KeyRoutedEventArgs

A well-designed keyboard UI is an important aspect of software accessibility. It enables users with vision impairments or who have certain motor disabilities to navigate an app and interact with its features. Such users might not be able to operate a mouse and instead rely on various assistive technologies such as keyboard enhancement tools, on-screen keyboards, screen enlargers, screen readers, and voice input utilities. Users can interact with universal apps through a hardware keyboard and two software keyboards: the On-Screen Keyboard (OSK) and the touch keyboard. On-Screen Keyboard The On-Screen Keyboard is a visual, software keyboard that you can use instead of the physical keyboard to type and enter data using touch, mouse, pen/stylus or other pointing device (a touch screen is not required). The OnScreen Keyboard is provided for systems that don't have a physical keyboard, or for users whose mobility impairments prevent them from using traditional physical input devices. The On-Screen Keyboard emulates most, if not all, the functionality of a hardware keyboard. The On-Screen Keyboard can be turned on from the Keyboard page in Settings > Ease of access. Note The On-Screen Keyboard has priority over the touch keyboard, which won't be shown if the On-Screen Keyboard is present.

On-Screen Keyboard

Touch keyboard

The touch keyboard is a visual, software keyboard used for text entry with touch input. It is not a replacement for the On-Screen Keyboard as it's used for text input only (it doesn't emulate the hardware keyboard). Depending on the device, the touch keyboard appears when a text field or other editable text control gets focus, or when the user manually enables it through the Notification Center:

Note The user might have to go to the Tablet mode screen in Settings > System and turn on "Make Windows more touch-friendly when using your device as a tablet" to enable the automatic appearance of the touch keyboard. If your app sets focus programmatically to a text input control, the touch keyboard is not invoked. This eliminates unexpected behaviors not instigated directly by the user. However, the keyboard does automatically hide when focus is moved programmatically to a non-text input control. The touch keyboard typically remains visible while the user navigates between controls in a form. This behavior can vary based on the other control types within the form. The following is a list of non-edit controls that can receive focus during a text entry session using the touch keyboard without dismissing the keyboard. Rather than needlessly churn the UI and potentially disorient the user, the touch keyboard remains in view because the user is likely to go back and forth between these controls and text entry with the touch keyboard. Check box Combo box Radio button Scroll bar Tree Tree item Menu Menu bar Menu item Toolbar List List item Here are examples of different modes for the touch keyboard. The first image is the default layout, the second is the thumb layout (which might not be available in all languages). Here are examples of different modes for the touch keyboard. The first image is the default layout, the second is the thumb layout (which might not be available in all languages). The touch keyboard in default layout mode: **

The touch keyboard in expanded layout mode:

The touch keyboard in default thumb layout mode:

The touch keyboard in numeric thumb layout mode: **

Successful keyboard interactions enable users to accomplish basic app scenarios using only the keyboard; that is, users can reach all interactive elements and activate default functionality. A number of factors can affect the degree of success, including keyboard navigation, access keys for accessibility, and accelerator (or shortcut) keys for advanced users. Note The touch keyboard does not support toggle and most system commands (see Patterns).

Navigation To use a control (including navigation elements) with the keyboard, the control must have focus. One way for a control to receive keyboard focus is to make it accessible via tab navigation. A well designed keyboard navigation model provides a logical and predictable tab order that enables a user to explore and use your app quickly and efficiently. All interactive controls should have tab stops (unless they are in a group), whereas non-interactive controls, such as labels, should not. A set of related controls can be made into a control group and assigned a single tab stop. Control groups are used for sets of controls that behave like a single control, such as radio buttons. They can also be used when there too many controls to navigate efficiently with the Tab key alone. The arrow keys, Home, End, Page Up, and Page Down move input focus among the controls within a group (it is not possible to navigate out of a control group using these keys). You should set initial keyboard focus on the element that users will intuitively (or most likely) interact with first when your app starts. Often, this is the main content view of the app so that a user can immediately start using the arrow keys to scroll the app content. Don’t set initial keyboard focus on an element with potentially negative, or even disastrous, results. This can prevent loss of data or system access. Try to rank and present the most important commands, controls, and content first in both the tab order and the display order (or visual hierarchy). However, the actual display position can depend on the parent layout container and certain properties of the child elements that influence the layout. In particular, layouts that use a grid metaphor or a table metaphor can have a reading order quite different from the tab order. This is not always a problem, but you should test your app's functionality, both as a touchable UI and as a keyboard-accessible UI. Tab order should follow reading order, whenever possible. This can reduce confusion and is dependent on locale

and language. Associate keyboard buttons with appropriate UI (back and forward buttons) in your app. Try to make navigating back to the start screen of your app and between key content as easy and straightforward as possible. Use the arrow keys as keyboard shortcuts for proper inner navigation among child elements of composite elements. If tree view nodes have separate child elements for handling expand–collapse and node activation, use the left and right arrow keys to provide keyboard expand–collapse functionality. This is consistent with the platform controls. Because the touch keyboard occludes a large portion of the screen, the Universal Windows Platform (UWP) ensures that the input field with focus scrolls into view as a user navigates through the controls on the form, including controls that are not currently in view. Custom controls should emulate this behavior.

In some cases, there are UI elements that should stay on the screen the entire time. Design the UI so that the form controls are contained in a panning region and the important UI elements are static. For example:

Activation A control can be activated in a number of different ways, whether it currently has focus or not. Spacebar, Enter, and Esc The spacebar should activate the control with input focus. The Enter key should activate a default control or the control with input focus. A default control is the control with initial focus or one that responds exclusively to the Enter key (typically it changes with input focus). In addition, the Esc key should close or exit transitory UI, such as menus and dialogs. The Calculator app shown here uses the spacebar to activate the button with focus, locks the Enter key to the “=” button, and locks the Esc key to the “C” button.

Keyboard modifiers Keyboard modifiers fall into the following categories: CATEGORY

DESCRIPTION

Shortcut key

Perform a common action without UI such as "Ctrl-S" for Save. Implement keyboard shortcuts for key app functionality. Not every command has, or requires, a shortcut.

Access key/Hot key

Assigned to every visible, top-level control such as "Alt-F" for the File menu. An access key does not invoke or activate a command.

Accelerator key

Perform default system or app-defined commands such as "Alt-PrtScrn" for screen capture, "Alt-Tab" to switch apps, or "F1" for help. A command associated with an accelerator key does not have to be a menu item.

Application key/Menu key

Show context menu.

Window key/Command key

Activate system commands such as System Menu, Lock Screen, or Show Desktop.

Access keys and accelerator keys support interaction with controls directly instead of navigating to them using the Tab key. While some controls have intrinsic labels, such as command buttons, check boxes, and radio buttons, other controls have external labels, such as list views. For controls with external labels, the access key is assigned to the label, which, when invoked, sets focus to an element or value within the associated control.

The example here, shows the access keys for the Page Layout tab in Word.

Here, the Indent Left text field value is highlighted after entering the access key identified in the associated label.

Usability and accessibility A well-designed keyboard interaction experience is an important aspect of software accessibility. It enables users with vision impairments or who have certain motor disabilities to navigate an app and interact with its features. Such users might be unable to operate a mouse and must, instead, rely on various assistive technologies that include keyboard enhancement tools and on-screen keyboards (along with screen enlargers, screen readers, and voice input utilities). For these users, comprehensiveness is more important than consistency. Experienced users often have a strong preference for using the keyboard, because keyboard-based commands can be entered more quickly and don't require removing their hands from the keyboard. For these users, efficiency and consistency are crucial; comprehensiveness is important only for the most frequently used commands. There are subtle distinctions when designing for usability and accessibility, which is why two different keyboard access mechanisms are supported. Access keys have the following characteristics: An access key is a shortcut to a UI element in your app. They use the Alt key plus an alphanumeric key. They are primarily for accessibility. They are assigned to all menus and most dialog box controls. They aren't intended to be memorized, so they are documented directly in the UI by underlining the corresponding control label character. They have effect only in the current window, and navigate to the corresponding menu item or control. They aren't assigned consistently because they can't always be. However, access keys should be assigned consistently for commonly used commands, especially commit buttons. They are localized. Because access keys aren't intended to be memorized, they are assigned to a character that is early in the label to make them easy to find, even if there is a keyword that appears later in the label. In contrast, accelerator keys have the following characteristics:

An accelerator key is a shortcut to an app command. They primarily use Ctrl and Function key sequences (Windows system shortcut keys also use Alt+nonalphanumeric keys and the Windows logo key). They are primarily for efficiency for advanced users. They are assigned only to the most commonly used commands. They are intended to be memorized, and are documented only in menus, tooltips, and Help. They have effect throughout the entire program, but have no effect if they don't apply. They must be assigned consistently because they are memorized and not directly documented. They aren't localized. Because accelerator keys are intended to be memorized, the most frequently used accelerator keys ideally use letters from the first or most memorable characters within the command's keywords, such as Ctrl+C for Copy and Ctrl+Q for Request. Users should be able to accomplish all tasks supported by your app using only the hardware keyboard or the OnScreen Keyboard. You should provide an easy way for users who rely on screen readers and other assistive technology to discover your app's accelerator keys. Communicate accelerator keys by using tooltips, accessible names, accessible descriptions, or some other form of on-screen communication. At a minimum, access and accelerator keys should be well documented in your app's Help content. Don’t assign well-known or standard accelerator keys to other functionality. For example, Ctrl+F is typically used for find or search. Don’t bother trying to assign access keys to all interactive controls in a dense UI. Just ensure the most important and the most used have access keys, or use control groups and assign an access key to the control group label. Don't change commands using keyboard modifiers. Doing so is undiscoverable and can cause confusion. Don't disable a control while it has input focus. This can interfere with keyboard input. To ensure successful keyboard interaction experiences, it is critical to test your app thoroughly and exclusively with the keyboard.

Text input Always query the device capabilities when relying on keyboard input. On some devices (such as phone), the touch keyboard can only be used for text input as it does not provide many of the accelerators or command keys found on a hardware keyboard (such as alt, the function keys, or the Windows Logo key). Don't make users navigate the app using the touch keyboard. Depending on the control getting focus, the touch keyboard might get dismissed. Try to display the keyboard throughout the entire interaction with your form. This eliminates UI churn that can disorient the user in the middle of a form or text entry flow. Ensure that users can always see the input field that they're typing into. The touch keyboard occludes half of the screen, so the input field with focus should scroll into view as the user traverses the form. A standard hardware keyboard or OSK consists of seven types of keys, each supporting unique functionality: Character key: sends a literal character to the window with input focus. Modifier key: alters the function of a primary key when pressed simultaneously, such as Ctrl, Alt, Shift, and the Windows logo key. Navigation key: moves input focus or text input location, such as the Tab, Home, End, Page Up, Page Down, and directional arrow keys.

Editing key: manipulates text, such as the Shift, Tab, Enter, Insert, Backspace, and Delete keys. Function key: performs a special function, such as F1 through F12 keys. Toggle key: puts the system into a mode, such as Caps Lock, ScrLk, and Num Lock keys. Command key: performs a system task or command activation, such as Spacebar, Enter, Esc, Pause/Break, and Print Screen keys. In addition to these categories, a secondary class of keys and key combinations exist that can be used as shortcuts to app functionality: Access key: exposes controls or menu items by pressing the Alt key with a character key, indicated by underlining of the access key character assignment in a menu, or displaying of the access key character(s) in an overlay. Accelerator key: exposes app commands by pressing a function key or the Ctrl key with a character key. Your app might or might not have UI that corresponds to the command. Another class of key combinations, known as secure attention sequence (SAS), cannot be intercepted by an app. This is a security feature intended to protect the user's system during login, and include Ctrl-Alt-Del and Win-L. The Notepad app is shown here with the expanded File menu that includes both access keys and accelerator keys.

Keyboard commands The following is a comprehensive list of the keyboard interactions provided across the various devices that support keyboard input. Some devices and platforms require native keystrokes and interactions, these are noted. When designing custom controls and interactions, use this keyboard language consistently to make your app feel familiar, dependable, and easy to learn. Don't redefine the default keyboard shortcuts. The following tables list frequently used keyboard commands. For a complete list of keyboard commands, see Windows Keyboard Shortcut Keys. Navigation commands

ACTION

KEY COMMAND

Back

Alt+Left or the back button on special keyboards

Forward

Alt+Right

Up

Alt+Up

Cancel or Escape from current mode

Esc

Move through items in a list

Arrow key (Left, Right, Up, Down)

Jump to next list of items

Ctrl+Left

Semantic zoom

Ctrl++ or Ctrl+-

Jump to a named item in a collection

Start typing item name

Next page

Page Up, Page Down or Spacebar

Next tab

Ctrl+Tab

Previous tab

Ctrl+Shift+Tab

Open app bar

Windows+Z

Activate or Navigate into an item

Enter

Select

Spacebar

Continuously select

Shift+Arrow key

Select all

Ctrl+A

Common commands ACTION

KEY COMMAND

Pin an item

Ctrl+Shift+1

Save

Ctrl+S

Find

Ctrl+F

Print

Ctrl+P

Copy

Ctrl+C

Cut

Ctrl+X

New item

Ctrl+N

ACTION

KEY COMMAND

Paste

Ctrl+V

Open

Ctrl+O

Open address (for example, a URL in Internet Explorer)

Ctrl+L or Alt+D

Media navigation commands ACTION

KEY COMMAND

Play/Pause

Ctrl+P

Next item

Ctrl+F

Preview item

Ctrl+B

Note: The media navigation key commands for Play/Pause and Next item are the same as the key commands for Print and Find, respectively. Common commands should take priority over media navigation commands. For example, if an app supports both plays media and prints, the key command Ctrl+P should print.

Visual feedback Use focus rectangles only with keyboard interactions. If the user initiates a touch interaction, make the keyboard UI gradually fade away. This keeps the UI clean and uncluttered. Don't display visual feedback if an element doesn't support interaction (such as static text). Again, this keeps the UI clean and uncluttered. Try to display visual feedback concurrently for all elements that represent the same input target. Try to provide on-screen buttons (such as + and -) as hints for emulating touch-based manipulations such as panning, rotating, zooming, and so on. For more general guidance on visual feedback, see Guidelines for visual feedback.

Keyboard events and focus The following keyboard events can occur for both hardware and touch keyboards. EVENT

DESCRIPTION

KeyDown

Occurs when a key is pressed.

KeyUp

Occurs when a key is released.

Important Some Windows Runtime controls handle input events internally. In these cases, it might appear that an input event doesn't occur because your event listener doesn't invoke the associated handler. Typically, this subset of keys is processed by the class handler to provide built in support of basic keyboard accessibility. For example, the Button class overrides the OnKeyDown events for both the Space key and the Enter key (as well as OnPointerPressed) and routes them to the Click event of the control. When a key press is handled by the control class, the KeyDown and KeyUp events are not raised.

This provides a built-in keyboard equivalent for invoking the button, similar to tapping it with a finger or clicking it with a mouse. Keys other than Space or Enter still fire KeyDown and KeyUp events. For more info about how class-based handling of events works (specifically, the "Input event handlers in controls" section), see Events and routed events overview. Controls in your UI generate keyboard events only when they have input focus. An individual control gains focus when the user clicks or taps directly on that control in the layout, or uses the Tab key to step into a tab sequence within the content area. You can also call a control's Focus method to force focus. This is necessary when you implement shortcut keys, because keyboard focus is not set by default when your UI loads. For more info, see the Shortcut keys example later in this topic. For a control to receive input focus, it must be enabled, visible, and have IsTabStop and HitTestVisible property values of true. This is the default state for most controls. When a control has input focus, it can raise and respond to keyboard input events as described later in this topic. You can also respond to a control that is receiving or losing focus by handling the GotFocus and LostFocus events. By default, the tab sequence of controls is the order in which they appear in the Extensible Application Markup Language (XAML). However, you can modify this order by using the TabIndex property. For more info, see Implementing keyboard accessibility.

Keyboard event handlers An input event handler implements a delegate that provides the following information: The sender of the event. The sender reports the object where the event handler is attached. Event data. For keyboard events, that data will be an instance of KeyRoutedEventArgs. The delegate for handlers is KeyEventHandler. The most relevant properties of KeyRoutedEventArgs for most handler scenarios are Key and possibly KeyStatus. OriginalSource. Because the keyboard events are routed events, the event data provides OriginalSource. If you deliberately allow events to bubble up through an object tree, OriginalSource is sometimes the object of concern rather than sender. However, that depends on your design. For more information about how you might use OriginalSource rather than sender, see the "Keyboard Routed Events" section of this topic, or Events and routed events overview. Attaching a keyboard event handler

You can attach keyboard event-handler functions for any object that includes the event as a member. This includes any UIElement derived class. The following XAML example shows how to attach handlers for the KeyUp event for a Grid. ...

You can also attach an event handler in code. For more info, see Events and routed events overview. Defining a keyboard event handler

The following example shows the incomplete event handler definition for the KeyUp event handler that was attached in the preceding example.

void Grid_KeyUp(object sender, KeyRoutedEventArgs e) { //handling code here }

Private Sub Grid_KeyUp(ByVal sender As Object, ByVal e As KeyRoutedEventArgs) ' handling code here End Sub

void MyProject::MainPage::Grid_KeyUp( Platform::Object^ sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e) { //handling code here }

Using KeyRoutedEventArgs

All keyboard events use KeyRoutedEventArgs for event data, and KeyRoutedEventArgs contains the following properties: Key KeyStatus Handled OriginalSource (inherited from RoutedEventArgs) Key

The KeyDown event is raised if a key is pressed. Likewise, KeyUp is raised if a key is released. Usually, you listen to the events to process a specific key value. To determine which key is pressed or released, check the Key value in the event data. Key returns a VirtualKey value. The VirtualKey enumeration includes all the supported keys. Modifier keys

Modifier keys are keys such as Ctrl or Shift that users typically press in combination with other keys. Your app can use these combinations as keyboard shortcuts to invoke app commands. You detect shortcut key combinations by using code in your KeyDown and KeyUp event handlers. You can then track the pressed state of the modifier keys you are interested in. When a keyboard event occurs for a nonmodifier key, you can check whether a modifier key is in the pressed state at the same time. NOTE The Alt key is represented by the VirtualKey.Menu value.

Shortcut keys example

The following example demonstrates how to implement shortcut keys. In this example, users can control media playback using Play, Pause, and Stop buttons or Ctrl+P, Ctrl+A, and Ctrl+S keyboard shortcuts. The button XAML shows the shortcuts by using tooltips and AutomationProperties properties in the button labels. This selfdocumentation is important to increase the usability and accessibility of your app. For more info, see Keyboard accessibility. Note also that the page sets input focus to itself when it is loaded. Without this step, no control has initial input focus, and the app does not raise input events until the user sets the input focus manually (for example, by tabbing to or clicking a control).

Play Pause Stop

//showing implementations but not header definitions void MainPage::OnNavigatedTo(NavigationEventArgs^ e) { (void) e; // Unused parameter this->Loaded+=ref new RoutedEventHandler(this,&MainPage::ProgrammaticFocus); } void MainPage::ProgrammaticFocus(Object^ sender, RoutedEventArgs^ e) { this->Focus(Windows::UI::Xaml::FocusState::Programmatic); } void KeyboardSupport::MainPage::MediaButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) { FrameworkElement^ fe = safe_cast(sender); if (fe->Name == "PlayButton") {DemoMovie->Play();} if (fe->Name == "PauseButton") {DemoMovie->Pause();} if (fe->Name == "StopButton") {DemoMovie->Stop();} }

void KeyboardSupport::MainPage::Grid_KeyDown(Platform::Object^ sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e) { if (e->Key == VirtualKey::Control) isCtrlKeyPressed = true; }

void KeyboardSupport::MainPage::Grid_KeyUp(Platform::Object^ sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e) { if (e->Key == VirtualKey::Control) isCtrlKeyPressed = false; else if (isCtrlKeyPressed) { if (e->Key==VirtualKey::P) { DemoMovie->Play(); } if (e->Key==VirtualKey::A) {DemoMovie->Pause();} if (e->Key==VirtualKey::S) {DemoMovie->Stop();} } }

protected override void OnNavigatedTo(NavigationEventArgs e) { // Set the input focus to ensure that keyboard events are raised. this.Loaded += delegate { this.Focus(FocusState.Programmatic); }; } private void MediaButton_Click(object sender, RoutedEventArgs e) { switch ((sender as Button).Name) { case "PlayButton": DemoMovie.Play(); break; case "PauseButton": DemoMovie.Pause(); break; case "StopButton": DemoMovie.Stop(); break; } } private void Grid_KeyUp(object sender, KeyRoutedEventArgs e) { if (e.Key == VirtualKey.Control) isCtrlKeyPressed = false; } private void Grid_KeyDown(object sender, KeyRoutedEventArgs e) { if (e.Key == VirtualKey.Control) isCtrlKeyPressed = true; else if (isCtrlKeyPressed) { switch (e.Key) { case VirtualKey.P: DemoMovie.Play(); break; case VirtualKey.A: DemoMovie.Pause(); break; case VirtualKey.S: DemoMovie.Stop(); break; } } }

Private isCtrlKeyPressed As Boolean Protected Overrides Sub OnNavigatedTo(e As Navigation.NavigationEventArgs) End Sub Private Sub Grid_KeyUp(sender As Object, e As KeyRoutedEventArgs) If e.Key = Windows.System.VirtualKey.Control Then isCtrlKeyPressed = False End If End Sub Private Sub Grid_KeyDown(sender As Object, e As KeyRoutedEventArgs) If e.Key = Windows.System.VirtualKey.Control Then isCtrlKeyPressed = True If isCtrlKeyPressed Then Select Case e.Key Case Windows.System.VirtualKey.P DemoMovie.Play() Case Windows.System.VirtualKey.A DemoMovie.Pause() Case Windows.System.VirtualKey.S DemoMovie.Stop() End Select End If End Sub Private Sub MediaButton_Click(sender As Object, e As RoutedEventArgs) Dim fe As FrameworkElement = CType(sender, FrameworkElement) Select Case fe.Name Case "PlayButton" DemoMovie.Play() Case "PauseButton" DemoMovie.Pause() Case "StopButton" DemoMovie.Stop() End Select End Sub

NOTE Setting AutomationProperties.AcceleratorKey or AutomationProperties.AccessKey in XAML provides string information, which documents the shortcut key for invoking that particular action. The information is captured by Microsoft UI Automation clients such as Narrator, and is typically provided directly to the user. Setting AutomationProperties.AcceleratorKey or AutomationProperties.AccessKey does not have any action on its own. You will still need to attach handlers for KeyDown or KeyUp events in order to actually implement the keyboard shortcut behavior in your app. Also, the underline text decoration for an access key is not provided automatically. You must explicitly underline the text for the specific key in your mnemonic as inline Underline formatting if you wish to show underlined text in the UI.

Keyboard routed events Certain events are routed events, including KeyDown and KeyUp. Routed events use the bubbling routing strategy. The bubbling routing strategy means that an event originates from a child object and is then routed up to successive parent objects in the object tree. This presents another opportunity to handle the same event and interact with the same event data. Consider the following XAML example, which handles KeyUp events for a Canvas and two Button objects. In this case, if you release a key while focus is held by either Button object, it raises the KeyUp event. The event is then bubbled up to the parent Canvas.



The following example shows how to implement the KeyUp event handler for the corresponding XAML content in the preceding example. void StackPanel_KeyUp(object sender, KeyRoutedEventArgs e) { statusTextBlock.Text = String.Format( "The key {0} was pressed while focus was on {1}", e.Key.ToString(), (e.OriginalSource as FrameworkElement).Name); }

Notice the use of the OriginalSource property in the preceding handler. Here, OriginalSource reports the object that raised the event. The object could not be the StackPanel because the StackPanel is not a control and cannot have focus. Only one of the two buttons within the StackPanel could possibly have raised the event, but which one? You use OriginalSource to distinguish the actual event source object, if you are handling the event on a parent object. The Handled property in event data

Depending on your event handling strategy, you might want only one event handler to react to a bubbling event. For instance, if you have a specific KeyUp handler attached to one of the Button controls, it would have the first opportunity to handle that event. In this case, you might not want the parent panel to also handle the event. For this scenario, you can use the Handled property in the event data. The purpose of the Handled property in a routed event data class is to report that another handler you registered earlier on the event route has already acted. This influences the behavior of the routed event system. When you set Handled to true in an event handler, that event stops routing and is not sent to successive parent elements. AddHandler and already-handled keyboard events

You can use a special technique for attaching handlers that can act on events that you already marked as handled. This technique uses the AddHandler method to register a handler, rather than using XAML attributes or languagespecific syntax for adding handlers, such as += in C#. A general limitation of this technique is that the AddHandler API takes a parameter of type RoutedEvent idnentifying the routed event in question. Not all routed events provide a RoutedEvent identifier, and this consideration thus affects which routed events can still be handled in the Handled case. The KeyDown and KeyUp events have routed event identifiers (KeyDownEvent and KeyUpEvent) on UIElement. However, other events such as TextBox.TextChanged do not have routed event identifiers and thus cannot be used with the AddHandler technique. Overriding keyboard events and behavior

You can override key events for specific controls (such as GridView) to provide consistent focus navigation for various input devices, including keyboard and gamepad. In the following example, we subclass the control and override the KeyDown behavior to move focus to the the GridView content when any arrow key is pressed.

public class CustomGridView : GridView { protected override void OnKeyDown(KeyRoutedEventArgs e) { // Override arrow key behaviors. if (e.Key != Windows.System.VirtualKey.Left && e.Key != Windows.System.VirtualKey.Right && e.Key != Windows.System.VirtualKey.Down && e.Key != Windows.System.VirtualKey.Up) base.OnKeyDown(e); else FocusManager.TryMoveFocus(FocusNavigationDirection.Down); } }

NOTE If using a GridView for layout only, consider using other controls such as ItemsControl with ItemsWrapGrid.

Commanding A small number of UI elements provide built-in support for commanding. Commanding uses input-related routed events in its underlying implementation. It enables processing of related UI input, such as a certain pointer action or a specific accelerator key, by invoking a single command handler. If commanding is available for a UI element, consider using its commanding APIs instead of any discrete input events. For more info, see ButtonBase.Command. You can also implement ICommand to encapsulate command functionality that you invoke from ordinary event handlers. This enables you to use commanding even when there is no Command property available.

Text input and controls Certain controls react to keyboard events with their own handling. For instance, TextBox is a control that is designed to capture and then visually represent text that was entered by using the keyboard. It uses KeyUp and KeyDown in its own logic to capture keystrokes, then also raises its own TextChanged event if the text actually changed. You can still generally add handlers for KeyUp and KeyDown to a TextBox, or any related control that is intended to process text input. However, as part of its intended design, a control might not respond to all key values that are directed to it through key events. Behavior is specific to each control. As an example, ButtonBase (the base class for Button) processes KeyUp so that it can check for the Spacebar or Enter key. ButtonBase considers KeyUp equivalent to a mouse left button down for purposes of raising a Click event. This processing of the event is accomplished when ButtonBase overrides the virtual method OnKeyUp. In its implementation, it sets Handled to true. The result is that any parent of a button that is listening for a key event, in the case of a Spacebar, would not receive the already-handled event for its own handlers. Another example is TextBox. Some keys, such as the ARROW keys,