//Build 2017 Day2 – Sessions

Lors de cette journée consacrée à Windows, j’ai assisté à plusieurs sessions où malheureusement le  contenue tournaient autour de quasiment le même sujet.

App Model evolution

Dans cette session  Andrew Clinick a présenté les évolutions de l’app Model:

  • Simplification et l’amélioration de la vitesse de distribution.
  • Les delta de MAJ
  • Self UWP updating apps (pour les applications installées en dehors du store)
  • Microsoft conseille fortement l’utilisation du desktop bridge, non pas pour être dans le store, mais pour améliorer fortement l’expérience utilisateur, dans le sens où l’installation/désinstallation de l’application sera « propre » avec 0 impact sur le système.

Quelques infos sur le Desktop Bridge :

  • Il ne convertit pas les applications mais plutôt le MSI, xcopy …
  • l’application ne change quasiment pas
  • Office et Microsoft teams utilisent le desktop bridge
  • Amélioration de l’engagement des utilisateurs avec plusieurs outils :
    • Le project Rome
    • Les adaptatives cards (via la nouvelle fonctionnalité de Windows « timeline » ou via Cortana/Bots)
    • Microsoft Graph (sujet récurant lors de la build)

What’s New in TypeScript

Le nom de cette session est trompeur. Aucune nouveauté n’a été présentée. Anders Hejlsberg a déroulé exactement les mêmes slides qu’il utilise depuis plusieurs mois, avec exactement les mêmes démos.

Les nouveautés listées (ou vues lors des démos) sont celles des versions 2.0 à 2.2 et non pas des futures versions:

  • Non-nullable types
  • Literal types
  • Async Await ( pour de l’ES3/ES5)
  • type checking pour du JavaScript (dans VS Code)
  • Quick fixes (dans VS Code)

//Build 2017 Day1 – Sessions

Pour cette première journée j’ai participé à plusieurs sessions:

1- Bring your desktop apps to UWP and the Windows Store using the Desktop Bridge

Dans cette session on nous a expliqué le but du bridge => Créer un pont entre l’ancien App model de Windows qui existe depuis les premières versions de celui-ci et le nouveau App model qui existe depuis 2011/2012 avec Windows 8.

Avantages:

  • Simplicité
  • Pas d’élévations de droit lors de l’installation/utilisation
  • Installation sûre (qui ne va pas aller modifier les clés de registre par exemple)
  • Offrir la possibilité d’avoir des MAJ automatiques et différentielles
  • Ouverture à la monétisation simple (via le store)
  • ….

Le fonctionnement est assez simple, il faut fournir un MSI à l’outil, celui-ci va le convertir en APPX (Si la conversion ne marche pas, c’est qu’il faut changer du code qui n’est pas supporté (ou pas encore) par le Bridge)

Le Bridge est en constante évolution avec le support de plus en plus d’API: la règle est simple, toutes les API publiques – non cassées – sont ou seront supportées.

Les dernières nouveautés sont:

  • Support du préinstall
  • Objets com
  • Déclaration de règles firewall
  • Support du wack
  • Support des applications sans MSI (un .exe avec des dll)

La version complète d’office qui sera bientôt dans le store utilise ce même Bridge !

 

2- Bot capabilities, patterns and principles

Cette session est orientée sur les patterns qu’il faut/qu’il ne faut pas utiliser pour créer un bot, exemple :

  • A NE PAS FAIRE => un bot avec un seul dialog (1 question) qui utilise 100 LUIS intents (choses que le bot peut faire) avec 100 différents énoncés == 10000 diférentes choses que l’utilisateur peut dire (ET n possibilités non prévues)
  • A Faire => Guider l’utilisateur, avec des questions précises, avec une UI (questions avec des boutons de réponses)

3- Cortana skills development: Get started

Super nouveauté qui ouvre énormément de  possibilités . Malheureusement inutile en France pour l’instant, Cortana skills n’est disponible qu’aux USA et on a pas d’informations d’infos sur la date de disponibilité dans les autres pays.

Cortana skills permet de déployer des skills (l’équivalent d’un bot) directement dans Cortana (PC, téléphone ou autre device qui supporte Cortana)

Un skill c’est une « unité d’intelligence conversationnelle » qui aide les utilisateurs via un service, ou autrement un Bot qui utilise le channel Cortana (et donc l’UI de cortana) pour interagir et fournir de l’information à un utilisateur.

L’authentification avec un compte d’une organisation est possible, la récupération des données de l’utilisateur aussi (par le service/bot)

On a eu droit à deux démos :

  • Commande d’une pizza Domino’s (sans application installée sur le PC)
  • Recherche d’un collègue pour faire du code review (le bot va chercher de l’information avec Microsoft Graph => scénario avec l’authentification)

Ressources dispo ici

4- Snapshot debugging and profiling in Microsoft Azure: Next generation diagnostics for your in-production cloud apps 

Super session qui montre les futures fonctionnalités de Visual Studio/Azure (qui seront complètement ouverts en preview à la fin de l’été).

  • Snapshots

Cette nouvelle fonctionnalité d’Application Insights permet de prendre un snapshot de l’application en prod quand une exception se déclenche via la télémétrie.

On peut aussi via Visual Studio Enterprise avoir des snappoints ( l’équivalent d’un point d’arrêt mais pour faire un snapshot et non pas arrêter l’exécution du code) et des logpoints (qui nous permettent d’insérer des logs sans redéployer l’application ni écrire du code !)

Les snapshots sont téléchargeable et peuvent être rejoués dans Visual studio.

  • Application Insight Profiler

Outil pour analyser et améliorer les applications déployés dans Azure pour plus détails voir https://azure.microsoft.com/en-us/blog/app-insights-app-map-and-profiler/

#UWPXAML – Compiled Binding – What’s new in the Anniversary Update?

Coming this summer, Windows 10 Anniversary Update will be more or less a Windows 10 v2.0.
With it comes a lot of new things for the windows app development, and a lot of new features and fixes for Compiled Binding.

Today we’ll see what those new features are and how to use them.

If you want to try them out yourself, you’ll need a Windows Insider build of Windows 10 with its Windows SDK and create a UWP project targeting a min version at least equals to Build 14383. Do not install it on your main work station, it will break any non-Anniversary Update apps.

For this post, I’ll use Windows 10 Build 14383 (available on Fast Ring) with Visual Studio 2015 Update 3.
The Windows SDK for Build 14383 can be found here: https://insider.windows.com/

In case you missed it, I wrote a few posts about compiled binding in the past.
Feel free to read them (again).

 

Function binding

Previously, it was possible to directly bind events to methods which followed specific rules regarding their parameters, but we were unable to bind the result of a method to a property without a converter which was calling the method for us.

Now, it’s possible to bind methods directly to properties without the need for a converter!
You can provide whatever method you like as long as it has a public accessor and you provide the parameters.

MainPage.xaml.cs

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
    }

    public string GetHelloWorld()
    {
        return "Hello World";
    }

    public Person Roberts = new Person()
    {
        Firstname = "Dread Pirate",
        Lastname = "Roberts"
    };
}

Person.cs

public class Person
{
    public string Firstname { get; set; }
    public string Lastname { get; set; }

    public string GetFullname()
    {
        return $"{Firstname} {Lastname}";
    }
}

MainPage.xaml

<TextBlock Text="{x:Bind GetHelloWorld()}" />
<TextBlock Text="{x:Bind Roberts.GetFullname()}" />

The method can have parameters.
You can provide them by setting constants in the XAML or by using data from your ViewModel.

MainPage.xaml.cs

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
    }

    public DateTime Today = DateTime.Now;

    public Person Someone = new Person()
    {
        Firstname = "Some",
        Lastname = "One"
    };        

    public string GetPersonFullname(Person person)
    {
        return person.GetFullname();
    }
}

MainPage.xaml

<TextBlock Text="{x:Bind Today.ToString('d', {x:Null})}" />
<TextBlock Text="{x:Bind GetPersonFullname(Someone)}" />

Does the binding is automatically updated when the data is updated?
Well, it is said to work if you set the Mode of the compiled binding to OneWay/TwoWay but I wasn’t able to compile it under VS2015. A few not really understandable compile errors appeared when I used TwoWay binding.

Along that, you may notice some errors appearing in the Error list when using parameters inside your binded functions stating « A value does not fall within the expected range ». It’s a bug of VS2015, but it compiles and runs fine anyway.

I hope those annoying errors will be fixed in the release version.
 

Dictionary indexers

As part of supporting most use cases without the need for a converter, x:Bind now supports access to a specific key in a dictionary.

MainPage.xaml.cs

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
    }

    public Dictionary<string, string> Dictionary = new Dictionary<string, string>()
    {
        { "A", "Alpha" },
        { "B", "Beta" },
        { "C", "Charlie" },
    };
}

MainPage.xaml

<TextBlock Text="{x:Bind Dictionary['A']}" />
<TextBlock Text="{x:Bind Dictionary['B']}" />
<TextBlock Text="{x:Bind Dictionary['C']}" />

It works great but there is a big shortcoming: You can only use constant strings directly set in the XAML.
Using anything else than a string, like an integer, will result in a compile error.
Even string data from your ViewModel won’t work.
 

Explicit value cast

Contrary to classic Databinding which uses duck typing to check if the binding is valid, compiled binding checks at compile time that the given data matches the property to which it is binded to.
In other words, if the value you’re trying to bind has no implicit cast to the type of the property, you can’t bind it using x:Bind without a converter.
Even if the value’s type declares an explicit cast…

As of the Anniversary Update, you will be able to declare an explicit cast inside a compiled binding, C#-style.

MainPage.xaml.cs

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
    }

    public bool? IsThreeStateNull = null;
}

MainPage.xaml

<CheckBox Content="IsThreeState = False" IsThreeState="{x:Bind (x:Boolean)IsThreeStateNull}" />

When casting explicitly, you’ll need to refer to the class type by its XAML namespace.
In this case, Boolean is part of the « x: » namespace declaration.
 

Implicit Visibility conversion

Who don’t know the legendary BooleanToVisibilityConverter?
Everyone, since the first time WPF came around, implemented it over and over in every projects.

x:Bind no longer requires that, it now converts booleans to Visibility by itself! Hurray!
You just need to bind a boolean to a property like Visibility.

MainPage.xaml.cs

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
    }

    public bool IsVisibleFalse = false;
    public bool IsVisibleTrue = true;
}

MainPage.xaml

<TextBlock Text="I'm not visible!" Visibility="{x:Bind IsVisibleFalse}" />
<TextBlock Text="I'm visible!" Visibility="{x:Bind IsVisibleTrue}" />

 

Conclusion

You can find a sample project on GitHub regrouping all the examples we saw in this post: http://github.com/TimLariviere/CompiledBinding-AnniversarySample

Écriture/lecture/modification de fichiers dans un projet Universel app/UWP et cordova

Dans nos applications, nous avons pris le parti d’écrire nos fichiers en JSON. Nous avons donc conçu une abstraction (en WinJS, avec un système de promises) qui nous permet d’utiliser des méthodes claires et simples sur toutes les plateformes (WinRT/UWP ou Cordova (iOS/Android) )

Ce module « DataContainer » est disponible dans notre libraire WinJSContrib (Github)

Dans WinJSContrib.DataContainer, nous avons 4 fichiers qui exposent les mêmes méthodes avec des implémentations différentes :

  • read : lecture d’un élément
  • save : enregistrement d’un élément
  • remove : suppression d’un élément
  • list : liste des fichiers d’un container
  • child : création/accès container enfant

Dans une application WinRT/UWP nous allons naturellement utiliser la couche WinRT/UWP pour écrire/lire les fichiers. Pour cela il suffit d’inclure le fichier « winjscontrib.datacontainer.winrt.file.js »

Dans une application cordova IOS ou Android, nous avons plusieurs choix :

  • Utiliser une base de données : winjscontrib.datacontainer.cordova.database.js
  • Utiliser le système de fichiers avec le plugin file : « winjscontrib.datacontainer.cordova.file.js »
  • Utiliser le localStorage : « winjscontrib.datacontainer.localstorage.js » (utilisable en WinRT aussi)

Ensuite, il faut instancier un container parent et l’utiliser partout dans l’application.

Dans le JS des applications Windows 8/Phone il suffit d’instancier le container (dossier) parent :

MyApp.Data.container = new WinJSContrib.DataContainer.WinRTFilesContainer(undefined, { logger: WinJSContrib.Logger });

Et changer WinRTFilesContainer par notre choix (CordovaDatabaseContainer par exemple) pour l’application cordova en faisant attention de ne l’appeler qu’après l’enclenchement de l’évènement deviceready.

Et c’est tout, la magie s’opère à l’intérieur de notre librairie 🙂

Quelques exemples d’utilisation :

  • Pour lire un fichier :
  • Data.container.read(&quot;objKey&quot;).then(function (data) { }, function (error) { });
    
  • Supprimer un fichier :
  • Data.container.remove(&quot;objKey&quot;).then(function () { }, function (error) { });
    
  • Enregistrer un fichier :
  • Data.container.save(&quot;objKey&quot;,obj).then(function () { }, function (error) { });
    
  • Accès à un container enfant (sous dossier) avec la lecture d’un fichier fichier :
  • Data.container.child(folderid).read(&quot;subObjKey&quot;).then( function (subObjInFolderID) { }, function (error) { }));
    
  • Liste des fichiers dans un container :
  • Data.container.list().then(function (res) {}, function (error) { });
    

Auditing your Windows Javascript UWP application in production

Since the launch of Windows 8, I’m writing native Windows applications using HTML and JavaScript, for the Windows store and for enterprise applications. Believe it or not but I’m doing it full time and, so far, I’m really enjoying it. I know many people will disagree, especially in the Windows ecosystem, but I’m really enjoying the productivity and the expressiveness you get by writing rich client applications using HTML. And the beauty with Windows 8, and now Windows 10, is that you have full access in JavaScript to the Windows API, from rich file access, to sensors, Cortana integration, notifications, etc.

Even better, with Windows 10 and the Universal Windows Platform (or UWP) you could write one single application using HTML and JavaScript that will run on Windows desktop, laptop, tablet, phone, IoT devices, Xbox, Hololens and probably much more.

If you are familiar with the web ecosystem, you could also very easily reuse most or all of your skills and application code and use it to build awesome websites, or target other devices, with Github electron to make a Mac OsX version, or use Cordova or React native to reach iOS or Android. It really is an exciting time for web developpers.

As exciting as those experiences have been, there are a few things that are still frustrating. No matter what technology you use for development, one of them is the ability to detect and troubleshoot problems when your application have been released into the wild. Visual Studio is really great and provide many tools to help debug and audit your app on your dev box, but for troubleshooting applications in production, you’re naked in the dark.

Luckily when using web technologies, you could use some wonderful tools like Vorlon.js. This tool is really great because you could target any device, without any prerequisite. You have nothing to install on the client to have great diagnostics from your app.
I previously explained how to use Vorlon.js in production, and how to use it with your JavaScript UWP, follow those post if you want to setup the stage. In this post, we will see an overview of what you can achieve with Vorlon.js for a Windows UWP app in production, and a few guidance. What we will see is not specific to a JavaScript UWP. You could use the same things to debug a Webview in a C# or C++ application.

Inspect the DOM

Vorlon.js is designed from the ground with extensibility in mind. It features many plugins, and you could really easily write your own (we will talk more on that later). One of the most usefull for frontend applications is the DOM explorer. It’s very much like the tools you will find in the developper tools of your favorite browser.
For troubleshooting issues in production, it is very interesting to see what appened into the DOM, what styles are applyed, check the current size of the user screen, etc.

domexplorer.jpg

 

Watch the console

Another core plugin of Vorlon is the console. It will shows all console entries in your dashboard. If you put meaningful console logging into your app, this plugin is insanely usefull because you see in (almost) realtime what the user is doing, which is key to reproduce the issue. With some luck (and coding best practices), you could also have errors popping directly in the console with the stack trace (if the Promise god is with you). The console also feature an « immediate window » where you could issue simple JavaScript commands.

console.jpg

Check objects value

You could also have access to global JavaScript variables using Object explorer. This plugin allow you to watch values from your objects, and explore graph of objects. It’s always interesting to be able to keep an eye on your application state when trying to troubleshoot your application.

objexplorer

Monitoring CPU, memory, disk, …

You sometimes have to face more insidious bugs, like memory leaks, that usually requires advanced debugging tools. In the comfort of your dev box, you could use IDEs like Visual Studio to diagnose those bugs with specific tools. Modern browsers usually have similar tools, but does not have APIs to check things like memory or CPU that you could use remotely. Fortunately, when you are targeting Windows UWP, you could have access to all modern Windows APIs, and especially those about diagnostics.

That’s why the Vorlon team implemented a plugin specific to Windows UWP. It uses WinRT APIs for diagnostics and for different metadata from the client. For now, this plugin is not released, and you will have to look at the dev branch to try it out.

uwp.jpg

From the application metadata, you will get infos, such as its name, but also the application version, current language, and device family.

uwpmetadata

You will also have a glimpse at the network kind and status, and the battery level of the device.

It enables you to monitor the CPU, the memory and disk I/O. It’s especially usefull to track memory leaks, or excessive resources consumption.

uwpmemory.jpg

And much more…

You have many more plugins within Vorlon that will help you diagnose your app, monitor xhr calls, explore resources like localstorage, check for accessibility and best practices, and so on. We cannot cover them all in one post, but I hope you get a decent idea of the many possibilities it is unlocking to help you improve your applications, both during development and more than anything, in your production environment. It’s especially usefull for mobile applications such as Windows UWP.

Writing plugin for Vorlon.js is really easy. You have to implement one javascript class for the client, and one other for displaying results in the dashboard. Writing a simple plugin can sometimes helps you save a lot of time because it can helps you analyse the problem when and where they occur. If you are proud of your plugin, submit it back to Vorlon.js !

Using Vorlon.js with your Windows 10 JavaScript UWP

Vorlon.js is a great tool for diagnosing and auditing any application built with web technologies, and Windows JavaScript applications, or UWP are no exception. It means you could use Vorlon to diagnose your app running on PC, tablet, phone, Xbox, Hololens, Raspberry Pi and any device supporting Windows IoT.

However, for being able to use Vorlon.js in a UWP, you will have to configure your application sandbox to enable communication between your app and Vorlon.js server (or desktop app).

In this post, we will illustrate the different aspects for a packaged application (a JavaScript application that embeds pages, scripts, styles, …) because it is the most complicated, but what we will see here will work equally well for a hosted app (an app where pages, scripts and styles are hosted on a web server). In fact, what we will see here could also help you using Vorlon.js in a webview for a C# application.

Put your application in web context

This step is very specific to packaged applications. Packaged applications runs in a very specific security context where resources can only be loaded from inside your package. It means that you cannot use a script tag which « src » attribute points to a resource outside of your package.

For using Vorlon, you will have to force your app into a web context, allowing you to use alien resources. Be aware that doing this is a weakpoint in your app’s sandbox. It’s not a major one but do it only if you have the need to.

Putting your app in web context is very easy. You just need to update a couple entries in the manifest of your application.

First, you must change your start page. If your start page is named « default.html », replace it with « ms-appx-web:///default.html ». You could do it by editing the appxmanifest.xml, or by opening your manifest within Visual Studio.

startpage

In application context, you have access to WinRT API, but not in web context. To bring it back; you must add your start page to Content URIs. Again, you could do it manually in your manifest or with Visual Studio. Go to the content URIs tab and add a URI to « ms-appx-web:///default.html ». Don’t forget to enable WinRT by choosing « All » in « WinRT Access ».

contenturi

Allow your Vorlon.js client script

Now we must allow our app to access Vorlon.js client script. This step is required for packaged and hosted JavaScript UWP, or if you want to use Vorlon in a webview in a C# app.

First you must take note of your Vorlon.js server URI, and add it to the content URIs for your app. I will use a local Vorlon instance running on localhost on port 1337.

Open your manifest with Visual Studio and go to the Content URIs tab. Add Vorlon server URI to the list. In my case, I must add « http://localhost:1337 &raquo;.

contenturi2

Enjoy !

You are ready to go, just start your Vorlon server and your app. If you have followed the steps above, you are now able to inspect your app. The screen capture bellow shows the WinRT API with object explorer !

vorlon

If it’s not working properly, look for messages in the console in Visual Studio. You probably have misspelled some URI and errors should show up there.

Happy Vorlon.js 🙂

 

#UWPXAML – Compiled Binding – Incremental rendering with x:Phase

Coming with Windows 10 are a lot of new features especially for XAML when creating a Universal Windows Platform application aka. UWP app. We can mention a few of them: new controls (as the RelativePanel, the SplitView and more); new tools for building responsive and adaptive UI (AdaptiveTrigger, Extension SDKs, etc.); and a new way to bind data to the UI, Compiled Binding.

This series on Compiled Binding will be composed of several parts:

 

Dealing with long list of data

You often have to work on apps that have a great deal of data. Those data are best displayed on list when they’re of same type, and you generally want to let your users scroll through it without noticeable performance issues.

To enable this, virtualized lists have been created.

Only a handful of items, that are visible to the user, are rendered at the same time while other items are simply not rendered at all. When the user scrolls through the list, rendered items are recycled to match where the user is in the list, thus keeping your memory usage low while still giving to your user what he needs.

This gives your users the illusion that your app is fast.

But sometimes, your items’ DataTemplate can be complex and when the user scrolls through the list, the CPU might not keep up and fully render new items in time. In that case, the list will display placeholder items until rendered items are ready. A quirky user experience may result from that.

To help you have more control on how to optimize the rendering of your items in those circumstances, Windows 8.1 added the event ContainerContentChanging allowing you to progressively render your items in a ListViewBase-derived control.
 

ContainerContentChanging event

The idea behind ContainerContentChanging is quite simple. By handling that event, you can progressively render the items that are visible to the user. This is done by using phases.

Let’s say that you have a list of books, each with a title, a subtitle and a description.
The most important information of your books is the Title property, so it must be displayed whenever possible. The Subtitle property is important but not crucial for the user experience while the Description property is not important.

With the ContainerContentChanging event, you can delay the rendering of the Subtitle and Description properties to later, when the CPU will be more available. The event is called multiple times if necessary, for each pair of container / data that need to be rendered.

Each time the event is raised for the same container / data pair is called a phase. The phase number is provided through the ContainerContentChangingArgs parameter, Phase property.

You can then check the phase number to decide which information should be loaded according to your importance scale.

There we can decide to let the Title property on Phase 0, the Subtitle property on Phase 1 and the Description property on Phase 2.

Phase 0 will be part of the first rendering of the item, while Phase 1 will be done once all current items’ Phase 0 have been rendered, and so on until all phases of all items are done.

Here’s an example that can be found on MSDN:
ListView and GridView UI optimization

XAML

<Page
    x:Class="LotsOfItems.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:lotsOfItems="using:LotsOfItems"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <GridView ItemsSource="{x:Bind ViewModel.ExampleItems}" ContainerContentChanging="GridView_ContainerContentChanging">
            <GridView.ItemTemplate>
                <DataTemplate x:DataType="lotsOfItems:ExampleItem">
                    <StackPanel Height="100" Width="100" Background="OrangeRed">
                        <TextBlock Text="{x:Bind Title}"/>
                        <TextBlock Opacity="0"/>
                        <TextBlock Opacity="0"/>
                    </StackPanel>
                </DataTemplate>
            </GridView.ItemTemplate>
        </GridView>
    </Grid>
</Page>

C#

namespace LotsOfItems
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            this.ViewModel = new ExampleItemViewModel();
        }

        public ExampleItemViewModel ViewModel { get; set; }

        // Display each item incrementally to improve performance.
        private void GridView_ContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
        {
            if (args.Phase != 0)
            {
                throw new System.Exception("We should be in phase 0, but we are not.");
            }

            // It's phase 0, so this item's title will already be bound and displayed.

            args.RegisterUpdateCallback(this.ShowSubtitle);

            args.Handled = true;
        }

        private void ShowSubtitle(ListViewBase sender, ContainerContentChangingEventArgs args)
        {
            if (args.Phase != 1)
            {
                throw new System.Exception("We should be in phase 1, but we are not.");
            }

            // It's phase 1, so show this item's subtitle.
            var templateRoot = args.ItemContainer.ContentTemplateRoot as StackPanel;
            var textBlock = templateRoot.Children[1] as TextBlock;
            textBlock.Text = (args.Item as ExampleItem).Subtitle;
            textBlock.Opacity = 1;

            args.RegisterUpdateCallback(this.ShowDescription);
        }

        private void ShowDescription(ListViewBase sender, ContainerContentChangingEventArgs args)
        {
            if (args.Phase != 2)
            {
                throw new System.Exception("We should be in phase 2, but we are not.");
            }

            // It's phase 2, so show this item's description.
            var templateRoot = args.ItemContainer.ContentTemplateRoot as StackPanel;
            var textBlock = templateRoot.Children[2] as TextBlock;
            textBlock.Text = (args.Item as ExampleItem).Description;
            textBlock.Opacity = 1;
        }
    }
}

As you can see, our DataTemplate contains three TextBlocks: one for the Title property, one for the Subtitle property and one for the Description property.

Title being the most important, the control is already databound in the DataTemplate while the others are simply not set and are even hidden from users with Opacity at 0.

Then we add an event handler to the ContainerContentChanging event of the GridView.

When the event is raised in GridView_ContainerContentChanging method, it is Phase 0, the book’s title is rendered.

x:Phase
 

To notify that we expect another phase to occur, we register an update callback through the ContainerContentChangingArgs.RegisterUpdateCallback method. In that callback, that will be called once all items’ Phase 0 are done, we retrieve the second TextBlock control to load its content, the book’s Subtitle, and display it by setting the Opacity to 1.

x:Phase
 

Once it’s done, we register for a third phase to display the book’s description.

x:Phase
 

If the user has scrolled past too many items and the list control wants to recycle containers before we have rendered all the phases, ContainerContentChanging is no longer called for these container / data pairs and the containers are recycled for other data, thus ending the rendering of those previous items.

While ContainerContentChanging is simple to use, its implementation can be quite tedious. Even more when you need to change the DataTemplate over the course of development, you found yourself re-implementing it over and over.

There comes to the rescue {x:Bind} and its x:Phase attribute.
 

Simplifying ContainerContentChanging with x:Phase

Based on the ContainerContentChanging event, x:Bind introduces a shortcut notation to use those rendering phases: x:Phase.

It uses the exact same principle that we’ve seen on the last example, except you don’t have to implement ContainerContentChanging. It’s done for you by code-generation when using {x:Bind}.

To use it, it’s really simple. Just set the x:Phase attribute on an {x:Bind} databound control.

XAML

<GridView ItemsSource="{x:Bind ViewModel.ExampleItems}">
    <GridView.ItemTemplate>
        <DataTemplate x:DataType="lotsOfItems:ExampleItem">
            <StackPanel Height="100" Width="100" Background="OrangeRed">
                <TextBlock Text="{x:Bind Title}"/>
                <TextBlock Text="{x:Bind Subtitle}" x:Phase="1"/>
                <TextBlock Text="{x:Bind Description}" x:Phase="2"/>
            </StackPanel>
        </DataTemplate>
    </GridView.ItemTemplate>
</GridView>

As we’ve seen with ContainerContentChanging, the higher the phase number, the later the control will be rendered. If no phase is set, it’ll be 0 by default.

Note: Those phases don’t have to be contiguous with x:Phase.

In this case, the CPU will try to render the book’s title, then the book’s subtitle and finally the book’s description instead of trying to render them all at once and failing to keep up with the scroll applied by the user.

When the control’s phase is not yet reached, they are set to Opacity=0 thus hiding them. When their phase is reached, the compiled binding is resolved and the controls are displayed.

The result is the same but it is less tedious to implement. You just have to set an attribute on the databound control as opposed to doing a whole implementation of the ContainerContentChanging event.

Later, if you need to change the DataTemplate, it will be way easier.

Just one thing, x:Phase needs x:Bind in order to work. If not present, x:Phase will simply be ignored. So if you need to delay the rendering of a not-databound control, you still have to use the ContainerContentChanging event, that also applies if you need more than just hiding a control for a time.
 

Going further

MSDN
« x:Phase attribute »
https://msdn.microsoft.com/en-us/library/windows/apps/mt204790.aspx

MSDN
« ListView and GridView UI optimization »
https://msdn.microsoft.com/en-us/library/windows/apps/mt204776.aspx

Channel 9
« Improving XAML performance »
https://channel9.msdn.com/Events/Windows/Developers-Guide-to-Windows-10-RTM/Improving-XAML-Performance

Build 2015
« Data Binding: Boost Your Apps’ Performance Through New Enhancements to XAML Data Binding » https://channel9.msdn.com/Events/Build/2015/3-635