La vraie nature de WinRT

La semaine dernière, Microsoft organisait un évènement dénommé Build Windows, dans le but de faire la lumière sur la dernière version de Windows, nom de code Windows 8, prévu pour débarquer l’année prochaine. Lors de cet évènement, MS en a profité pour dévoiler un nouveau type d’application pour Windows : les applications Metro, orientées grand public et basées sur une nouvelle couche logicielle dénommée Windows Runtime alias WinRT.

Depuis, on peut entendre beaucoup de bruit sur la véritable nature de WinRT : est-ce que WinRT remplace Silverlight ? WPF ? Win32 ? A tel point que cela en devienne assez dur de comprendre le concept, pourtant très simple et très puissant à la fois. Heureusement plusieurs bons articles sont apparus sur la toile pour expliquer qu’est-ce que WinRT et comment il va fonctionner conjointement avec le reste du système d’exploitation. Cet article va donc essayer d’expliquer ce qu’est véritablement WinRT et pourquoi le concept est si puissant !

Windows 8, le premier Windows schizophrène

Comme le faisait remarquer Mary Jo Foley sur son blog All About Microsoft, c’est que s’il y a bien une slide que tout le monde gardera en mémoire du Build, c’est celle-ci, qui représente l’architecture des applications pour Windows 8.

Ce qui est intéressant ici est la séparation entre les Metro Style apps, les fameuses applications développées exclusivement pour Windows 8, et … tout le reste ! Oui la partie droite en bleu représente l’intégralité des applications existantes ! Cela aurait d’ailleurs dû couper court à toutes les discutions de mort de Silverlight / .NET : tout cela sera présent dans Windows 8 comme c’est le cas dans Windows 7 !

Comment dans ce cas, vont cohabiter les différentes applications ? Quel est l’intérêt de créer un nouvel écosystème applicatif, quand on a déjà, et de loin, le plus vaste ?

Et bien tout simplement, parce que Windows 8 a deux personnalités ! Une personnalité qu’il a héritée de son père Windows 7, qui reprend toute la partie bureautique de Windows (bureau, barre de lancement rapide, icônes, fichier, et ainsi de suite), et une personnalité qu’il a hérité de son lointain cousin Windows Phone 7 (je ne veux pas savoir comment c’est arrivé !), qui instaure pour la première fois dans Windows une interface très très très orientée grand public, avec les fameuses live tiles, notifications, et les applications sans chrome qui mette l’accent sur le contenu, la typographie, l’expérience utilisateur… Attendez mais ça me rappelle quelque chose !

Effectivement, cela défini parfaitement Metro, cet ensemble de règles qui font qui ont permis de créer une toute nouvelle expérience utilisateur sur Windows Phone, comme je l’avais décrit l’année dernière dans cet article : https://sebastienmornas.wordpress.com/2010/08/29/qu-est-ce-que-metro/ Et c’est effectivement un bien bel exemple d’interface Metro que nous a présenté avec le nouveau « Start screen » de Windows 8, qui remplacera donc le menu démarrer qui était apparu avec Windows 95 ! Ils nous avaient prévenus, Windows 8 est un tournant dans l’histoire de Windows !

Nous y voilà, Windows 8 aura donc deux facettes, une classique qui sera un Windows 7 amélioré, et une qui transforme le PC en grand Windows Phone. Qui a dit « tablette » ? Bien évidemment le but avoué de Windows 8 est de conquérir le marché des tablettes tout en conservant celui des ordinateurs. Cette interface Metro est ainsi une aide précieuse pour faire adopter Windows aux tablettes, car bien qu’elle soit prévue pour être utilisée autant à la souris / clavier qu’aux doigts, on imagine sans mal que le tactile sera notre moyen favoris pour naviguer dedans !

WinRT, un composant phare de Windows 8 Metro

Une des nouveautés de Windows 8 est également sa compatibilité avec l’architecture ARM, qui n’était pas supporté jusqu’à Win8. Cela rentre aussi dans la stratégie de pousser Windows sur tablette, un secteur où les processeurs x86 sont présents, mais pas dominants. Seulement voilà, comment porter toutes les applications natives de Windows sur ARM, sachant que le jeu d’instruction est sensiblement différent ? En un mot : impossible (ou plutôt « trop contraignant » mais ça faisait deux mots).

C’est pour cela que Microsoft a besoin de constituer un nouvel écosystème d’applications résolument orienté vers le grand public, en plus de son écosystème d’applications existantes ; le but étant également que toutes ces nouvelles applications soient autant utilisable à la souris que via un écran tactile. Oui je parle bien des applications Metro, qui pourront fonctionner de la même manière sur toutes les versions de Windows 8 de la même manière, même sur un système ARM. Pour cela, pas besoin de compiler son application pour plusieurs architectures, c’est une toute nouvelle couche logicielle qui permettra aux applications Metro de communiquer avec l’OS : le Windows Runtime.

Je pense que ce n’est que maintenant, après avoir compris le contexte derrière Windows 8 que l’on peut réellement saisir ce qui se cache derrière le diagramme présenté au début de l’article. Dans le schéma présenté au début de l’article, WinRT est une couche qui descend aussi bas que Internet Explorer, Win32 et .NET / Silverlight ; pourquoi ?

Parce que WinRT n’est pas une couche de plus qui s’insère entre deux couches existantes, bien au contraire, c’est une couche entièrement indépendante de Win32, qui discute directement avec l’OS sans intermédiaire ! C’est en ce sens que Paul Thurrott écrit son article WinRT is replacing Win32, bien que pour moi cela soit faux : WinRT est une alternative, pas un remplacement !

Mais WinRT ne s’arrête pas au niveau de Win32, mais qui monte également plus haut, incorporant une partie des blocs HTML / JavaScript, C / C++ et C# / VB.NET, et il y a une raison à cela : WinRT permet d’écrire des applications via des langages natifs (C/C++), managés (C#/VB.NET) et même web (HTML/JavaScript), et contient donc des mécanismes pour pouvoir utiliser les mêmes APIs depuis tous les langages supportés (nous y reviendront plus tard).

WinRT, en soit, est composé d’un grand nombre d’APIs, qui ressemble grandement à des APIs .NET, et qui sont accessibles aux trois langages. Magique ? Non. Ingénieux ? Certainement ! Derrière ce sont des APIs bas niveaux, entièrement développée en C++, pour s’assurer une performance maximale, mais qui sont exposées en utilisant un format de métadonnées standardisée par Microsoft (ECMA 335 pour les puristes, et oui, c’est les mêmes métadonnées utilisées par le .NET Framework !), ce qui permet d’utiliser de la réflexion, des langages dynamiques, etc.

En ce qui concerne la partie graphique, WinRT contient également toutes les mécaniques pour écrire des interfaces en XAML, comme on le ferait pour écrire des interfaces Silverlight ou WPF. C’est en cela que Silverlight et WinRT + XAML se ressemble beaucoup. Mais derrière, c’est très différent. La partie graphique de WinRT est entièrement exécuté par DirectX, de manière native, ce qui assure des performances à hauteur et un support encore plus abouti du GPU. Comme DirectX est extrêmement présent dans WinRT, cela promet également de pouvoir écrire des jeux DirectX encore moins couplé au matériel.

Les wrappers JavaScript et C# / VB.NET

Si les APIs de WinRT sont écrite en C++, on peut comprendre qu’utiliser WinRT depuis C++ est assez naturel. En revanche, comment peut-on l’utiliser depuis JavaScript ou les langages basés sur .NET ?

Pour ce qui est du C# et du VB.NET, le principe est le même que le P/Invoke couramment utilisé par les développeurs .NET pour appeler des méthodes définie dans les DLL du système. Le principe, mais pas la syntaxe, car pour consommer un objet WinRT, il suffit de l’instancier comme n’importe quel objet .NET et de l’utiliser de la manière la plus managée qui soit. Fantastique ! Mais en ce qui concerne le reste du Framework ? Pas d’inquiétude, le CLR 4.5 sera là pour exécuter notre code managé, mais sera simplement restreint pour ne pas utiliser les APIs bas-niveau du Framework (par exemple la gestion de fichiers). Miguel De Icaza, le papa du projet Mono, a justement écrit un excellent article sur WinRT à ce propos.

Pour ce qui est de JavaScript et HTML, il faudra passer par une bibliothèque JavaScript nommée WinJS, qui ne fonctionnera que dans Windows 8 (pas sur le web, ce qui est normal) et qui offrira les mêmes APIs que pour .NET / C++ dans un style résolument plus JavaScript. Le code JavaScript, ainsi que l’interface HTML5 / CSS3 sera interprété par le même moteur de rendu / exécution de script que IE10, bien que l’application ne soit pas vraiment exécutée par ledit navigateur.

Pour conclure

Windows Runtime, je ne sais pas de qui c’était l’idée, mais c’est une fort bonne idée ! Avec WinRT, il est possible de faire des applications avec le style d’écriture .NET (et la productivité qui va avec), tout en manipulant des objets natifs sans le savoir, ce qui augmente sensiblement les performances. Plus important encore, WinRT permet de fédérer l’écriture d’applications pour la plateforme Windows, le but étant de recréer un écosystème d’application modernes, fluide et intuitives. J’ai hâte d’y être !

Contrôles personnalisés et templates en Silverlight

Lorsque l’on débute en Silverlight, on a tendance à utiliser des UserControl (littéralement contrôles personnalisés) pour personnaliser ses contrôles ; c’est vrai que le nom UserControl laisse à penser que c’est le cas d’utilisation parfait. Cependant, la classe UserControl permet de créer un regroupement de contrôles et pas n’est pas forcément idéale pour un contrôle générique, réutilisable et pouvant être stylisé.

En revanche, il existe une technique pour créer un contrôle qui possède tous ces attributs : le mécanisme de Template de Silverlight et le fichier generic.xaml. Dans cet article je vous propose de voir en quelques étapes comment créer un tel contrôle, en prenant l’exemple du contrôle HeaderedContentControl, que l’on peut trouver dans le Silverlight Toolkit, mais qui est absent de la version Windows Phone.

L’exemple

Le contrôle HeaderedContentControl est un contrôle qui sert de conteneur à un contenu (propriété Content) et qui est caractérisé par un entête (Header). Bien que l’implémentation visuelle du HeaderedContentControl pourrait être faite de nombreuses manières différentes, j’ai fait le choix de m’inspirer des écrans de paramétrage de Windows Phone OS, dans lesquels on voit pour chaque option un titre. Comme on le verra également, redéfinir l’aspect visuel d’un contrôle templaté est une tâche particulièrement aisée et succincte.

Etape 1 : choisir la classe de base

Lors de la création d’un contrôle templaté, il est possible de partir de n’importe quelle classe non sellée (sealed) du Framework et de l’étendre. Pour un contrôle qui n’aurait rien en commun avec les autres contrôles, on pourrait partir de la classe Control.

Néanmoins, certaines classes sont là pour encapsuler une partie du comportement désiré par notre contrôle étendu – pas besoin de réinventer la roue donc ; ici on a besoin d’afficher du contenu ; il existe justement une classe nommée ContentControl, qui prévoit justement l’utilisation d’un contenu. Si on avait voulu afficher des éléments, on serait parti de la classe ItemsControl, et ainsi de suite.

Pour commencer il suffit donc de créer une nouvelle classe dans votre projet Silverlight / Windows Phone, puis de la faire dériver de la classe de base qui va bien, ici ContentControl.

Etape 2 : ajouter des propriétés

Une fois la classe créée, on peut à présent ajouter des Dependency Properties, qui vont constituer la valeur ajoutée par votre contrôle. Une Dependency Property est une propriété qui en plus d’être définie dans la classe, nécessite d’être enregistrée afin de pouvoir être utilisée depuis du Binding.

Dans notre cas, on veut ajouter l’entête du conteneur. On pourrait créer cette propriété sous forme de chaîne de caractères, mais ce qui paraît encore plus intéressant est de la définir en tant qu’Object ; ainsi il sera possible de mettre n’importe quel objet en tant qu’entête et ainsi de l’afficher par le biais d’un convertisseur ou du HeaderTemplate, une autre propriété de type DataTemplate que nous allons exposer pour personnaliser l’affichage de l’entête.

Il est également possible d’ajouter des évènements ou des méthodes, et de s’inscrire aux évènements déjà présents dans la classe ContentControl, afin d’ajouter du comportement à notre classe, mais nous n’exploreront pas cette possibilité dans cet article.

Etape 3 : définir le template par défaut

Maintenant que toutes les propriétés sont prêtes à être utilisées, il nous faut encore décrire le template par défaut, utilisé quand aucun template personnalisé n’est là pour le surcharger. C’est logiquement du code XAML que nous allons écrire pour définir ce template car il s’agit de la description de l’interface. Le code XAML sera mis dans un fichier nommé generic.xaml situé dans le répertoire Themes. Attention, l’emplacement exact du fichier est important, car c’est un fichier spécial, utilisé uniquement dans le cas de contrôles templatés.

Pour définir le contrôle, nous allons tout d’abord ajouter le namespace XML dans lequel il est défini :
xmlns:controls=”clr-namespace:Controls”

Nous pouvons ensuite créer un style dont le type ciblé est notre classe HeaderedContentControl. A l’intérieur de ce style, nous allons définir les valeurs par défaut de propriétés telles que Background, ForeGround, Horizontal/VerticalContentAlignment, etc. qui seront utilisé si ces propriétés ne sont pas changées explicitement.

Enfin nous allons définir, par le même biais, la propriété ControlTemplate qui représente l’aspect visuel du contrôle. Ici cette partie est extrêmement simple, une Grid comportement 2 lignes, l’une pour l’entête et l’autre pour le contenu, mais il pourrait bien plus complexe, avec par exemple l’utilisation du VisualStateManager, qui permet de faire des contrôle templatés à états (par exemple l’état sélectionné ou non d’une CheckBox) et animés.

Ce qu’il faut tout de même remarquer, est l’utilisation du TemplateBinding pour faire la liaison avec le contenu, l’entête et leur ContentTemplate respectifs. Le TemplateBinding est en fait un raccourci permettant de faire du Binding sur le contrôle templaté ; c’est l’équivalent de :
Content=”{Binding Header, RelativeSource={RelativeSource TemplatedParent}}”

Etape 4 : changer la DefaultStyleKey

Il ne reste plus qu’à préciser dans le constructeur de notre contrôle que le style par défaut est celui défini dans generic.xaml ; pour cela Silverlight passe par la propriété DefaultStyleKey. En lui donnant le type du contrôle comme clé, il va retrouver la bonne ressource et associé le code C# au code XAML.

Utilisation et surcharge du template

Il suffit maintenant pour utiliser notre contrôle flambant neuf d’ajouter le namespace XML et de remplir sa propriété Header et Content. C’est d’ailleurs ce même contrôle que j’avais déjà utilisé dans mon article précédent : Ajouter des éléments spéciaux dans une collection liée via binding

L’avantage de cette technique est que le Template est du coup très facile à changer, en particulier à l’aide de Microsoft Expression Blend : certain parlent par conséquent du caractère « blendable » du contrôle.

Dans Blend, en faisant un clic-droit sur le contrôle en question et en choisissant « Edit Template » puis « Edit a Copy… », l’outil crée une copie du Template que l’on peut éditer.

Une fois le Template créé, on peut facilement reporter la modification sur toutes les occurrences du contrôle, en utilisant la commande « Apply Resource ». On peut donc en quelque clics obtenir le résultat suivant :

Pour terminer on peut donc dire que la création d’un contrôle templaté, à priori moins immédiat que celle d’un UserControl, apporte plus de finesse dans le contrôle de l’apparence et est donc à prescrire pour les contrôles pensés pour être génériques et réutilisables.

Ajouter des éléments spéciaux dans une collection liée via Binding

Le Binding des technologies basées sur XAML (Silverlight / WPF) a constitué une grande avancée pour simplifier le découplage des données et de l’interface en apportant un contrôle poussé des données affichées dans la vue ainsi qu’une grande simplicité. Cependant certains rares cas de figures étaient plus faciles à implémenter avec les mécanismes de Binding pré-XAML.

Cet article présente l’un de ces cas, et une astuce pour le contourner, transparente pour l’utilisateur. La méthode exposée en est assurément une parmi tant d’autre mais je n’ai que trouvé peu de solutions sur la toile (sans doute me manquait-il les mots-clés magiques). Je vous présente donc la mienne, possiblement améliorable, et si vous avez une autre technique à ce même problème, n’hésitez pas à réagir via les commentaires !

Le problème

Nous sommes dans une application de test de gestion d’une bibliothèque (vous savez ces endroits où l’on peut trouver des ensembles de feuilles de papiers attachées les unes aux autres appelés « Livres »… Qu’importe c’est un exemple théorique). La vue permettant d’ajouter un nouveau livre comporte trois champs, dont une catégorie qu’il faut sélectionner dans une liste de choix.

Cette liste de choix, est dans cet exemple implémenté avec le ListPicker du Silverlight Toolkit pour Windows Phone. On a lié sa propriété ItemsSource à une collection Categories contenant les objets représentant les catégories, possiblement chargée elle-même depuis une base de données.

<toolkit:ListPicker ItemsSource=”{Binding Categories}” />

Seulement voilà, vous voulez gérer le cas où un livre n’a pas la catégorie proposée ! Quelles sont alors vos possibilités ?

  • Ajouter un enregistrement dans la base nommé « Aucune » est une solution peu intelligente car on serait en train de mélanger des catégories avec des non-catégories !
  • Mettre le SelectedIndex du ListPicker à -1 ; quand on ouvre la vue, il n’y a donc pas de catégorie de sélectionner. Cela fonctionne, mais si l’utilisateur choisi une catégorie, il ne pourra plus se rétracter, et sera condamné à fermer la vue et à la rouvrir ! Pas très ergonomique…
  • Ma solution : utiliser une classe pour étendre la classe utilisée dans la collection pour fournir des items spéciaux qui représentent des valeurs non liées. Tout un programme !

La solution

Un enum qui représente les types d’éléments spéciaux

Pour symboliser les éléments spéciaux nous allons créer tout d’abord un enum qui correspond à leurs types. Par exemple ici, j’ai mis les types suivants : aucun, tous et autre. Vous êtes libre d’en ajouter ou d’en enlever, ma solution est plus un pattern qu’un framework, et il vous faudra sans doute l’adapter à vos besoins.

La classe pour étendre les entités

Cette classe implémente le Design Pattern Decorator qui consiste à encapsuler un objet dans un autre objet pour lui ajouter des fonctionnalités. Ici on rajoute un attribut de type SpecialItemType qui est l’enum que nous avons déclaré plus tôt (c’est un Nullable pour pouvoir gérer le cas où l’élément n’a pas de type spécial).

A noter également que ma classe dérive de NotificationObject qui est apportée par Prism v4 pour Windows Phone (sur lequel je ferai un article plus complet plus tard). Globalement il sert uniquement à implémenter l’interface INotifyPropertyChanged et définit une méthode RaisePropertyChanged que l’on peut utiliser dans les setters de ses classes. Nous pouvons à présent utiliser cette classe dans la collection de catégories située dans notre ViewModel.

L’affichage des catégories et des non-catégories

Pour l’affichage nous sommes confrontés à un dernier problème : un élément à afficher de deux façons différentes selon le type d’objet. Heureusement ce problème-là, je l’avais déjà traité dans mon post : https://sebastienmornas.wordpress.com/2010/10/07/utiliser-un-datatemplateselector-en-silverlight/

Il faut créer un DataTemplateSelector qui choisit son template en fonction du caractère spécial de l’élément ou non. Pas de surprise dans mon implémentation, si ce n’est que cette fois j’utilise la classe DataTemplateSelector définie par Prism v4 (aucune différence avec la version que j’avais présentée dans mon article, mais au moins il n’y a plus besoin de la réécrire dans chaque projet !)

Enfin dans notre XAML, il ne nous reste plus qu’à utiliser ce DataTemplateSelector, comme ceci :

Et voilà : visuellement, on a bien ce qu’on s’attend à voir, et sous le capot, on voit que la catégorie est à null ce qui représente bien la notion de « aucune catégorie ». Certes la solution n’est pas immédiate à mettre en place, mais elle a le mérite de garder une architecture claire et propre et est très facilement adaptable et personnalisable.

Les 7 fautes à éviter lors du design d’une app WP7

Alfred Astort de l’équipe de l’équipe de « User Experience Design Lead » sur Windows Phone 7, a commencé une série de posts extrêmement intéressants sur le design d’applis sur le blog officiel de Windows Phone, où il reprend les erreurs les plus courantes à éviter lors du design d’une application WP7. Il en est actuellement à son septième article, et vous pourrez lire tous ces posts depuis cette page : http://windowsteamblog.com/windows_phone/b/wpdev/archive/2010/11/05/top-ten-things-to-keep-an-eye-on.aspx

Parce que je pense que les points qu’il aborde sont absolument inévitables pour tout développeur qui vise le Marketplace, je vous propose un article récapitulatif qui reprend les 7 premiers points. Les 3 suivants pourront également bénéficier d’un article étant donné qu’ils sont également particulièrement importants.

1. Icône de l’application

L’icône de l’application, visible sur le Marketplace ou sur l’écran de démarrage du téléphone, est la première chose de votre application que vos futurs-utilisateurs vont voir. C’est ce qui va faire qu’un utilisateur ne va peut-être ne même pas cliquer sur votre application. Vous pouvez avoir créé une magnifique application qui accompli sa tâche à merveille, si l’utilisateur ne vous donne pas votre chance, c’est beaucoup de travail
pour rien… C’est pour ça que l’icône d’application doit être au moins aussi soigné que tout le reste de l’application !

Sérieusement ? (Ou devrais-je dire Really ?) Ces applications ne donnent pas envie… du TOUT !

Premier conseil avisé de la part d’Alfred : faîtes vous aider d’un designer si vous le pouvez ! Honnêtement il n’y a pas photo, les designers ont quelque chose que nous, développeurs, n’avons pas. Maintenant il est vrai que nous n’avons pas tous la chance d’avoir un designer sous la main pour travailler le logo de notre application. Heureusement, en évitant certaines erreurs, même les moins graphistes pourront faire des icônes qui rendront l’utilisateur heureux :

  1. Eviter les typographies 3D : non, l’effet WordArt 3D n’est pas votre ami ! Pour rappel Metro c’est de la 2D dans un environnement en 3D (projections). La police 3D c’est du passé, point.
  2. Eviter les dégradés de couleurs : comme j’abordais le sujet dans mon article sur le dithering, les guidelines Microsoft déconseillent l’utilisation de dégradés, principalement parce que les écrans de certains Windows Phone les gèrent très mal et font des barres hideuses.
  3. Eviter les coins arrondis : Windows Phone n’est PAS iOS. Microsoft a décidé de faire quelque chose de différent de son concurrent fruité, et Metro c’est des formes droites et épurés. A éviter donc, même si Microsoft ne montre pas le bon exemple avec l’application Facebook officielle !
  4. Eviter les fonds noirs ou blancs : pour que l’on voie votre icône quel que soit le thème choisi par l’utilisateur, privilégiez n’importe quelle couleur sauf le noir et le blanc (qui ne sont d’ailleurs pas vraiment des couleurs)
  5. Eviter les formes ambigües : certains ont bien compris que l’icône doit être simple, pour continuer dans la lignée des applications natives de WP7. Pour cela je ne peux qu’être d’accord avec eux. Cependant il ne faut pas tomber dans l’extrême inverse et faire un icône qui n’a aucun sens, et dont on ne comprend pas l’utilité de l’application décrite.
  6. Faire une icône colorée sur fond transparent : il est possible de mettre de la transparence dans les icônes d’application, ce qui permet de remplacer la transparence par la couleur d’accent choisie par l’utilisateur. Cependant si vous faites ça et que votre icône est coloré vous risquez que ladite icône disparaisse dans le fond. Au lieu de ça, si vous choisissez une icône à fond transparent, la seule couleur que vous devez utiliser est le blanc. Cela vous donnera le même rendu que les applications natives.

2. Le clavier ne doit pas cacher les boutons

Ce conseil s’applique principalement aux fenêtres de login : les boutons qui permettent de passer à l’écran suivant doivent être visible même quand le clavier est ouvert. Dans le cas contraire l’utilisateur ne va peut-être pas arriver à faire disparaitre le clavier, ou bien il va appuyer sur un autre bouton sans le vouloir, il ne vas plus comprendre ce qu’il se passe et ne sera pas heureux ! Ok, c’est un peu tiré par les cheveux, mais admettons… En tout cas le conseil sous-jacent d’Alfred est d’utiliser la barre d’application afin de garder toujours les actions importantes à portée de doigt.

3. Prendre en compte le thème de l’utilisateur

J’en ai déjà parlé dans un précédent billet, donc je ne m’attarderai pas sur ce point. Quand vous testez votre application, prenez bien soin de la tester en thème light et en thème dark. Faîtes attention aux problèmes de lisibilité, et utiliser les ressources du système pour que l’application soit toujours agréable, quel que soit le thème et la couleur d’accent choisie. L’autre solution est d’utiliser une copie du fichier de thème qui est propre à votre application, et donc de surcharger les couleurs dans un cas comme dans l’autre ; ce qui est une solution tout à fait acceptable. Dans ce cas vous n’avez que vos couleurs à gérer, mais gérez les biens !

4. Faites des applications manipulable au doigt

Contrairement à votre émulateur, les utilisateurs utiliseront leurs doigts pour naviguez dans votre application. Il faut donc adapter les zones de touché au doigt. Pour ça il est conseillé d’agrandir la zone de touché bien au-delà de la zone visuelle. Rapprocher trop les éléments les uns des autres introduit un risque pour l’utilisateur d’appuyer sur le mauvais bouton.

La bonne nouvelle c’est que les contrôles de Silverlight sont déjà optimisés par natures, en ayant naturellement un margin important. Si vous utilisez des contrôles personnalisés ou que vous modifiez les margins des contrôles existants, alors respectez scrupuleusement les guidelines de Metro sur les tailles minimums de cible, issus des recherches en expérience utilisateur menées par Microsoft.

Dans le document UI Design and Interaction Guide, à la page 75 on peut par exemple lire qu’une cible doit être au moins un carré de 34px avec un espacement d’au moins 8px. L’agrandissement de la zone de touché doit être d’au moins 60% de la taille de l’élément. Pour les éléments textuels touchables, la taille de police doit être d’au moins 15pts.

En conclusion, vérifiez toujours que votre application est toujours utilisable au doigt et vérifiez ça sur un téléphone !

5. L’utilisateur veut savoir ce qui se passe…

… Alors donnez-lui des indices ! Sur tous les éléments tactiles, vous pouvez utiliser l’effet « Tilt » (qui est décrit sur la MSDN : http://msdn.microsoft.com/en-us/library/ff941102(VS.92).aspx) pour montrer à l’utilisateur que le touché à bien un effet.

Pour les téléchargements ou les opérations qui prennent du temps, utiliser la ProgressBar pour montrer à l’utilisateur que l’application n’est pas plantée et qu’il doit patienter encore quelques instants. Si vous pouvez donner une estimation du temps restant les guidelines conseillent une progress bar à temps déterminé (IsIndeterminate = false) et l’inverse si on ne peut pas donner d’estimation.

Note : n’oubliez pas de mettre IsIndeterminate à false après que vous l’ayez fait disparaitre, sinon il se peut qu’elle impacte quand même vos performances…

6. Attentions aux contenus Web

Si vous intégrez du contenu Web dans votre application par le biais du composant WebBrowser, il y a quelques petites choses à ne pas oublier.

  • Empêchez de faire des zooms dans le contenu Web en réglant le viewport (height, width et user-scalable=no) pour que l’utilisateur ne se rende pas compte que le contenu est effectivement un contenu Web
  • Privilégiez de grandes tailles de police, à minima 15pt.
  • Veillez à ce que les champs (texte, listes, etc.) tiennent sur toutes la largeur de la page
  • De manière générale, évitez tous scrolling horizontal, qui pourrait faire penser à un panorama sans l’être
  • Faites en sorte que la charte graphique utilisée par la partie Web soit conforme au reste de l’application

En conclusion si vous utilisez du contenu Web, le reprendre tel quel ne serait pas acceptable du point de vue de l’expérience utilisateur. Pour plus de détails sur le moteur de rendu intégré dans le composant WebBrowser, reportez-vous à la page MSDN consacrée : http://msdn.microsoft.com/en-us/library/ff462082(VS.92).aspx

7. Placement des boutons dans l’application et les boutons à éviter

Il y a dans le dernier article deux points très importants sur les boutons (software et hardware). Premièrement il y a, comme vous le savez, trois boutons en façade sur tous les modèles de Windows Phone : un bouton retour, un bouton accueil et un bouton rechercher.

Ce que nous dit Alfred pour commencer est d’éviter dans l’application de mettre de bouton « Retour » ou de bouton « Accueil », le premier parce qu’il fait double emploi avec la touche physique et qu’il faut éviter de faire douter l’utilisateur, et le second parce qu’il risquerait de perturber l’utilisateur. « Si j’appuie sur Accueil est ce que cela m’amène sur l’écran du démarrage du téléphone comme le bouton physique ? Si j’appuie sur le bouton physique est ce que cela va m’amener sur l’écran d’accueil de l’application ? »

Tout en étant 100% d’accord avec cela, on pourrait quand même se demander pourquoi Microsoft ne permet pas la surcharge du bouton physique de recherche, ce qui permettrait d’éviter d’ajouter un bouton recherche qui fait double emploi dans nos applications, mais cela n’engage que moi.

Deuxième point, au sein de l’application, les boutons doivent être disposés de façon structurée. Bien évidemment, si vous pouvez utiliser la barre d’application (Pivot ou page simple), faite le ! Sinon, disposez vos boutons dans une structure simple et compréhensible (StackPanel, WrapPanel, etc.) pour ne pas laisser l’utilisateur pantois quand il découvrira votre interface.

En conclusion, on peut voir que de jour en jour le Marketplace se remplit à une vitesse toujours plus grande avec plus de 6000 applications. Pour moi ce chiffre ne veut pas dire grand-chose… Certes à cette vitesse le marketplace de BlackBerry sera dépassé dans quelques mois, mais la qualité doit tout de même primer sur la quantité. Je ne souhaite pas voir 100 000 applications comme c’est le cas sur Android, si ces applications ne sont pas faites avec le désir de contenter l’utilisateur avant tout.

Encore une fois, ça n’engage que moi…

Première application sur le marketplace !

Voilà, malgré un certain temps d’absence depuis le dernier article (mais rassurez-vous, un prochain article est en préparation), j’ai eu le temps de réaliser une petite application gratuite, plus pour m’amuser que pour créer la killer-app du siècle, que j’ai mise sur le marketplace. Il s’agit de « Fête du jour » pour voir quels prénoms sont fêtés un jour donné, et inversement voir à quelles dates sont fêtés vos proches. Voilà le lien de téléchargement Zune, ainsi que quelques screens ! N’hésitez pas à commenter pour me donner votre avis sur l’application !
Télécharger pour Windows Phone 7

Télécharger pour Windows Phone 7

EDIT 02/02/02 : Mon application est aujourd’hui dans les applications recommandées par Microsoft ! Champagne !

Mon application recommandée par Microsoft !

Metro et les animations

Les animations font partie intégrante de Metro, l’UX de Windows Phone 7. Un certain nombre d’animations sont utilisées au sein même du système mobile de Microsoft ; reproduire ces animations peut donc permettre à une application de ressembler plus au reste du système et donc de ne pas perdre l’utilisateur avec une signalétique différente. Dans cet article nous verrons les différentes animations de WP7 et comment les implémenter dans son application. Les spécifications des animations proviennent du blog de Clarity Consulting : http://blogs.claritycon.com/blogs/kevin_marshall/archive/2010/10/12/wp7-page-transitions-sample.aspx

Les types d’animations

Voyons tout d’abord les différents types d’animations de Windows Phone 7. Chacun des types d’animation est utilisé dans des cas distincts, qui seront décrits à chaque fois. Une chose importante à noter est l’utilisation dans les animations d’Easing, c’est-à-dire que les animations ne sont pas linéaires et s’accélèrent ou se décélèrent dans le temps. Toutes les animations de Windows Phone 7 utilisent l’Easing Exponential 6 (entrée ou sortie).
Note : Comme décrit dans l’article de Clarity Consulting, si vos pages sont un peu complexes, l’exponentielle 6 sera peut-être trop rapide ; utilisez dans ce cas une exponentielle 3.
Pour chaque animation il y a plusieurs cas d’utilisation, en général un pour amener du contenu et l’autre pour enlever le contenu. Ces différents cas seront également décrits ci-dessous. Clarity Consulting a de plus réalisé une vidéo qui vous permettra de voir tout de suite ce qui se cache derrière les énigmatiques noms d’animations :

Turnstile et Turnstile Feather

Description

L’animation Turnstile est l’animation la plus courante dans l’interface Windows Phone 7 : cette animation qui rappelle le mouvement les pages d’un livre qui se tournent, est utilisée quand on lance une application, ou quand on arrive dans les paramètres pour prendre deux exemples parmi tant d’autres.
Il y a d’ailleurs une grosse différence entre ces deux cas précis : quand on lance une application, le splash screen arrive en block alors que les liens des configurations arrivent en tournant de manière similaire mais dont le mouvement est légèrement décalé. On appelle la première animation « Turnstile » et la seconde animation « Turnstile Feather ». La seule différence entre ces deux types d’animation est donc que le premier s’applique à un seul contrôle, alors que le second s’applique à une liste. Le décalage entre chaque élément du Turnstile Feather est de 50 ms.
Le turnstile est une animation qui possède quatre variations :
  • On arrive sur une nouvelle page ; la page apparaît par derrière et s’arrête. C’est le Turnstile Forward in.
  • On sort de cette page pour une autre page ; la page courante disparaît par devant. C’est le Turnstile Forward out.
  • On revient de la nouvelle page sur la page d’avant ; la page précédente revient de devant et s’arrête. C’est le Turnstile Backward in.
  • On sort de l’application ; la page s’en va par derrière. C’est le Turnstile Backward out.

Spécifications

Nom Mouvement Durée Interpolation
Forward in -80 à 0 sur l’axe Y (avec centre de rotation en X à 0) 350 ms Exponentiel 6 (EaseOut)
Forward out 0 à 50 sur l’axe Y 250 ms Exponentiel 6 (EaseIn)
Backward in 50 à 0 sur l’axe Y 350 ms Exponentiel 6 (EaseOut)
Backward out 0 à -80 sur l’axe Y 250 ms Exponentiel 6 (EaseIn)

Conseils

Le Turnstile (et Turnstile Feather) est l’animation reine de Windows Phone 7 et donne un rendu magnifique, d’autant plus que les projections sont accélérées par le GPU. Elle est faite pour les animations d’entrée et de sortie d’application et pour la navigation dans les pages de l’application.
Attention cependant aux chutes de performances si vous utiliser cet effet sur des pages qui contiennent trop d’éléments, ou qui ne sont pas mise en cache sur le GPU (par exemple lors de l’utilisation de masque d’opacité).

Slide

Description

Le slide est un glissement de la page entière qui peut être lié à un fondu ou non (Slide / Slide and Fade). Il est utilisé pour symboliser la création d’un nouvel élément. Il peut être s’effectuer sur les côtés ou en haut / en bas. Deux états le caractérisent, l’apparition (slide in) et la disparition (slide out).

Spécifications

Nom Mouvement Durée Interpolation
Slide in Mouvement de 150 px dans la direction voulue 350 ms Exponentiel 6 (EaseOut)
Slide out Idem 250 ms Exponentiel 6 (EaseIn)
Slide and fade in Idem 350 ms Exponentiel 6 (EaseOut)
Slide and fade out Idem 250 ms Exponentiel 6 (EaseIn)

Conseils

Le slide est une animation qui est utilisée lors de la création d’une nouvelle donnée (exemple nouveau mail, nouveau contact, etc.) Elle est très simple et rend généralement bien. On peut également jouer sur les directions pour ajouter du sens : par exemple lors de la création d’un nouveau mail, si l’on annule la création du mail le slide s’effectue vers le bas (je jette mon mail à la poubelle) et si on envoie le mail le slide s’effectue vers le haut (j’envoie mon mail vers le server).

Continuum

Description

L’effet continuum permet de suivre la transition depuis une liste, vers une page de description de l’élément que l’on vient de sélectionner. Il est utilisé par exemple dans le Marketplace, lorsque l’on sélectionne une application et que l’on arrive sur la page descriptive de l’application.
Lorsque l’on clique sur l’élément, cet élément va avoir un mouvement courbe qui sort de l’écran (Forward out) et après la transition sur la page suivante, ce même élément va apparaître depuis l’extrémité de l’écran pour se placer en haut de l’écran, toujours suivant un mouvement courbe (Forward in). Quand on appuiera sur la touche back, la page entière disparaît (Backward out), et de retour sur la page précédente, l’élément réapparait du côté et revient à sa place dans la liste (Backward in).

Spécifications

Nom Mouvement Durée Interpolation
Forward out L’élément sélectionné se déplace de 73px vers le bas et de 225px sur le côté droit. La page glisse vers le bas de 70px et disparaît (opacité 0%) 150 ms Exponentiel 6 (EaseOut)
Forward in La page glisse vers le haut de 150 px. L’élément quant à lui arrive du coté de 130 px et descend de 70 px. 150 ms Exponentiel 6

(EaseOut)
Backward out La page effectue un glissement de 150 px et disparaît en même temps (Opacité 0%) 150 ms Exponentiel 6 (EaseIn)
Backward in L’élément revient de 70 px depuis la gauche. 150 ms Exponentiel 6 (EaseOut)

Conseils

Le continuum est parfait pour relier deux pages par un élément spécifique. Il faut juste faire en sorte que c’est cet élément qui se déplace de la première à la seconde page et inversement.

Swivel

Description

L’effet swivel est un effet qui montre l’apparition d’une fenêtre modale à l’écran. C’est une projection sur l’axe X. On peut en voir une application lors d’un appel entrant (apparition) et lorsque l’appel est terminé (disparition).

Spécifications

Nom Mouvement Durée Interpolation
Apparition -45 à 0 sur l’axe X (avec centre de rotation en Y à 0,5) 350 ms Exponentiel 6 (EaseOut)
Disparition 0 à 60 sur l’axe X 250 ms Exponentiel 6 (EaseIn)

Conseils

Les angles utilisés sont volontairement inférieurs à 90° pour donner une impression de vitesse. Pensez à mettre la visibilité à Collapsed dès que l’animation est terminée, ou votre rendu paraîtra chaotique. Cet effet est à réserver aux éléments qui apparaissent au-dessus des pages normales, qu’ils soient en plein écran ou non.

Rotate

Description

La rotation est l’effet par défaut lors d’un changement d’orientation dans le système. Il peut se faire du mode portrait au mode paysage ou du mode paysage au mode portrait.

Spécifications

Nom Mouvement Durée Interpolation
Rotation gauche (respectivement droite) 0 à -90 (respectivement -90 à 0) sur l’axe Z 500 ms Exponentiel 6 (EaseInOut)

Conseils

La rotation est l’effet à utiliser en cas de changement d’orientation. Par cohérence, vous pouvez également utiliser ces caractéristiques de durée et d’interpolation pour n’importe quelle rotation au sein de votre application.

Implémentation

Il est curieux que Microsoft n’ai pas encore proposé de code samples pour gérer les animations tout en étant cohérent avec le reste du système. Heureusement plusieurs l’ont déjà fait. C’est le cas de Clarity Consulting qui propose dans leur article une classe abstraite AnimatedBasePage qui gère les transitions. C’est également le cas de Telerik qui propose depuis peu un ensemble de contrôles pour Windows Phone.
Avec les spécifications, vous pouvez également créer ces animations, soit en XAML, soit en code et les appeler dans les différents évènements de la page. Par exemple, gérer les évènements NavigatedTo, NavigatingFrom et OnBackKeyPress vous permettra de créer dynamiquement des instances des différents storyboards et de jouer les animations.
Implémenter les animations de Windows Phone 7 peut être somme toute un peu compliqué, mais la valeur ajoutée est au rendez-vous, car cela permet à vos applications de se comporter comme le reste du système, et il faut avouer que les animations de WP7 ont vraiment un style unique !

Windows Phone 7 Silverlight Toolkit et les animations

Microsoft a justement attendu ce jour pour dévoiler la mise à jour de Novembre du WP7 Silverlight Toolkit qui contient… les classes qui vont vous aider à mettre en place les animations dans vos applications Windows Phone 7 ! Les nouvelles API ont l’air assez faciles à utiliser; il faut tout d’abord remplacer la RootFrame dans le App.xaml.cs par un TransitionFrame. Ensuite on pourra définir des transitions en XAML comme ceci :
<toolkit:TransitionService.NavigationInTransition>
 <toolkit:NavigationInTransition>
 <toolkit:NavigationInTransition.Backward>
 <toolkit:TurnstileTransition Mode="BackwardIn"/>
 </toolkit:NavigationInTransition.Backward>
 <toolkit:NavigationInTransition.Forward>
 <toolkit:TurnstileTransition Mode="ForwardIn"/>
 </toolkit:NavigationInTransition.Forward>
 </toolkit:NavigationInTransition>
</toolkit:TransitionService.NavigationInTransition>
Plus d’informations sur le Toolkit 2ème édition se trouvent sur le blog de David Anson !

La bibliothèque Silverlight Database

J’avais évoqué dans un précédent post les mécanismes de persistance de données dans Windows Phone 7 via l’IsolatedStorage. J’avais ainsi terminé l’article sur le fait que Silverlight pour Windows Phone manquait encore de réel gestionnaire de base de données tel que SQL CE. Il existe en revanche plusieurs API Open Source qui comblent ce manque. L’une d’entre elles est la bibliothèque Silverlight Database, projet hébergé sur la plateforme de projets Open Source de Microsoft, CodePlex. Vous pouvez télécharger le projet sur sa page : http://silverdb.codeplex.com

Fonctionnalités de Silverlight Database

L’API est en réalité très simple à utiliser, avec seulement quelques classes importantes, en particulier Database et Table<T>. Grâce à ses classes vous allez pouvoir créer une représentation objet de votre base de données et la sauvegarder sur l’IsolatedStorage de votre client (que cela soit du Silverlight pour navigateur ou du Silverlight pour Windows Phone 7). Toute la manipulation de l’IsolatedStorage sont effectué par Silverlight Database sans que vous ayez à vous préoccuper de quoi que ce soit. Les fonctionnalités de l’API sont les suivantes :

  • Création et suppression d’une ou plusieurs bases
  • Ajout et suppression d’une ou plusieurs tables
  • Récupération des données avec possibilité d’utiliser du Lazy Loading (c’est-à-dire que les données ne seront récupérées que lorsque le programme en aura vraiment besoin)
  • Compression des données via la bibliothèque Open Source Silverlight SharpZipLib (également hébergée sur CodePlex : http://slsharpziplib.codeplex.com/)
  • Chiffrage des données par l’algorithme de chiffrage symétrique AES (via la classe AESManaged)

Ce que Silverlight Database n’est pas

Contrairement à ce que le nom suggère Silverlight Database n’est pas un vrai gestionnaire de base de données. En effet si j’ai une entité A reliée à une ou plusieurs entités B, on aura en fait une classe A qui contient un IEnumerable<B> ; cette liste sera sérialisée en même temps que l’objet de type A, et tous ces objets seront contenu dans la table de A, hors dans un véritable SGBD les instances de B devraient être conservées à part dans une table contenant tous les B.

Ce n’est pas vraiment une limitation, mais cela peut donner des choses étranges si on n’y fait pas attention. C’est pourquoi je pense que Silverlight Database est plus un gestionnaire de conteneur d’objets persisté plutôt qu’un SGBD. Silverlight Database n’en ai pas moins très facile et agréable à utiliser.

Utilisation de l’API

Pour commencer, vous devez créer une base via la méthode statique Database.CreateDatabase qui prend en argument un identifiant (pour retrouver la base plus tard) et optionnellement un mot de passe qui servira de clé de chiffrage. Si vous avez déjà créé une base vous pouvez la charger via la méthode statique Database.LoadDatabase qui prend les mêmes arguments que pour la création.

Depuis l’instance de Database que vous venez de récupérer vous pouvez ajouter une table (ou plus exactement un conteneur pour un certain type d’objet) en appelant la méthode CreateTable<ObjectType> ou récupérer une table déjà créée via la méthode Table<ObjectType>.

Le type Table<T> renvoyé par ces deux méthodes est une classe bien pratique, qui dérive d’ObservableCollection<T>. Cela signifie que vous pouvez par exemple lier une Table<T> directement par Binding à une ListBox dans votre XAML. Comme l’ObservableCollection<T> lève des évènements lors d’ajouts et de suppressions, la ListBox sera ainsi directement mise à jour en fonction de vos traitements métiers sans aucun effort supplémentaire.

Bien évidemment, qui dit ObservableCollection dit Collection et donc possibilité d’utiliser les méthodes d’extensions de LINQ. Vous pourrez donc exécuter des requêtes sur vos tables en utilisant les méthodes Where, Any, Take et ainsi de suite. Pour terminer un appel à la méthode Save de la classe Database vous permettra de sauvegarder les modifications.

Conclusion

Pour conclure Silverlight Database est une bibliothèque très pratique qui permet de persister dans l’IsolatedStorage des objets managés de manière simple et profite de fonctionnalités intéressantes telles que la compression ou le chiffrage. Ce n’est pas exactement un SGBD comme le serait l’hypothétique SQL CE pour Windows Phone 7, mais néanmoins il permet d’abstraire une tâche peu intéressante que l’on retrouve dans un vaste panel d’application et d’ainsi accélérer vos développements.