Accueil Nos publications Blog Expression Blend, les 10 bonnes raisons de l’utiliser : #5 \\ Les styles & templates

Expression Blend, les 10 bonnes raisons de l’utiliser : #5 \\ Les styles & templates

#5blend_styles&templatesContrairement à ce que pensent un bon nombre de développeurs, Expression Blend n’est pas fait que pour les designers ! Si vous l’ouvrez et commencez à éditer une page, vous retrouverez le même affichage que sur Visual Studio : c’est à dire l’aperçu et le code.

Si on prend quelques heures pour s’y habituer et apprendre à l’utiliser, il peut s’avérer bien utile et vous rendre très productif !

Cet article parle de la cinquième bonne raison de l’utiliser : Les styles et les Templates. Grâce à cette fonctionnalité, stylez très facilement tous les contrôles dans votre application ! Une fonctionnalité à la portée de tous grâce à la simplicité d’utilisation qu’apporte Blend, ce que nous allons voir dans cet article.

Programme

Semaine 0 : Introduction

Semaine 1 : La Puissance du designer

Semaine 2 : TFS intégré à Blend

Semaine 3 : Visualiser vos fichiers de ressources

Semaine 4 : Les animations

Semaine 5 : Les styles & templates

Semaine 6 : DataSample

Semaine 7 : Behaviors

Semaine 8 : Stechflow

Semaine 9 : Import de fichiers Illustrator / Photoshop

Semaine 10 : Spécificités Windows Phone / Windows 8

Semaine 11 : Conclusion / Les différentes versions de Blend

Introduction

Vous avez envie de créer des styles pour votre application mais vous trouvez cela trop fastidieux avec Visual Studio ? Vous passez beaucoup trop de temps à rechercher le style par défaut pour enfin pouvoir commencer à le modifier tant bien que mal et ainsi vous avez déjà envie de laisser tomber pour laisser votre application tel quel avec les styles par défaut…

Nous allons découvrir ensemble dans cet article comment styler votre application avec Blend en 10 secondes !

Qu’est-ce qu’un Style ou un Template ?

Dans l’article précédent, on parlait de ressources, un style et un template sont des ressources définies par une clé x:Key="NomDuStyle".

Rappelez-vous :

« Une ressource peut être un dégradé, une couleur, une image, un style tout cela dans le but de l’appliquer à un élément visuel comme couleur de fond ou de contour ou bien à un contrôle pour changer son apparence.

Un style est défini par un certain nombre de propriétés (Background, Foreground, Padding, etc.) dont la propriété Template qui est de type ControlTemplate, spécifique à un type de contrôle (TargetType).

Un contrôle possède donc son propre Style et éventuellement un à plusieurs Data Template (en fonction du type de contrôle).

Définitions :

Control Template : Spécifie la structure visuelle et les aspects comportementaux d’un Control qui peuvent être partagés par plusieurs instances du contrôle.

Data Template : Décrit la structure visuelle d’un objet de donnée.

Quelle est la différence ?

Un style est utilisé pour définir l’apparence du contrôle tandis qu’un Template définit le contenu et la disposition des éléments que le contrôle affiche.

Le meilleur exemple pour illustrer le style et le Template est le contrôle de type ListBox. Ce contrôle possède :

<ListBox ItemContainerStyle="{StaticResource ListBoxItemStyle1}" 
ItemTemplate="{StaticResource DataTemplate1}" Style="{StaticResource ListBoxStyle1}" 
ItemsPanel="{StaticResource ItemsPanelTemplate1}"/>

  • Style : aspect visuel du contrôle
  • ItemContainerStyle : aspect visuel des items contenus dans le contrôle
  • ItemTemplate : disposition et contenu des items du contrôle
  • ItemsPanel : container des items du contrôle

Comment ça marche ?

Créer / appliquer un style ou template

Pour Blend, le terme Style et Template est un peu ambiguë car un Style est un Template. Pourquoi ? Et bien allons voir comment créer un style pour une ListBox.

Il suffit de faire un clic droit dessus, puis « Edit Template » afin d’éditer le style de votre ListBox, vous voyez ici l’ambiguïté ?

#5blend_createstyle

Si vous voulez éditer les autres éléments, il faudra aller dans « Edit Additionnals Templates » afin de retrouver ItemTemplate, ItemContainerStyle et ItemPanel :

#5blend_createtemplate

Une fois que vous avez compris ces ambiguïtés sur les termes utilisés, c’est ici que Blend devient très intéressant à utiliser !

En effet 4 possibilités s’offrent à vous en un seul clic :

  • Editer le Template courant (si un style est déjà défini)
  • Editer une copie du Template courant (pour repartir du Style par défaut)
  • Créer un Template vide
  • Appliquer un Style/Template d’une ressource existante

Donc si aucun style n’est encore défini dans votre projet, vous allez utiliser « Editer une copie », Blend va ainsi générer le code XAML correspondant au style ou Template par défaut du contrôle. C’est ici qu’est la puissance de Blend ! En un clic vous repartez du style par défaut !

Si vous étiez passé par le code sous Visual Studio il aurait fallu écrire ce code XAML ou bien aller le chercher sur votre ordinateur (cf. la partie suivante « Où trouver les styles par défaut »).

Grace à Blend, vous avez donc gagné du temps ! Vous pouvez ainsi définir tous les Styles et Templates de cette façon pour tous vos contrôles.

Ou trouver des styles par défaut ?

Pour ceux qui aiment le code, allez voir le code XAML généré quand vous allez créer votre premier style. Pour cela, affichez le code XAML de votre page :

#5blend_viewcode

Voici alors le code généré par Blend pour le Style de votre ListBox :



<Style x:Key="ListBoxStyle" TargetType="ListBox">

<Setter Property="Background" Value="Transparent"/>

<Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>

<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>

<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>

<Setter Property="BorderThickness" Value="0"/>

<Setter Property="BorderBrush" Value="Transparent"/>

<Setter Property="Padding" Value="0"/>

<Setter Property="Template">

<Setter.Value>

<ControlTemplate TargetType="ListBox">

<ScrollViewer x:Name="ScrollViewer" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Foreground="{TemplateBinding Foreground}" Padding="{TemplateBinding Padding}">

<ItemsPresenter/>

</ScrollViewer>

</ControlTemplate>

</Setter.Value>

</Setter>

</Style>

Ce code généré très facilement dans Blend peut être retrouvé de différentes façons selon le type de votre application :

Les applications WPF et Silverlight avaient leur style par défaut publiés sur MSDN :

Pour les applications Windows Phone et Windows 8, il faut aller voir sur votre PC :

  • Windows Phone : C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v8.0\Design\System.Windows.xaml
  • Windows 8 : C:\Program Files (x86)\Windows Kits\8.0\Include\WinRT\Xaml\Design\generic.xaml.

Modifier votre style ou template

Quand vous modifiez un style ou un template, l’arborescence visuelle n’est plus celle de votre page mais de votre Template :

#5blend_editstyle

Il faut utiliser le petit bouton suivant afin de revenir sur votre page / user control dans lequel vous avez créé un style ou template :

#5blend_editstyleback

De plus, dans le panel « States » vous allez pouvoir modifier l’apparence visuelle de votre contrôle selon ses différents états. Prenons pour cet exemple un contrôle de type « bouton » pour lequel nous allons modifier son style :

#5blend_editstylestates

Pour chaque état du bouton vous allez pouvoir modifier son apparence comme ci-dessous :

#5blend_buttonstyle

Pour ce faire il suffit de sélectionner l’état que vous souhaitez modifier puis appliquez les propriétés que vous désirez. Pour par exemple, avoir une couleur de fond différente dans chaque état (sélectionné, appuyé, inactif) :



<Style x:Key="ButtonStyle" TargetType="Button">

<Setter Property="Background" Value="Transparent"/>

<Setter Property="BorderBrush" Value="{StaticResource PhoneForegroundBrush}"/>

<Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>

<Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/>

<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiBold}"/>

<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMediumLarge}"/>

<Setter Property="Padding" Value="10,3,10,5"/>

<Setter Property="Template">

<Setter.Value>

<ControlTemplate TargetType="Button">

<Grid Background="Transparent">

<VisualStateManager.VisualStateGroups>

<VisualStateGroup x:Name="CommonStates">

<VisualState x:Name="Normal"/>

<VisualState x:Name="MouseOver"/>

<VisualState x:Name="Pressed">

<Storyboard>

<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentContainer">

<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneBackgroundBrush}"/>

</ObjectAnimationUsingKeyFrames>

<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ButtonBackground">

<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneForegroundBrush}"/>

</ObjectAnimationUsingKeyFrames>

<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ButtonBackground">

<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneForegroundBrush}"/>

</ObjectAnimationUsingKeyFrames>

</Storyboard>

</VisualState>

<VisualState x:Name="Disabled">

<Storyboard>

<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentContainer">

<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>

</ObjectAnimationUsingKeyFrames>

<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ButtonBackground">

<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>

</ObjectAnimationUsingKeyFrames>

<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ButtonBackground">

<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>

</ObjectAnimationUsingKeyFrames>

</Storyboard>

</VisualState>

</VisualStateGroup>

<VisualStateGroup x:Name="FocusStates"/>

</VisualStateManager.VisualStateGroups>

<Border x:Name="ButtonBackground" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="0" Margin="{StaticResource PhoneTouchTargetOverhang}">

<ContentControl x:Name="ContentContainer" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>

</Border>

</Grid>

</ControlTemplate>

</Setter.Value>

</Setter>

</Style>

Autre avantage de Blend est que vous visualisez directement le rendu de votre contrôle sans avoir à compiler (cf. image du rendu du bouton ci-dessus). Nous verrons dans l’article suivant qu’avec les DataSamples nous pouvons même pré-visualiser les styles de nos items dans le cas de l’utilisation d’une ListBox ou autre contrôle.

De plus, vous avez un visuel sur tous les Styles / Templates de votre projet grâce au Panel de ressources (cf. article précédent).

Ainsi il vous est très facile de factoriser vos Styles et Templates pour une réutilisation dans votre projet !

Les styles implicites

Depuis Silverlight 4 (cette possibilité existait déjà avant avec WPF), les styles implicites sont apparus vous permettant ainsi d’appliquer un style par défaut à vos contrôles. Comment ? Tout simplement en ne renseignant pas la propriété x:Key="NomDuStyle" comme ci-dessous :

<Style TargetType="ListBox">…</Style>

Ainsi le style s’applique par défaut à tous les contrôles de type ListBox !

Bonnes pratiques

Factoriser le code !

Il est préférable de bien centraliser vos styles dans des fichiers spécifiques au lieu de tout mettre dans la page que vous utilisez. Cela vous permettra ainsi de les réutiliser partout dans votre projet c’est ce qu’on appelle la centralisation du code.

A la création d’un nouveau Style, Blend vous demande où générer le Style ce qui est très pratique pour bien centraliser :

#5blend_createressource

Si vous avez créé des “Resources dictionary” vous pourrez alors sélectionner dans laquelle le code de votre ressource sera généré. Vous pouvez même à cette étape créer une Resource dictionary, donc plus aucune excuse pour ne pas bien classer vos styles !

Comment centraliser les styles ?

Vous pouvez par exemple, regroupez vos styles par type de contrôles, si vous en avez beaucoup :

#5blend_resourcesfiles

Cette astuce permet de retrouver très facilement le style ou le template que vous recherchez, bien que le Pannel Ressources vous aide également :

#5blend_ressourcespanel

Factorisez en créant des custom contrôles

Un autre moyen de bien factorisez votre code XAML est de préférer l’utilisation d’un custom contrôle plutôt que d’un user contrôle.

Pourquoi ? Et bien à cause du Style ! En effet, un custom contrôle possède son propre style alors qu’un user contrôle n’est que du code XAML dans un fichier, réutilisable certes mais pas modifiable comme un style. L’avantage d’avoir un style ici, c’est que celui-ci peut être modifié très rapidement pour en créer un second à partir du premier alors qu’un user contrôle vous allez dupliquer du code (dupliquer le user control) pour modifier son apparence visuelle !

A noter que lorsque vous créez un custom contrôle cela engendre la création de deux fichiers :

  • MyCustomControl.cs
  • Themes/generic.xaml (fichier dans lequel on retrouve le style du contrôle créé, ce fichier est créé une seule fois pour x contrôles)

Pour en savoir plus sur les customs contrôles et éviter les erreurs je vous invite à consulter cet article : https://www.geekchamp.com/articles/7-mistakes-developer-make-when-implementing-windows-phone-custom-controls

Conclusion

Nous avons vu qu’il était très facile en un clic de redéfinir un style/template pour vos contrôles dans vos applications XAML. J’espère que cet article vous a redonné envie de redéfinir tous les styles de votre application !

  • Sur Silverlight c’était facile, Microsoft nous a fourni des thèmes à appliquer sur un projet (cf. mon article sur les Themes Silverlight).
  • Sur Windows 8, nous avons sur Codeplex plein de templates de projet vous permettant de sortir un peu de l’ordinaire : https://www.codeproject.com/Articles/616073/60-Design-Templates-for-Windows-Store-Apps
  • Sur Windows Phone, nous n’en avons pas encore ! Est-ce que ce cela vous intéresse ? Un projet de Styles Windows Phone sur Codeplex ? Plutôt sous forme de thème comme Silverlight ou de templates comme sur Windows 8 ? Voici un petit sondage afin de savoir quel type de projet vous intéresse :

Rendez-vous très prochainement pour la suite de la série avec un article sur les DataSamples, très utiles pour réaliser des applications démo en quelques minutes !