Dot.Blog

C#, XAML, Xamarin, UWP/Android/iOS

Windows Store Apps : Comment créer et gérer une AppBar

[new:30/12/2012]Dans une application Windows Store l’AppBar est cette barre de boutons qui apparaît en bas de l’écran et qui remplace dans l’esprit les menus contextuels (popup) de Win32. Il existe une variante en haut de l’écran dédiée plutôt à la navigation. C’est un élément essentiel de l’UI Windows Store sous Windows 8.

Le rôle de la AppBar

Dans une application “Metro” l’AppBar est une zone en bas de l’écran qui reste cachée et qui ne s’affiche que lorsque cela est nécessaire pour présenter des boutons : navigation, commandes, outils, il n’y a pas forcément de limite même si quelques guidelines doivent être respectées.

Bien qu’assez différente techniquement des popups Win32 déclenchés sur le clic-droit l’AppBar joue un rôle assez similaire. Les Flyout sont plus proches visuellement des popups, mais faute de temps les équipes de Microsoft n’ont pas encore ajouté ce composant Html/WinJS au profil C#/Xaml (il en existe néanmoins une version non officielle C# sur CodePlex, le CharmFlyout, disponible aussi en package nuget).

image

L’AppBar se situe généralement en bas de l’écran et c’est là que je vous conseille de la laisser par souci d’homogénéité avec les règles d’UI Metro (comme sous Windows Phone donc). Mais l’AppBar peut aussi apparaître en haut de l’écran, voire les deux à la fois !

Dans ces cas particuliers on voit généralement l’AppBar du bas rester dédiée aux commandes alors que celle du haut sera plutôt utiliser pour naviguer par exemple (ce qui fait partie des guidelines). Mais là encore la liberté est assez grande, l’essentiel est que cela ait un sens pour l’utilisateur et que la cohérence et la qualité de l’UX soient préservées.

Comment ajouter une AppBar ?

C’est en réalité très facile puisqu’autant la barre du haut que celle du bas sont des propriétés de l’objet Page.

On trouve ainsi les propriétés TopAppBar et BottomAppBar dans l’objet Page et il est facile de les renseigner par un contenu quelconque, les deux propriétés étant de type AppBar, type dérivant lui-même de ContentControl (et si on remonte le courant tel un saumon : Control, FrameworkElement, UIElement, DependencyObjet, et Object !).

Une AppBar peut être créée par code C# ou Xaml, cela ne fait aucune différence. Le code peut changer une AppBar à sa guise (ce qui en fait un remplaçant du popup contextuel Win32) pour adapter le contenu au contexte.

Le contenu de l’AppBar est totalement libre même si, selon les guidelines, il s’agira principalement de boutons.

N’étant qu’un ContentControl, l’AppBar peut se définir par tout code Xaml valide possédant un objet racine qui contient tout le reste. Généralement il s’agit d’une Grid sans aucune propriété (donc qui prendra tout l’espace disponible par défaut) dans laquelle on retrouve des StackPanel contenant les boutons.

Je dis “des” StackPanel car il est très fréquent de voir deux groupes de boutons dans une AppBar : une série sur la gauche, l’autre sur la droite. Les StackPanel sont tout à fait indiqués pour mettre en page des séries d’objets surtout de même taille comme ici. Un StackPanel est ferré à gauche, l’autre à droite.

A cela deux raisons : la séparation est (doit être) sémantique (les deux groupes de boutons doivent impliquer deux groupes logiques de commandes), et s’agissant d’applications tournées vers la mobilité il est plus aisé de fournir un groupe pour le pouce gauche et un autre pour le droit plutôt qu’une longue barre ayant des boutons au centre qui seront difficilement accessibles (le Design c’est aussi de l’ergonomie ne l’oublions pas !).

Mais là encore la liberté est assez grande tant que les choix font sens avec le contexte.

Le code Xaml suivant définit une AppBar (dans un objet Page) :

<Page.BottomAppBar>
    <AppBar x:Name="bottomAppBar" Padding="10,0,10,0">
        <Grid>
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
                <Button Style="{StaticResource EditAppBarButtonStyle}" Click="Button_Click"/>
                <Button Style="{StaticResource RemoveAppBarButtonStyle}" Click="Button_Click"/>
                <Button Style="{StaticResource AddAppBarButtonStyle}" Click="Button_Click"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
                <Button Style="{StaticResource RefreshAppBarButtonStyle}" Click="Button_Click"/>
                <Button Style="{StaticResource HelpAppBarButtonStyle}" Click="Button_Click"/>
            </StackPanel>
        </Grid>
    </AppBar>
</Page.BottomAppBar>

 

ce qui, visuellement, se traduira par :

Bottom app bar control

Partager une AppBar au travers des pages

Bien que l’AppBar soit souvent contextuelle, cela n’est pas une obligation. Il peut être parfois plus pertinent d’offrir la même AppBar à toutes les pages d’une application.

Je ne détaillerai pas la technique mais juste l’esprit : Dans un tel cas on créée une page racine possédant une Frame dans laquelle les autres pages de l’application navigueront. C’est cette page racine qui possède la AppBar. Elle override aussi le OnNavigateTo pour le “rerouter” les URI vers la Frame intérieure.

L’illusion est alors parfaite. Mais attention, cela se pense “avant”. Ll’ajouter “après” peu remettre en cause certains choix. Une application Metro doit toujours être designée avant de commencer à code !

Ce n’est pas parce que j’en parle moins ces temps-ci, actualité oblige, que le Design n’a plus d’importance… Vous pouvez facilement retrouver tous les billets sur ce sujet en interrogeant le tag “design” de Dot.Blog : http://www.e-naxos.com/Blog/?tag=/design

Ouverture et Fermeture

L’AppBar possède une propriété IsOpen dont le nom est clair… Lorsque la propriété est mise à True la barre s’ouvre, à False, elle se referme.

Les AppBar sont des objets à “light dismiss”, c’est à dire qu’ils disparaissent facilement dès qu’on clic (ou tape avec le doigt) en dehors de leur zone. Il est possible de forcer l’ouverture d’une AppBar au premier affichage d’une page en mettant IsOpen à True. Dès que l’utilisateur tapera ailleurs ou qu’il aura cliqué sur l’un des boutons la AppBar se cachera.

Cela peut être un moyen simple de montrer les possibilités d’une page sans aucune autre explication. L’utilisateur voit ce qui est possible de faire, nul besoin de 15 pages de docs pour cela… Certaine pages peuvent aussi s’ouvrir en ayant immédiatement besoin d’une commande utilisateur (par exemple afficher une image prise à la webcam et afficher deux boutons “ok” / “recommencer”). L’ouverture immédiate de la AppBar trouve ainsi sa place dans de nombreux scénarios (mais cela ne s’invente pas pendant qu’on code, il faut y avoir pensé avant sinon gare non plus au “code spaghetti” mais au “design spaghetti” ce qui est un crime tout aussi condamnable !).

Figer la barre

Une AppBar disparait dès que l’utilisateur interagit avec des éléments de l’application en dehors de l’espace de la barre elle-même. Mais il est possible de figer la barre pour qu’elle ne disparaisse pas.

Pour cela une seule propriété : IsSticky qu’on peut placer à True aussi bien en Xaml qu’en C# (à condition d’avoir ajouté un “x:Name” pour pouvoir référencer la barre dans le code dans ce dernier cas).

Les évènements d’ouverture et fermeture

Il est très simple de réagir aux évènements d’ouverture et de fermeture d’une AppBar car elle expose deux events : Opened et Closed. Comme les noms le laissent supposer, ces évènements sont des “constats” et non des “avertissements”. J’entends par là que l’action est déjà consommée, le code ne peut que constater que cette action s’est déroulée. Un event d’avertissement serait du type OnClose, permettant par exemple d’agir avant que l’ouverture ne soit définitivement opérée, voire de l’annuler. Ce n’est pas le cas ici.

L’argument de ces events est d’ailleurs un “object” de base, donc sans information (ni en entrée, ni en sortie).

Les styles cachés des boutons

Les boutons d’une AppBar sont très simples, il sont généralement rond avec une icône de couleur unie. Vous pouvez utiliser des banques d’icônes, ou des outils comme Metro Studio dont la version gratuite est très sympa (elle permet aussi de partir d’une fonte de symboles quelconque pour fabriquer une icône ce qui est très utile).

Mais il existe aussi quelques boutons “tout fait” cachés dans la feuille de style Xaml accrochée par défaut à un projet Windows Store.

Ce dictionnaire de styles se trouve dans le répertoire Common du projet (StandardStyle.xaml). En navigant vers les lignes 403 et suivantes vous découvrirez des définitions de styles pour des boutons. Mais ce code est commenté donc non opérant.

Pour vous en servir supprimez simplement les balises de commentaire !

On trouve ainsi des boutons “Skip back”, “Skip ahead”, “Play”, “Pause”, etc.

Les propriétés définies dans ces styles peuvent être changées et vous pouvez aussi ajouter de la même façon vos propres styles de boutons. La création d’un bouton devient alors très simple dans le code même de la AppBar. Par exemple :

<Page.BottomAppBar>
   <AppBar x:Name="bottomAppBar" Padding="10,0,10,0">
      <Grid>
         <StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
            <Button Style="{StaticResource OpenFileAppBarButtonStyle}" Click="Open_Click"/>
         </StackPanel>
         <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
            <Button Style="{StaticResource PlayAppBarButtonStyle}" Click="Play_Click"/>
            <Button Style="{StaticResource PauseAppBarButtonStyle}" Click="Pause_Click"/>
         </StackPanel>
      </Grid>
   </AppBar>
</Page.BottomAppBar>

 

On voit dans ce code les styles directement appliqués à des instances de Button sans aucun besoin de spécifier d’autres propriétés (en dehors de la gestion du clic qui sera avantageusement remplacé par une commande dans le cadre du pattern MVVM).

Le dictionnaire de styles par défaut définit les styles de button de cette façon (exemple du style pour créer un bouton “play”) :

<Style x:Key="PlayAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
        <Setter Property="AutomationProperties.AutomationId" Value="PlayAppBarButton"/>
        <Setter Property="AutomationProperties.Name" Value="Play"/>
        <Setter Property="Content" Value="&#xE102;"/>
</Style>

 

Les principales propriétés touchées sont :

AutomationProperties.AutomationId

Cela permet tout bêtement de donner un ID ré-exploitable pour la gestion de commandes.

AutomationProperties.Name

On indique ici le nom qui pourra s’afficher sous le bouton. C’est une indication très utile pour l’utilisateur car parfois l’icône, même bien choisi, n’est pas forcément totalement évident. Une fois encore, une interface Metro est auto-explicative. On doit pouvoir utiliser le soft sans aucune aide autre que ce qu’on voit.

J’insiste là dessus car je sais à quel point pour nombre de développeurs c’est un saut énorme à franchir que de penser de cette façon… Le réflexe “l’utilisateur n’a qu’à lire la doc” est un réflexe de dinosaure qui ne vit pas avec son temps. Je le rencontre encore assez souvent hélas, ne serait-ce qu’indirectement quand je vois le “design” que certains développeurs prévoient pour leurs applications et où il est clair '(la seule chose qui le soit d’ailleurs!) qu’il faudra une longue formation des utilisateurs finaux pour s’en sortir ! Les lecteurs de Dot.Blog, grâce à mes divers billets de sensibilisation sur le Design ne sont pas comme ça, je le sais bien, mais les vieux réflexes reviennent parfois sournoisement, alors une piqûre de rappel ne coûte rien :-)

Content

C’est bien entendu l’icône centrale du bouton qu’on fournit au bouton à cet endroit.

Tout contenu Xaml est valide (un Path, un PNG…). Toutefois le système tel qu’il est fait utilise habilement la fonte “Segoe UI Symbol”, autant que faire se peut, utilisez la même astuce, la fonte est déjà chargée et ses symboles sont reconnus facilement. Sinon utilisez des images ou du Xaml (Metro Studio ou le Noun Project qui est orienté SVG mais très utile tout de même, ou faites appel à un infographiste si le projet le nécessite !).

image

Bien entendu il reste possible de définir vos boutons d’une autre façon, tant que cela reste esthétique et cohérent avec le look Metro et ses guidelines, vous avez le champ libre.

Conclusion

La gestion des AppBar dans les applications est d’une redoutable simplicité mais joue un rôle centrale dans la qualité de l’UX.

Ne négligez pas ni la conception de styles propres et cohérent, ni la logique et l’ordre d’affichage des boutons, et encore moins le choix des icônes,

Finalement, une bonne AppBar est une AppBar bien conçue (Lapalissade), toute la difficulté est dans le “bien conçue” !

Metro pour Windows 8 est riche de bien d’autres surprises, cela permet déjà de prévoir d’autres billes à venir !

Alors… Stay Tuned !

blog comments powered by Disqus