Windows Presentation Foundation
Windows Presentation Foundation
Avec l’arrivé de Windows VISTA, on assiste à l’apparition des nouvelles technologies qui
lui sont liées. Que ce soit au niveau affichage (avec Windows Presentation Foundation) ou
bien communication (avec Windows Communication Foundation), en passant par le
système de fichier (Windows File System, WinFS), beaucoup de choses changent.
Cet article a pour but de vous parler de Windows Presentation Foundation, le système
graphique qui sera inclut dans Windows VISTA.
Thomas LEBRUN
[Link] 1
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
WPF fait partie de WinFX, un nouvel ensemble d’API entièrement managées qui seront
introduites dans Microsoft Windows VISTA pour remplacer les API Windows actuelles.
Voici une image qui vous permettra, je l’espère, de bien comprendre l’architecture de WPF :
Thomas LEBRUN
[Link] 2
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Thomas LEBRUN
[Link] 3
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
2. Les pré-requis
Pour pouvoir utiliser une application WinFX, il ne vous faut rien de plus que le Runtime
WinFX.
La CTP de Février 2006 de ce Runtime est disponible à cette adresse :
[Link]
172BFA3B828B&displaylang=en
Si vous souhaitez pouvoir développer des applications WinFX, il va vous falloir plusieurs
choses :
1. Tout d’abord, il vous faut le Runtime WinFX. Là encore, la version de Février 2006
est disponible :
[Link]
474F-86D3-172BFA3B828B&displaylang=en
2. Un outil de développement : même si vous pouvez tout faire à la main, et compiler en
ligne de commande, je vous recommande vivement d’utiliser un IDE (Integrated
Development Environment ou Environnement de Développement intégré, en français)
qui vous permettra de bénéficier des fonctionnalités comme le glisser/déposer de
composants, etc….Pour cela, je vous recommande Visual Studio 2005.
A noter que les versions Express de Visual Studio sont disponibles ici :
[Link] Pour rappel, les versions
Express sont des versions de Visual Studio qui sont limitées à un seul langage qui
possèdent des fonctionnalités réduites mais largement suffisantes.
3. A présent, il vous faut télécharger et installer le SDK de Windows. Celui-ci contient
des API qui vous seront nécessaires pour vos développements, ainsi que de la
documentation, des exemples et des outils. La version de Février 2006 du SDK de
Windows peut-être téléchargée ici :
[Link]
88DD-61E3EF88C402&displaylang=en
4. Une des choses dont vous aurez probablement besoin (mais cela n’est pas obligatoire),
est un ensemble d’outils de développement pour WinFX. Ces outils sont, par exemple,
des Template de projet pour Visual Studio, l’intellisense XAML dans Visual Studio,
etc… A noter qu’un des outils présents dans ce package n’est autre que Cider, le
designer d’interface graphique de WPF ! (On notera que même si le produit est
toujours en développement, on peut tout à fait commencer à l’utiliser pour se faire une
idée de ce qu’il donnera une fois terminé). Pour télécharger et installer ces outils de
développement (ou tout du moins la version de Février 2006), rendez-vous à cette
adresse : [Link]
D7B6-44BC-910D-E91F3E370477&displaylang=en
5. Enfin, si vous travaillez avec Windows Worflow Foundation (un ensemble constitué
d’un modèle de programmation, d’un moteur de workflow et d’outils pour développer
rapidement des applications de workflow sur Windows), alors vous voudrez sans
doute installer, en plus, les extensions de Visual Studio 2005 pour Windows
Workflow Foundation. La version de Février 2006 de ce package est téléchargeable à
sur le site de Microsoft :
[Link]
A707-5883FF4C1DC2&displaylang=en
Thomas LEBRUN
[Link] 4
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Une chose importante à savoir : XAML est un langage de description qui n’est pas dédié à
WPF !
Pour vous permettre de mieux visualiser ce qu’est le XAML, voici un bout de code :
<Window x:Class="DemosWPF.Window1"
xmlns=[Link]
xmlns:x=[Link]
Title="DemosWPF" Height="768" Width="1024"
WindowStartupLocation="CenterScreen"
>
xmlns:x=[Link]
x:Class="DemosWPF.Window1"
Quant aux propriétés, elles correspondent tout simplement aux attributs des éléments du code
XAML. Par exemple, l’attribut Title de l’élément Window correspond tout simplement à la
propriété Title de la classe Window.
Title="DemosWPF"
Thomas LEBRUN
[Link] 5
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Il est également bon de savoir que tout ce que vous développez avec du code XAML peut-
être redéveloppé avec du code, comme le montre cette image :
b. Cider :
Cider est le nom de code du designer d’interface graphique de WPF. Celui-ci, toujours en
version Beta, sera inclu dans Orcas (nom de code de la prochaine version de Visual Studio).
Comme la plupart des designers d’interface graphique, Cider offre la possibilité d’utiliser le
glisser/déposer (Drag&Drop) pour placer vos composants (boutons, labels, listbox, etc….)
au sein de votre formulaires.
Voici quelques captures d’écran de Cider (à ce jour) et des différents contrôles qui sont
d’ores et déjà pris en charge :
La fenêtre principale :
Thomas LEBRUN
[Link] 6
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Cider apparaît donc comme un outil à la fois simple et très puissant, qui vous permet de
développer, rapidement, des interfaces graphiques complexes.
c. La gamme Expression :
Nous l’avons vu précédemment, un des objectifs de WPF est de permettre une meilleure
collaboration entre les designers et les développeurs.
Pour cela, Microsoft a sortit une nouvelle gamme de produits : la gamme Expression.
Cette gamme est composée de trois logiciels destinés, principalement, aux designers et aux
graphistes :
Thomas LEBRUN
[Link] 7
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
La fenêtre principale :
Thomas LEBRUN
[Link] 8
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Thomas LEBRUN
[Link] 9
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Comme souvent, les contrôles WPF possèdent des propriétés, des évènements et des
méthodes.
On retrouve beaucoup de contrôles standards dans WPF : les boutons, les labels, les textbox,
etc…
Bien sur, la grande nouveauté des contrôles WPF est qu’ils peuvent contenir n’importe quoi :
on a donc la possibilité de personnalisé complètement le rendu d’un contrôle WPF.
En effet, ce sont des éléments fonctionnels auquels on applique un style et qu’il est possible
de combiner avec d’autres grâce au système de template.
Par exemple, le bout de code suivant permet d’insérer simplement une image dans un bouton :
On a réussi à personnaliser un bouton de façon très simple et avec très peu de lignes de code ;
ce qui nous aurait pris beaucoup plus de temps si nous avions du faire la même chose en C#
ou en [Link], dans une application WindowsForms classique.
Afin de bien comprendre comment fonctionnent les contrôles WPF, je vous recommande de
regarder cette image (extraite des slides de la PDC 2005) :
Thomas LEBRUN
[Link] 10
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Ici, vous avez une description complète de l’architecture des contrôles, dans Windows
Presentation Foundation.
On peut donc décomposer chaque contrôle WPF sous forme de graphes d’objets, jusqu'à
obtenir un ensemble de données qui seront affichées à l’écran.
La propriété Content des contrôles WPF remplace la propriété Text des contrôles
« classiques », mais vous permet bien plus. En effet, c’est grâce à cette propriété Content, qui
est mappée sur les enfants d’un nœud XAML, que vous allez pouvoir faire « ce que vous
voulez » avec votre contrôle : ajouter une image, une vidéo, etc….
Vous allez même pouvoir aller plus loin. En effet, si vous étudiez bien cette propriété, vous
vous rendrez compte qu’elle est de type object. Ainsi, vous avez la possibilité de lui assigner
n’importe quel objet (objet métier, etc..).
b. Les ressources
Chaque composant WPF possède une propriété Resources qui, comme son nom l’indique,
permet de définir les ressources qui lui seront associées.
Par ressources, on entend beaucoup de choses :
o les styles (définissent l’apparence d’un contrôle),
o les templates (permettent de définir comment afficher les données affectées à
un contrôle),
o les animations
o les transformations (rotation, etc…)
Ces ressources vous permettent d’avoir accès et donc de réutiliser des objets définis pour
l’ensemble de votre application
Voici un exemple dans lequel on définit, dans les ressources d’une Grid, le style qui sera
appliqué à des contrôles de type Button. Si vous ne comprenez pas ce code, ne vous inquiétez
pas : nous y reviendrons plus en détails juste après, dans la partie traitant des Styles.
<Grid>
<!—
Dans les ressources de la grille
-->
<[Link]>
<!—
On definit un style, qui sera appliqué au type définit
On définit la propriété à modifier et la valeur à lui appliquer
-->
<!—
Thomas LEBRUN
[Link] 11
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Ainsi, on se rend compte que les ressources de nos contrôles peuvent facilement être
assimilées aux fichiers CSS des applications Web : bien que toujours interne à notre
application, on « externalise » tout ce qui concerne le design/l’apparence pour se concentrer
uniquement sur les fonctionnalités.
Il n’est plus nécessaire de spécifier, pour chaque type de contrôle, le style ou le template à
appliquer : en passant par les ressources, vous pouvez définir un style (ou un template)
spécifique à chaque type de contrôle, et l’appliquer lors de la déclaration de ceux-ci.
c. Les styles
Nous l’avons vu précédemment : les styles permettent de définir l’apparence de vos contrôles.
Nous avons également vu comment définir un style :
Au moyen de l’élément Style, on indique que l’on veut définir un style.
Ensuite, c’est très simple : il ne nous reste plus qu’à utiliser des Setter, qui vont nous servir à
définir la propriété à modifier (grâce à la propriété Property) et la valeur à lui attribuer
(propriété Value).
Et voilà, à partir de ce moment là, il ne vous reste plus qu’à attribuer, à un de vos contrôles, le
style que vous venez de définir. Pour cela, il vous faut juste « lier » la propriété Style de votre
contrôle au style que vous venez de créer.
Notez bien que pour trouver à quel style on veut se lier, nous devons :
o utiliser l’attribut Key de notre style
o utiliser l’attribut TargetType, qui nous permet d’indiquer pour quel type de
contrôle ce style sera valable.
L’exemple ici n’est pas des plus pertinents, mais il a l’avantage de vous permettre de bien
vous rendre compte du rendu de l’application du style à notre bouton.
Thomas LEBRUN
[Link] 12
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Autre point important : Vous avez la possibilité de créer un style à partir d’un autre style, ce
qui a l’énorme avantage de vous permettre de ne pas refaire plusieurs fois le même travail et
de pouvoir partir sur une base déjà existante.
Pour cela, il vous faudra utiliser l’attribut BasedOn, lors de la déclaration de votre style, et lui
indiquer le style sur lequel vous souhaitez vous baser.
Voyons un exemple :
<!—
Style basé sur un autre
-->
<Style TargetType="{x:Type Button}" x:Key="MonStyleHerite"
BasedOn="{StaticResource MonStyleDePolice}">
<Setter Property="[Link]" Value="Green" />
</Style>
Dans cet extrait de code, on voit bien que l’on redéfinit un style, qui porte la « clé »
MonStyleHerite, et qui se base sur notre style précédemment définit, MonStyleDePolice.
On peut donc affirmer que les styles, dans WPF, s’avèrent très utiles et très puissants et
permettent de réaliser des applications dont vous pouvez entièrement modifier le
design/l’apparence.
d. Les templates
Les Templates sont utilisés pour décrire la structure visuelle d’un contrôle. Pour cela, les
contrôles WPF présentent la propriété Template, qui vous permettra donc d’associer un
template, que vous avez définit, à un contrôle.
Pour appliquer un template, la syntaxe est la même que pour appliquer un style :
Thomas LEBRUN
[Link] 13
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Comme vous pouvez le voir, on utilise un élément de type ControlTemplate pour définir le
template, autrement dit la façon dont notre contrôle sera affiché : simple non ? ☺
Nous aurions également pu passer par un style pour définir la propriété Template de notre
contrôle :
Je vous épargne la capture d’écran, étant donné qu’elle donne le même résultat que la capture
précédente ;)
Les DataTemplates sont utilisées pour définir une représentation visuelle d’un objet de
données. On peut donc dire que les DataTemplates permettent à une application d’afficher à
l’écran des objets non-visuels, autrement dit des objets de données.
Thomas LEBRUN
[Link] 14
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
class MyPhoto
{
private int m_IdPhoto;
Comme vous pouvez le constatez, cette classe ne comporte aucun élément visuel. Nous allons
donc utiliser un DataTemplate pour définir la façon dont les éléments de type MyPhoto
devront être affichés :
Ainsi, nous définissons le fait que tous les éléments de types MyPhoto doivent être affichés
sous forme d’une image, qui aura sa source « bindée » (liée) à la propriété Filename de notre
source de données.
La conséquence de ceci est simple : dès qu’un objet de type MyPhoto sera détecté dans votre
application, c’est ce template qui sera appliqué à cet objet.
Attention tout de même : Pour pouvoir réaliser à bien cette opération, il nous a fallut mapper
le type MyPhoto au XAML, au moyen de l’attribut xmlns :
<Window x:Class="DemosWPF.Window1"
xmlns:x="[Link]
xmlns=[Link]
Title="DemosWPF" Height="768" Width="1024"
xmlns:m="clr-namespace:DemosWPF"
>
e. Les triggers
Les Triggers sont utilisés conjointement avec les styles et les templates, afin de réaliser des
applications proposant des interactions riches et dynamiques.
Thomas LEBRUN
[Link] 15
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Il faut également savoir que WPF vous permet de vérifier trois choses dans les conditions
d’un trigger :
o une « Property Dependency » (utilisation de Trigger)
o une propriété .NET (utilisation de DataTrigger)
o un événement (utilisation d’EventTrigger)
Dans le cas des deux premières conditions, le trigger est déclenché lorsque la propriété
spécifiée est modifiée.
Dans le dernier cas, le trigger est déclenchée lorsque l’évènement indiqué survient (par
exemple, le clic sur un bouton)
Pour modifier la valeur d’une propriété, dans un trigger, vous devez là encore utiliser
l’élément Setter :
<!—
On utilise un Trigger sur ce style pour faire en sorte de
changer la couleur du fond lorsque la
souris est sur le bouton
-->
<[Link]>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="[Link]" Value="Red" />
</Trigger>
</[Link]>
Dans cet exemple, nous ajoutons un Trigger qui sera déclenché lorsque la propriété
IsMouseOver passera à vrai. Dans ce cas, on change la propriété Background de notre
bouton, pour la faire passer à rouge.
Bien entendu, vous avez la possibilité d’utiliser plusieurs Triggers dans un style, ceci afin de
permettre la modification de multiples propriétés lors du changement des valeurs de
différentes propriétés :
<!—
On utilise un Trigger sur ce style pour faire en sorte de
changer la couleur du fond lorsque la
souris est sur le bouton
-->
<[Link]>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="[Link]" Value="Red" />
</Trigger>
<Trigger Property="IsFocused" Value="True">
<Setter Property="[Link]" Value="Green" />
</Trigger>
</[Link]>
Thomas LEBRUN
[Link] 16
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Vous pouvez également ajouter des triggers qui ne s’exécuteront que sous certaines
conditions. Pour cela, vous devez utiliser un MultiTrigger, dans lequel vous spécifier, dans
l’élément Conditions, les différentes conditions qui doivent être remplies pour que votre
trigger s’exécute :
<MultiTrigger>
<[Link]>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="IsFocused" Value="True" />
</[Link]>
Dans cet exemple, on s’assure que les propriétés IsMouseOver et IsFocused sont bien à
vrais. Si ces deux conditions sont bien remplies, alors on change la propriété Foreground de
notre bouton.
Prenez garde à ne pas oublier que ces types de triggers ne s’exécutent que si toutes les
conditions sont vérifiées : dans le cas contraire, le trigger ne fonctionnera pas.
Après avoir vu les triggers de propriétés, attardons nous un instant sur les triggers de données
(DataTriggers) pour voir à quel point ils peuvent s’avérer pratiques.
En effet, si les triggers de propriétés ne peuvent effectuer de vérifications que sur les
« Property Dependencies », les DataTriggers ont la possibilité de pouvoir effectuer des
vérifications sur n’importe quelle propriété d’un objet .NET.
Tout comme les DataTemplate, les DataTriggers sont utilisés avec les objets « non visuels » :
ils peuvent donc vérifier les propriétés de n’importe quel objet .NET « non visuel ».
Reprenons notre classe MyPhoto et imaginons, par exemple, que l’on souhaite effectuer une
action lorsque l’identifiant d’une photo est égal à une valeur donnée. Dans ce cas, on ne peut
pas utiliser de Trigger simple, pour la simple et bonne raison que MyPhoto n’est pas un objet
que l’on peut représenter visuellement : la propriété IdPhoto (qui sert à connaitre l’identifiant)
est donc une propriété qui, elle aussi, ne peut être définie visuellement. Par conséquent, si l’on
souhaite faire une vérification sur une propriété de ce type, il nous faut utiliser un
DataTrigger.
Cette notion pouvant paraitre compliquée, voici un exemple qui vous aidera, je l’espère, à
mieux comprendre de quoi il s’agit :
Dans cet exemple de DataTrigger, on fait un test sur la propriété IdPhoto de notre source de
données. On teste, en effet, si la valeur de cette propriété est égale à un. Dans ce cas, on fait
changer la couleur du texte de notre bouton.
On voit tout de suite que, si les triggers de propriétés agissent sur le style, l’apparence des
objets, les triggers de données eux agissent sur le contenu des objets.
Thomas LEBRUN
[Link] 17
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Le dernier point qu’il nous reste à voir à propos des triggers concerne les EventTriggers,
autrement dit les triggers qui sont déclenchés suite à un événement.
En effet, dès qu’un événement survient, tel que l’événement Click d’un bouton, un
EventTrigger est déclenché en réponse à cet événement.
Nous allons à présent voir un autre élément important dans l’utilisation des EventTriggers,
les StoryBoards.
f. Les storyboards
Les StoryBoards sont des éléments XAML qui vous permettent de définir un ensemble
d’actions.
On peut donc dire que les Storyboards sont un ensemble d’animations/transformations, qui
vous offre la possibilité de pouvoir définir le temps que doivent durer vos animations, la
propriété à modifier sur votre objet, etc….
Thomas LEBRUN
[Link] 18
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
• La propriété TargetName :
Cette propriété est utilisée pour définir la cible, autrement dit l’objet,
que l’on désire manipuler. Il peut s’agir d’un élément, d’une rotation,
etc…
• La propriété TargetProperty
Cette propriété, quand à elle, est utilisée pour indiquer, sur notre
cible, quelle est la propriété que l’on souhaite manipuler : un angle,
une taille, etc….
On a donc repris le code utilisé précédemment, mais nous y avons ajouté plusieurs éléments :
• un élément BeginStoryboard, utilisé pour démarrer un Storyboard
• un élément Storyboard, qui servira à indiquer que l’on souhaite
déclarer un nouveau Storyboard
Dans la déclaration de notre élément Storyboard, nous avons utilisé les deux propriétés vues
juste avant, afin d’indiquer avec quel objet nous désirons travailler, et plus précisément quelle
propriété de cet objet nous allons modifier lors de l’exécution de notre Storyboard.
Bien entendu, l’élément Storyboard possède d’autres propriétés intéressantes, que nous allons
voir tout de suite :
Bien sûr, il existe d’autres propriétés mais le but de cet article n’est pas de vous en faire la
liste.
Maintenant que nous avons vu à quoi servent les StoryBoards, nous allons voir quels sont les
éléments qu’il est commun d’utiliser afin d’animer vos boutons, TextBox, etc…
Vous pouvez utiliser, pour cela, des animations et des transformations, que nous allons voir
un peu plus en détails maintenant.
g. Les animations
Dans vos applications WPF, vous avez la possibilité d’utiliser des animations, qui vous
permettront d’animer vos contrôles.
Par exemple, vous allez pouvoir faire en sorte que pendant 10 secondes, la taille d’un bouton
augmente, etc….
Bref, les possibilité offertes par les animations WPF sont énormes, et ne doivent pas être
négligées si vous voulez réaliser des applications au design et à l’interaction utilisateur
innovante !
Pour manipuler un élément, et plus précisément la propriété d’un élément, vous devez utiliser
les deux propriétés que nous avons vues précédemment : TargetName et TargetProperty.
Ici, on utilise une DoubleAnimation pour modifier la valeur de la propriété Width de notre
contrôle nommé m_BoutonAnime.
On notera au passage l’utilisation de la propriété SpeedRatio, qui vous permet de spécifier à
quelle vitesse doit s’exécuter votre animation.
Voici une liste des différentes animations possibles que vous pouvez utiliser dans vos
applications WPF :
o ByteAnimation : Ce type d’animation vous permet d’animer la valeur d’une
propriété de type Byte,
o ColorAnimation : Vous permet d’animer la valeur d’une propriété de type
Color,
o DoubleAnimation : Est utilisé pour animer la valeur d’une propriété de type
Double,
o Etc…
Thomas LEBRUN
[Link] 20
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Nous allons maintenant voir les KeyFrames, qui peuvent être utilisés avec vos animations.
Les KeyFrames sont utilisés pour définir des « étapes » lors de votre animation.
En effet, vous allez pouvoir définir une animation qui dure, au total, 10 secondes, et indiquer
qu’une animation doit se produire à 2 secondes, une autre animation doit être déclenchée à 7
secondes, etc…. Tout cela, en utilisant des KeyFrames, sorte de point d’arrêt de vos
animations.
<DoubleAnimationUsingKeyFrames SpeedRatio="5"
[Link]="m_BoutonAnime"
[Link]="Width" Duration="[Link]">
<LinearDoubleKeyFrame KeyTime="[Link]" Value="360" />
</DoubleAnimationUsingKeyFrames>
Comme vous pouvez le voir, les KeyFrames sont relativement simples à utiliser. Et, dans une
animation qui utilise les KeyFrames, rien ne nous empêche d’utiliser plusieurs « étapes » en
même temps :
<DoubleAnimationUsingKeyFrames SpeedRatio="5"
[Link]="m_BoutonAnime"
[Link]="Width" Duration="[Link]">
<LinearDoubleKeyFrame KeyTime="[Link]" Value="360" />
<LinearDoubleKeyFrame KeyTime="[Link]" Value="500" />
</DoubleAnimationUsingKeyFrames>
Maintenant, si vous voulez utiliser plusieurs animations en même temps, vous serez tentez
d’écrire quelque chose comme cela :
Thomas LEBRUN
[Link] 21
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
<ParallelTimeline>
<DoubleAnimation SpeedRatio="5"
[Link]="m_BoutonAnime"
[Link]="Width" From="0" To="200" />
<DoubleAnimation SpeedRatio="5"
[Link]="m_BoutonAnime"
[Link]="Height" From="0" To="200" />
</ParallelTimeline>
Maintenant que nous avons vu les animations, et leur fonctionnement, jetons un œil sur les
transformations.
h. Les transformations
Les transformations sont l’autre élément que vous pouvez utiliser si vous souhaitez donner
plus de vie à vos applications.
Les TranslateTransform, tout d’abord, sont utilisées pour translater un objet. On indique
donc la position en X et la position en Y que notre objet doit avoir, par rapport à son point de
départ, et on assiste ainsi à son déplacement.
Voici un petit exemple :
Thomas LEBRUN
[Link] 22
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Comme celui-ci n’est sans doute pas très parlant, voici une capture d’écran du résultat :
Les RotateTransform sont des transformations qui vous permettent de réaliser, comme vous
le devinez surement, des rotations. Là encore, un bout de code et une image seront plus
explicites qu’un long roman :
Comme vous pouvez le voir, il vous suffit de spécifier les coordonnées en X et en Y du point
de rotation. Ensuite, grâce à l’attribut Angle, vous spécifier de quelle valeur vous voulez
effectuer la rotation de votre contrôle.
Thomas LEBRUN
[Link] 23
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Ici, nous avons utilisé un ScaleY négatif pour faire en sorte que notre rectangle soit inversé.
Thomas LEBRUN
[Link] 24
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Comme vous pouvez le constater, cette transformation est particulière, dans le sens où il s’agit
à la fois d’une rotation et d’un basculement du rectangle. Cela n’est pas possible autrement
qu’en passant par une MatrixTransform.
Un autre type de transformation qui est disponible dans WPF est la SkewTransform.
Ce type de transformation est utilisé pour faire pivoter votre contrôle suivant un ou deux
axes : l’axe des X et l’axe des Y.
Grâce à l’attribut AngleX, vous allez pouvoir spécifier le degré d’inclinaison de votre
contrôle, par rapport à l’axe des Y.
Inversement, l’attribut AngleY vous permet de définir le degré d’inclinaison de votre
contrôle, par rapport à l’axe des X.
Thomas LEBRUN
[Link] 25
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Bien entendu, rien ne vous empêche d’utiliser les deux axes (X et Y) pour appliquer votre
transformation :
Comme vous l’imaginez surement, on peut très vite arriver à créer des transformations qui
donneront à vos applications un style plutôt impressionnant ;)
Thomas LEBRUN
[Link] 26
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Pour finir les transformations, il ne me reste plus qu’a vous parler des TransformGroup.
En effet, vous ne pouvez pas utiliser deux transformations simultanément de cette façon.
Pour pouvoir le faire, vous devrez utiliser (vous l’avez compris je suppose), les
TransformGroup.
Et là, plus de problèmes ! Vous pouvez utiliser un, deux, trois, etc… bref, autant de
transformations que vous voulez, tant que celles-ci sont comprises dans un
TransformGroup.
Thomas LEBRUN
[Link] 27
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
i. WPF et la 3D
L’une des grandes forces de WPF est de pouvoir utiliser non seulement des objets 2D, mais
également des objets en 3D (trois dimensions).
Vous allez donc pouvoir utiliser dans vos applications des objets qui, habituellement, ne sont
utilisables qu’en deux dimensions (par exemple, une image, une ListBox, etc…)
Note : Travailler avec des objets en trois dimensions n’est pas une chose aisée et nécessite
quelques connaissances préalables sur le sujet. Je vais tenter de rendre cette partie la plus
simple et la plus claire possible, mais n’hésitez surtout pas à consulter la documentation du
SDK (Software Development Kit) pour de plus amples informations, plus « techniques » sur le
sujet.
L’objet qui va nous permettre de mettre un peu plus de dimension dans nos applications est un
objet particulier, le Viewport3D, qui fonctionne comme une fenêtre classique, mais en trois
dimensions.
Avant de commencer, voici une image qui va vous permettre de comprendre comment
visualiser les axes des coordonnées X, Y et Z, dans un plan en trois dimensions, par rapport à
un plan en deux dimensions :
Parce qu’une même scène en trois dimensions semble différente suivant le point de vue
(autrement dit la position) de celui qui la regarde, vous devez, au moyen de la classe Camera,
spécifier ce point de vue pour une scène 3D.
Vous allez pouvoir spécifier, pour une Camera, sa position dans le plan en trois dimensions,
sa direction, son champ de vision (il s’agit d’un angle), et un vecteur qui définit le haut de la
scène.
Le schéma suivant vous permettra de mieux comprendre de quoi il s’agit :
Thomas LEBRUN
[Link] 28
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Ici, on s’aperçoit que la caméra est centrée sur l’axe des Z, qu’elle regarde dans la direction
inverse de l’axe des Z (donc dans la direction –Z), et que le haut de la scène est définit à +Y.
Vous pouvez utiliser plusieurs types de Camera mais nous allons en voir deux plus en détails :
o la PerspectiveCamera
o l’OrthograficCamera
La PerspectiveCamera, tout d’abord, nous permet de définir une caméra qui se « projette »
autour de la scène. Le schéma ci-dessus représente justement le dessin d’une
PerspectiveCamera.
L’OrthograficCamera, quand à elle, définit une projection orthogonale d’un modèle en trois
dimensions, vers une surface visuelle en deux dimensions.
Ce type de caméra est très similaire à la PerspectiveCamera : en effet, là encore vous allez
pouvoir spécifier une direction, un point de vue, etc….Cependant, L’OrthograficCamera
définit une vue dont les cotés sont parallèles au lieu d’une vue dont les cotés finissent par se
rejoindre en un point.
Pour bien comprendre cette notion, observez le dessin suivant :
Dans le premier cas, les cubes sont alignés, grâce à une OrthograficCamera, de façon à ce
qu’ils soient tous parallèles.
Dans le deuxième cas, on voit bien que, à l’aide d’une PerspectiveCamera, on a disposé les
cubes de façon à ce que ceux-ci ne soient pas parallèles.
Pour vous en convaincre, regardez cette image, qui vous montre bien que, dans un cas, les
deux traits ne se rejoindront jamais (utilisation d’une OrthograficCamera), tandis que dans
le deuxième cas, ils ne tarderont pas à se croiser (utilisation d’une PerspectiveCamera) :
Pour faire simple, retenez qu’avec une OrthograficCamera, la distance d’un objet n’influe
pas sur sa taille à l’écran.
Maintenant que nous avons vu la théorie, voyons un peu la pratique, pour apprendre comment
utiliser (entre autre) les Viewport3D ainsi que les Camera.
Thomas LEBRUN
[Link] 29
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
<!--
On ajoute une caméra pour la vue 3D
-->
<Viewport3D Focusable="True" ClipToBounds="True"
Name="ViewPortLisBox3D">
<[Link]>
<PerspectiveCamera
FarPlaneDistance="50"
UpDirection="0,1,0"
NearPlaneDistance="1"
Position="0.0,2.5,10.0"
LookDirection="0.0,-2.5,-9.0"
FieldOfView="45" />
</[Link]>
</Viewport3D>
Voici un petit aperçu de ce que vous pouvez obtenir : pour l’exemple, j’ai utilisé un
composant particulier, une ListBox dans laquelle on peut stocker des vidéos et où les éléments
sont disposés autour d’un cylindre. Je vous laisse apprécier le résultat :
Thomas LEBRUN
[Link] 30
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Vous avez également la possibilité d’illuminer votre scène, c’est-à-dire de rendre certaines
surfaces de votre scène visible. Pour cela, il vous faut utiliser des objets de la classe Ligth, tel
que :
o AmbientLigth, qui fournit une lumière ambiante, utilisée pour illuminer tous les
objets de la scène, quelque soit leur position ou leur orientation :
o PointLigth, qui est utilisé pour illuminer un point de votre scène. Les objets de la
scène seront illuminés en fonction de leur position et de leur distant. L’attribut Range
est utilisé pour spécifié à partir de quelle distance la lumière n’a plus d’effet :
o SpotLigth, qui hérite de PointLigth, projette une lumière via un cône, dont vous
définissez la taille du point de départ et celle du point d’arrivée :
Thomas LEBRUN
[Link] 31
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Un autre objet fort utile, lorsque vous faîte de la 3D, est le ScreenSpaceLine3D.
Cet objet vous permet de créer des polygones en trois dimensions. Utilisé correctement, il
peut vous permettre de dessiner beaucoup de figure géométrique :
Ici, nous utilisons un ScreenSpaceLine3D pour créer une simple ligne, de couleur bleue.
Avec l’attribut Thickness, nous définissons l’épaisseur du trait qui sera utilisé pour afficher
notre ligne.
L’attribut Points nous permet de définir les points de notre figure.
Maintenant, si vous souhaitez pouvoir utiliser plusieurs éléments pour animer vos objets en
trois dimensions, vous allez être obligé d’utiliser un Model3DGroup :
Dans cet exemple, on utilise un Model3DGroup pour insérer, dans notre application, quatre
ScreenSpaceLine3D qui nous serviront à tracer des traits.
Maintenant que nous avons vu comment fonctionne la 3D dans WPF, comment l’implémenter
et comment utiliser certains des objets disponibles pour rendre votre application un peu plus
« réelle », nous allons voir différentes techniques pour effectuer des transformations sur vos
objets 3D.
Thomas LEBRUN
[Link] 32
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Nous avons déjà vu, dans les chapitres précédents, qu’il existe plusieurs objets pouvant servir
à effectuer des transformations sur votre objets 2D :
o les TranslateTransform
o les RotateTransform
o les ScaleTransform
o les MatrixTransform
o les SkewTransform
o les TransformGroup
Et bien sachez que certaines de ces transformations sont également disponible pour les objets
en 3 dimensions :
o les TranslateTransform3D
o les RotateTransform3D
o les ScaleTransform3D
o les MatrixTransform3D
o les Transform3DGroup
Vous l’aurez compris, nous allons nous attarder sur certaines de ces modifications, afin de
vous permettre de comprendre leur comportement et leur utilisation, même si celles-ci sont
très semblables à leur équivalent en deux dimensions.
Les TranslateTransform3D sont utilisées pour permettre à vos objets 3D d’effectuer des
translations dans le plan à trois dimensions.
Regarder cette image pour vous permettre de comprendre de quoi il s’agit :
Thomas LEBRUN
[Link] 33
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Les TranslateTransform3D possèdent plusieurs attributs, dont les attributs OffsetX, OffsetY,
et OffsetZ, qui nous permettent d’indiquer quelles seront les coordonnées de notre objet,
après la translation.
Jetons maintenant un œil sur les RotateTransform3D, qui vous permettront d’effectuer, sur
vos objets 3D, des rotations. Dans ce type de transformation, il est commun de spécifier l’axe
et l’angle de rotation. Vous utilisez, pour cela, une Rotation3D et plus précisément, la
propriété Rotation de cette classe :
Comme vous pouvez le constater, l’axe de rotation est définit ici au moyen de la propriété
Axis, qui prend en paramètre un ensemble de 3 points servant à indiquer les coordonnées de
notre axe. La propriété Angle permet de spécifier l’angle de rotation de notre axe.
Thomas LEBRUN
[Link] 34
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Pour appliquer une transformation de type ScaleTransform3D, vous devez spécifier la valeur
des axes X, Y et Z à partir d’un point central. Voyons, par exemple, le code qui a été utilisé
pour générer le cube le plus petit :
Si vous voulez multiplier les transformations sur des objets 3D, vous devez utiliser des
Transform3DGroup. Ceux-ci vous permettent de manipuler, une à plusieurs
transformations, en même temps.
Thomas LEBRUN
[Link] 35
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Au travers de cette partie, j’ai tenté de vos expliquer les différents concepts et mises en œuvre
sur tout ce qui touche à la 3D dans WPF. Comme je vous l’ai dit au début, cette partie est
sans doute l’un des plus complexes à maitriser, surtout si vous n’en avez jamais fait
auparavant.
Cependant, des outils sont là pour vous aider : j’ai déjà cité Sparkle, mais sachez qu’il existe
aussi un outil, développé par ElectricRain ([Link] qui se nomme ZAM3D et
qui vous permet de réaliser, très simplement, des éléments d’interface en trois dimensions.
Thomas LEBRUN
[Link] 36
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
j. Le binding
Pour comprendre le DataBinding, dans WPF, une notion est importante à comprendre et à
bien maîtriser :
Il s’agit du DataContext : dans WPF, ce terme représente un concept, qui autorise les
éléments enfants à hériter de l’information de leur élément parent.
<Grid>
<[Link]>
//
</[Link]>
</Grid>
De cette façon, tous les éléments insérés dans la grille (représentée par le contrôle Grid)
auront pour source de données l’objet que vous aurez indiqué dans l’attribut DataContext.
Même si cela peut vous paraitre complexe pour le moment, je vais tenter de clarifier la chose
par la suite, avec d’autres exemples un peu plus parlants.
Attardons maintenant sur un objet bien pratique pour interroger une source de données au
format XML : le XmlDataProvider.
Voyons directement un exemple, qui sera plus parlant que des dizaines de lignes de texte :
<Grid>
<[Link]>
<XmlDataProvider
Source="[Link]
x:Key="MyXmlRssSource" />
</Grid. Resources >
</Grid>
Comme vous pouvez le constater, cet objet est relativement simple à utiliser: il vous suffit
d’indiquer l’endroit où se situe la source des données, au moyen de l’attribut Source, et
éventuellement, la requête XPath que vous voulez effectuer, toujours au moyen d’un attribut,
l’attribut XPath.
Une fois votre source de données définie, il ne vous reste plus qu’à la lier à votre grille (ou
autre composant). Pour cela, vous allez utiliser l’attribut DataContext, que nous avons vu
juste avant !
<Grid>
<[Link]>
<Binding Source="{StaticResource MyXmlRssSource}"
XPath="/rss/channel" />
</[Link]>
</Grid>
Ici, nous définissons que la source de données communes à tous les enfants de notre grille
sera en fait notre source de données au format XML.
Thomas LEBRUN
[Link] 37
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
A partir de là, il ne vous reste plus qu’à lier les propriétés qui vous intéressent en faisant du
Binding (liaison de données).
L’exemple suivant est suffisament complet et commenté pour parler de lui-même. Je signale
simplement qu’il s’agit d’un simple lecteur RSS développé en quelques minutes à peine :
<Grid>
<[Link]>
<XmlDataProvider
Source="[Link]
x:Key="MyXmlRssSource" />
<!—
On définit un DataTemplate pour notre ListBox:
On choisit donc la façon dont seront afficher les
données
On utilise un TextBlock dont la propriété Text est
bindée à l'élément title
car le context de la ListBox, dans le DataTEmplate, est
la collection d'item
-->
<DataTemplate x:Key="MyListBoxItemTemplate">
<TextBlock Text="{Binding XPath=title}" />
</DataTemplate>
</Grid. Resources >
<[Link]>
<Binding Source="{StaticResource MyXmlRssSource}"
XPath="/rss/channel" />
</[Link]>
<[Link]>
<ColumnDefinition Width="0.4*" />
<ColumnDefinition Width="0.6*" />
</[Link]>
<DockPanel [Link]="0">
<!—
On indique la source de données de notre ListBox et
son ItemTemplate
-->
<ListBox ItemsSource="{Binding XPath=item}"
ItemTemplate="{StaticResource MyListBoxItemTemplate}"
x:Name="MyListBoxOfRss" IsSynchronizedWithCurrentItem="True"
SelectedIndex="0" />
</DockPanel>
<DockPanel [Link]="1">
<!—
Le DataContext de notre TextBlock correspond à
l'item sélectionné dans la ListBox
Et on binde le texte sur le description de cet
élément.
-->
<TextBlock DataContext="{Binding
ElementName=MyListBoxOfRss, Path=SelectedItem}" Text="{Binding
XPath=description}" x:Name="TextBlocDescription" />
</DockPanel>
</Grid>
Thomas LEBRUN
[Link] 38
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Voyons maintenant un autre objet fort utile lorsque vous faites du Databinding :
l’ObjectDataProvider.
Cet objet propose les mêmes fonctionnalités, et même bien plus, que l’ObjectDataSource,
disponible dans le Framework .NET 2.0.
En effet, grâce à lui, vous allez pouvoir définir un objet comme étant la source de vos
données, mais vous allez également pouvoir :
o passer des paramètres au constructeur de votre objet (celui utilisé comme source de
données)
o vous lier à une méthode (qui peut, ou non, prendre des paramètres)
o remplacer l’objet qui sert de source de données
o créer l’objet servant de source de données de façon asynchrone
Avant d’allez plus loin dans les détails, voici un exemple, simple, de déclaration d’un
ObjectDataProvider :
(J’ai repris, pour cet exemple, la classe MyPhoto que j’ai introduit lors de la partie 4D).
Avec ce code, nous définissons une source de données, qui s’appellera MyPhotoDSO, et, au
moyen de l’attribut ObjectType, nous définissons le type des données à utiliser comme
source (dans notre cas, des données de type MyPhoto).
Etudions donc maintenant, d’un peu plus près, les fonctionnalités avancées offertes par cet
objet.
Avec cet attribut, qui est en fait une collection, vous pouvez spécifier l’ensemble de
paramètres à passer à votre constructeur, en indiquant leur type (Int32, String, Float, etc…).
A noter que le type des paramètres est précédé du namespace s. Pour rappel, cet espace de
nom est déclaré lors de la déclaration de notre élément Window :
<Window x:Class="DemosWPF.Window1"
xmlns=[Link]
xmlns:x=[Link]
Title="DemosWPF" Height="768" Width="1024"
WindowStartupLocation="CenterScreen"
xmlns:s="clr-namespace:System;assembly=mscorlib"
>
Thomas LEBRUN
[Link] 39
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Ici, on créé un DataTemplate, qui nous servira à définir comment nous devons afficher les
éléments de type MyPhoto. On indique que ces éléments doivent être affichés dans un
contrôle de type Image, dont la source est liée à notre source de données, nommée
MyPhotoDSO et plus particulièrement, à la propriété SourcePhoto.
Et voila ! A partir de là, vous avez spécifié que vous vouliez utiliser un objet de type
MyPhoto, et plus précisément l’objet qui a comme propriété l’identifiant ayant pour valeur
« 1 » et la description, avec comme valeur « Ma photo ». Ainsi, lors de la liaison
(« Binding »), on ne va afficher qu’une photo, celle dont les paramètres ont été passés en
paramètre.
Voyons maintenant la possibilité qui nous est offerte, par l’ObjectDataProvider, de nous lier
(« binder ») à une commande.
Là encore, nous allons devoir utiliser plusieurs attributs particuliers :
o MethodName, prend en paramètre le nom de la méthode à laquelle vous voulez vous
lier. Autrement dit, vous spécifier ici le nom de la méthode, sur votre objet, que vous
voulez exécuter.
o ObjectInstance, vous permet d’indiquer l’instance, en cours d’exécution, avec
laquelle vous voulez travailler.
o MethodParameters, représente la collection de paramètres que vous pouvez,
éventuellement, passer à votre méthode.
Pour concrétiser cette théorie, reprenons notre classe MyPhoto et ajoutons-y une méthode qui
va afficher les informations sur la photo dont l’identifiant est passé en paramètre:
Voyons comment nous pouvons nous lier à cette méthode. Pour cela, il nous faut créer un
autre ObjectDataProvider :
Thomas LEBRUN
[Link] 40
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Pour utiliser cet objet nouvellement créé, voici comment nous pouvons faire :
Imaginez ce scénario :
Vous avez à votre disposition une ListBox dont la source de données est liée à une collection
d’images. Comment pourriez-vous faire pour changer le type des éléments de votre source de
données, et utiliser des chaines des caractères à la place des images ?
Une solution serait de créer deux sources de données (une pour les images et une pour les
chaines de caractères), et de sélectionner l’une ou l’autre selon vos besoins.
Mais la solution la plus élégante est très certainement d’utiliser un ObjectDataProvider et de
modifier, dynamiquement, la valeur de sa propriété ObjectType.
En effet, si celle-ci est modifiée, votre ObjectDataProvider sera aussitôt averti que la source
de données à changer et se mettra à jour automatiquement.
Pour finir cette partie, nous allons voir, rapidement, comment nous pourrions faire pour créer
notre objet, source de données, de façon asynchrone.
Vous aurez sans doute remarquez l’un des attributs possibles de l’ObjectDataProvider :
IsAsynchronous="True"
Celle-ci vous permet d’indiquer si vous désirez que le chargement de vos données se déroule
dans le même thread que votre application, ou bien dans un thread différent.
A noter que, par défaut, l’ObjectDataProvider est synchrone et le XmlDataProvider est
asynchrone.
Note : Je n’ai traité ici qu’une partie du DataBinding avec Windows Presentation Foundation.
Le domaine est tellement vaste qu’il mériterait un article (ou un livre) à lui tout seul.
Cependant, si vous voulez plus de détails sur l’ObjectDataProvider, et le DataBinding, en
général, avec Windows Presentation Foundation, je ne peux que vous conseiller le site Web
de Beatriz Costa : [Link] et plus particulièrement ce message, qui traite
spécifiquement de l’ObjectDataProvider : [Link]
[Link]
Thomas LEBRUN
[Link] 41
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
k. Textes et documents
Le support du texte et des documents a complètement été remanié dans Windows Presentation
Foundation.
Ce que l’on peut appeler le « Framework de Texte » de WPF supporte désormais :
o des animations de texte qui utilisent au mieux les matériaux compatible DirectX
o utilisation optimisée de la technologie ClearType
o l’affichage indépendant de la résolution
o l’utilisation de l’Unicode pour tous les textes
o etc….
Bien entendu, cette liste n’est pas exhaustive : beaucoup d’autres fonctionnalités sont
supportées et fournies par WPF.
Pour inclure du texte dans vos applications, vous avez accès à de nombreuses APIs, telles que
les Labels, les TextBox, les TextBlock, etc….
Ces éléments sont les éléments de base de l’interface utilisateur, et offrent un moyen simple et
rapide d’utiliser du texte. Ils possèdent des propriétés telles que FontFamily, FontSize et
FontStyle, qui vous permettent de définir, précisement, la police à utiliser :
Au travers de ce bout de code, nous avons définit le type de police à utiliser (Lucida
Console), le style à appliquer (Oblique) et la taille de la police (15).
Le résultat, en image :
ClearType, lorsqu’elle est utilisé avec GDI (Graphic Device Interface) sans l’anti-aliasing via
l’axe Y, offre une meilleure résolution sur l’axe des X. C’est bien sur l’inverse lorsque vous
utiliser la technologie de l’anti-aliasing suivant l’axe des Y.
Thomas LEBRUN
[Link] 42
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Pour voir une démonstration, regarder ces images : sur celles de droite, les contours sont
lisses, l’image est nette. On a donc utilisé ClearType, dans notre application WPF, pour cette
image :
<FlowDocumentReader>
<FlowDocument>
<Paragraph>
Paragraphe Normal
</Paragraph>
<Paragraph FontSize="25">
Paragraphe avec une taille de 25
</Paragraph>
<Paragraph>
<Bold>
<Italic>Paragraphe en gras et
italique</Italic>
</Bold>
</Paragraph>
<Paragraph>
<LineBreak />
Paragraphe avec un LineBreak (Saut de ligne)
juste avant
</Paragraph>
<Section>
<Paragraph>
Une section qui inclut un paragraphe
</Paragraph>
</Section>
<Paragraph TextIndent="25">
Paragraphe avec un indentation, pour le Texte, de
25
</Paragraph>
</FlowDocument>
</FlowDocumentReader>
Thomas LEBRUN
[Link] 43
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Vous avez également la possibilité d’utiliser des décorations pour vos textes. La classe
TextDecoration est en effet là pour vous permettre d’utiliser des ornements visuels sur vos
textes. Il y a quatre types de décoration de texte disponibles, que je vais vous représenter
grâce à cette image :
Pour spécifier où la décoration doit apparaître, utilisez la propriété Location de votre objet de
type TextDecoration. Pour définir l’apparence de votre décoration, il vous faut passer par la
propriété Pen.
Voici un bout de code vous expliquant comment mettre en application notre décoration :
<TextBlock FontSize="30">
Ceci est une simple décoration
<[Link]>
<!—
On indique que la décoration voulue est située au
dessus du texte
-->
<TextDecoration Location="OverLine"
PenThicknessUnit="FontRecommended">
<[Link]>
<Pen Brush="YellowGreen" Thickness="1" />
</[Link]>
</TextDecoration>
</[Link]>
</TextBlock>
Bien entendu, vous n’êtes pas limité à une seule décoration. Comme je vous l’ai dit,
TextDecorations est une collection donc, à ce titre, vous pouvez en ajouter autant que vous
voulez, pour avoir, par exemple, quelque chose comme cela :
Thomas LEBRUN
[Link] 44
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
<TextBlock FontSize="30">
Ceci est une riche décoration
<[Link]>
<!—
On indique que la décoration voulue est située au
dessus et dessous du texte
-->
<TextDecoration Location="OverLine"
PenThicknessUnit="FontRecommended">
<[Link]>
<Pen Brush="Blue" Thickness="1" />
</[Link]>
</TextDecoration>
<TextDecoration Location="Underline"
PenThicknessUnit="FontRecommended">
<[Link]>
<Pen Brush="BlueViolet" Thickness="2" />
</[Link]>
</TextDecoration>
</[Link]>
</TextBlock>
Enfin, sachez que rien ne vous empêche d’appliquer, à vos textes, des styles un peu plus
élaborés : nous allons en effet voir la technique utilisée pour réaliser des dégradés de couleurs.
Note : Les dégradés de couleurs seront vus ici avec les décorations de texte, mais sachez que
rien ne vous empêche de les utiliser ailleurs dans vos applications WPF, comme par exemple
pour créer des fonds dégradés, etc… comme le montre cette image :
Thomas LEBRUN
[Link] 45
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Lorsque l’on y réfléchit bien, un dégradé de couleur, qu’est ce que c’est ? Une couleur de
début, une couleur de fin puis on affiche toutes les couleurs du spectre qui sont comprises
entre nos deux bornes.
Et bien c’est ce que WPF nous permet de faire, et cela de façon très simple :
<TextBlock FontSize="30">
Ceci est une très riche décoration
<[Link]>
<!—
On indique que la décoration voulue est un trait de
soulignement
-->
<TextDecoration Location="Underline"
PenThicknessUnit="FontRecommended">
<[Link]>
<Pen Thickness="1.5">
<[Link]>
<LinearGradientBrush Opacity="0.5"
StartPoint="0,0.5" EndPoint="1,0.5">
<[Link]>
<GradientStop Color="Yellow"
Offset="0" />
<GradientStop Color="Red"
Offset="1" />
</[Link]>
</LinearGradientBrush>
</[Link]>
<!—
Pour afficher des pontillés
-->
<[Link]>
<DashStyle Dashes="2"/>
</[Link]>
</Pen>
</[Link]>
</TextDecoration>
<TextDecoration Location="Underline"
PenThicknessUnit="FontRecommended">
<[Link]>
<Pen Brush="BlueViolet" Thickness="2" />
</[Link]>
</TextDecoration>
</[Link]>
</TextBlock>
Ici, nous utilisons un LinearGradientBrush, sur lequel nous précisons les coordonnées du
point de départ (via l’attribut StartPoint) ainsi que les coordonnées du point d’arrivée (au
moyen de l’attribut EndPoint). Nous précisons également quelle doit être l’opacité du trait
qui sera tracé, grâce à l’attribut Opacity.
Concrètement, nous ne faisons que dire : « Je veux tracer un trait, qui doit aller du point A (0,
0.5) au point B (1, 0.5), en étant visible à 50% ».
Ensuite, nous utilisons des GradientStops, qui nous servirons à définir quelle couleur doit
être appliquée lorsque l’on se situe sur la position indiquée.
Pour terminer, nous définissons le style de trait que nous voulons utiliser, via l’élément
DashStyle.
Thomas LEBRUN
[Link] 46
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
On a bien un trait en pointillé, situé en dessous du texte, qui commence en jaune et qui se
termine en rouge !
Bien sur, rien ne vous empêche de rajouter, selon vos besoins, d’autres GradientStops.
Tout ce que l’on a vu à propos des rotations de contrôles WPF est également valable pour le
texte. Ainsi, le code suivant ne pose aucun problème :
<TextBlock FontSize="15">
Un texte transformé
<[Link]>
<RotateTransform Angle="20" />
</[Link]>
<LineBreak />
<LineBreak />
</TextBlock>
Pour les animations, c’est la même chose ! Ce qui a été vu pour les contrôles fonctionne tout à
fait pour le texte :
<TextBlock FontSize="15">
Un texte avec une animation
<[Link]>
<RotateTransform Angle="0" x:Name="RotationTextBlock" />
</[Link]>
<[Link]>
<EventTrigger RoutedEvent="[Link]">
<[Link]>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
[Link]="RotationTextBlock"
[Link]="Angle" From="0.0" To="360"
Duration="[Link]" />
</Storyboard>
</BeginStoryboard>
</[Link]>
</EventTrigger>
</[Link]>
</TextBlock>
Thomas LEBRUN
[Link] 47
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Bien entendu, WPF vous donne la possibilité d’appliquer, à votre texte, des effets grâce à la
classe TextEffect.
Cette classe vous permet, en effet, de prendre le texte qui est dans une chaîne de caractères et
de le considérer comme s’il s’agissait d’un ou plusieurs groupes de lettres. Vous aller donc
pouvoir appliquer des transformations, animations, etc… à un ou plusieurs groupes de
caractères, composé de une à plusieurs lettres.
<TextBlock FontSize="25">
Texte avec un caractère animé
<[Link]>
<TextEffect PositionStart="12" PositionCount="1">
<[Link]>
<RotateTransform Angle="0"
x:Name="RotationLettreTextBlock" />
</[Link]>
</TextEffect>
</[Link]>
<[Link]>
<EventTrigger RoutedEvent="[Link]">
<[Link]>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
[Link]="RotationLettreTextBlock "
[Link]="Angle" From="0.0" To="360"
Duration="[Link]" />
</Storyboard>
</BeginStoryboard>
</[Link]>
</EventTrigger>
</[Link]>
</TextBlock>
Nous avons donc définit un effet, et plus précisément une RotateTransform, qui sera
appliqué à un groupe de caractères. Pour définir la position de départ de ce groupe de
caractères, nous utilisons la propriété PositionStart de l’objet TextEffect. La propriété
PositionCount nous permet simplement de savoir combien de caractères nous servirons à
composer ce groupe.
Vous avez également la possibilité d’appliquer des effets de relief à vos textes, grâce aux
classes DropShadowBitmapEffect et OutterShadowBitmapEffect. Notez cependant que
l’utilisation de ces classes entrainera la désactivation de la technologie ClearType, au sein de
vos applications WPF.
Thomas LEBRUN
[Link] 48
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
5. WPF /E
Vous l’avez vu jusqu'à maintenant, Windows Presentation Foundation vous permet de réaliser
des applications au design novateur, et cela en quelques minutes seulement.
Mais le but de Microsoft ne s’arrête pas là. En effet, leur objectif est de pouvoir faire en sorte
que les applications WPF puissent s’exécutent sur un maximum de plateformes possibles.
Pour cela, ils ont créé WPF /E (Windows Presentation Foundation /EveryWhere).
Il s’agit d’un sous-ensemble de WPF, qui permet d’exécuter des applications WPF sur
n’importe quel type de plateforme (PC, Mac, Pocket PC, Smartphone, etc..).
Microsoft cible en effet Opéra, FireFox et Internet Explorer sur Windows, mais également
Safari et FireFox sur Mac. Une version pour Linux et Solaris est également envisagée.
Pour arriver à ce résultat, il vous faut créer des applications de type XAML Browser
Application, autrement dit des applications qui s’exécuteront dans un navigateur Internet.
Car, en effet, si l’on y réfléchit bien, quel est le seul type d’applications qu’il est possible
d’exécuter à la fois sous Windows, Linux mais encore Solaris, Pocket PC, etc….
La réponse est bien sur évidente : il s’agit des applications Web.
Au travers de ce chapitre, je vais donc vous parler, un peu plus en détails, de WPF /E.
Les bases étant maintenant établies, nous savons que WPF /E est un sous-ensemble de WPF,
qui a pour objectif de fournir des applications Web tirant parti de toute la puissance de
WinFX : On peut donc espérer, maintenant, des applications Web aussi jolies que des
applications Windows.
A noter : Vous ne pouvez pas, dans vos applications WPF /E, utiliser de contrôles en 3D.
Avant de rentrer plus dans les détails, laissez moi vous montrer quelques images pour
découvrir un aperçu d’applications WPF /E :
Sur cette première image, l’auteur de l’application a créé une horloge dont les aiguilles sont
animées. L’horloge est transparente, ce qui nous permet de voir l’image utilisée en arrière-
plan. Au passage, notez le navigateur Web qui a été utilisé pour la démonstration…
Thomas LEBRUN
[Link] 49
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Ici, nous avons affaire à un outil de visualisation vectoriel, qui permet à l’utilisateur de
zoomer et de faire pivoter l’image.
Pour finir, il ne me reste plus qu’à vous montrer cette copie de XAMLPad pour les
applications WPF /E. Il s’agit d’une application DHTML qui incorpore le plugin de
navigation Internet WPF /E, et qui interprète le XAML qui a été saisi dans la zone de texte :
Le rendu de toutes ces images donne l’impression que ces applications ont été réalisées à
l’aide de Flash ou d’une technologie semblable mais pourtant, il s’agit bien d’applications
Web utilisant le moteur graphique de WinFX : Windows Presentation Foundation.
Thomas LEBRUN
[Link] 50
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Voyons à présent, un peu plus en détails, comment fonctionnent les applications de type
XAML Browser Application, autrement dit les applications WPF que vous allez exécuter
dans un navigateur Web.
Première chose à savoir, qui peut paraître logique mais qu’il est bon de rappeler : les
applications WPF /E sont des applications disponibles en ligne uniquement !
Ensuite, vous aurez sans doute remarqué qu’il n’y a pas d’installation, lorsque vous exécutez
une application de ce type. En effet, cela passe par un déploiement ClickOnce, transparent
pour l’utilisateur, et qui n’affiche aucune entrée dans le menu « Démarrer » ou bien dans le
panneau « Ajout/Suppression de programmes » :
Nous avons vu que l’exécution de ces applications se fait au travers d’un navigateur Web : il
suffit donc d’avoir un navigateur Web compatible, ainsi que le Runtime WinFX, pour
pouvoir exécuter des applications WPF /E.
Du côté sécurité, tout à également été prévu : en effet, les applications s’exécutent dans un
contexte sécurisé, ce qui nous permet de ne pas avoir d’avertissement de sécurité.
Pour pouvoir faire fonctionner toute cette mécanique, il nous manque un élément important :
le JavaScript. C’est lui qui représente le lien qui servira à connecter l’applet WPF /E à la
page Web. WPF /E ne possède pas son propre moteur JavaScript. Au lieu de cela :
o il expose des propriétés et des méthodes au JavaScript qui est dans le
navigateur
o il déclenche des évènements que le JavaScript peut manipuler.
Thomas LEBRUN
[Link] 51
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
<Grid>
<TextBlock FontSize="35" FontStyle="Italic" FontWeight="Bold"
VerticalAlignment="Center" HorizontalAlignment="Center" [Link]="0">
Bienvenue dans cette application WPE /F
</TextBlock>
<[Link]>
<EventTrigger RoutedEvent="[Link]">
<[Link]>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
[Link]="MyButtonTransform"
[Link]="Angle" From="0" To="360" Duration="[Link]"
/>
</Storyboard>
</BeginStoryboard>
</[Link]>
</EventTrigger>
</[Link]>
</Button>
</Grid>
Thomas LEBRUN
[Link] 52
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Et le résultat obtenu:
Techniquement, vous être maintenant en mesure de réaliser les mêmes applications, que ce
soit en client lourd (applications Windows) ou en client léger (applications Web).
Vous pouvez également « embarquer » votre code XAML dans une simple page Web, et
l’utiliser grâce à du JavaScript.
En voici d’ailleurs un exemple :
<div>
<input id="textbox" type="text" value="Orange"/>
<button onclick="clickHandler()">Change
Color</button><br />
<embed id="WpfeControl1" height="312px" width="354px"
SourceElement="WpfeControl1Xaml" BackgroundColor="White"
type="application/xcp-plugin"/>
</div>
</body>
</html>
Thomas LEBRUN
[Link] 53
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Dans cet exemple, nous encadrons notre code XAML dans une balise script en spécifiant le
type adéquat : text/xaml.
Ensuite, tout passe par du simple JavaScript :
o On récupère le contenu de notre TextBox
o Ensuite, on récupère notre contrôle WPF /E
o Puis à partir de là, toujours à l’aide de JavaScript, on accède aux contrôles qui sont à
l’intérieur de notre contrôle WPF /E
o Et on termine par travailler avec ces contrôles, en appelant les méthodes adéquates.
Ainsi, on a une complète interaction entre notre code XAML et notre code JavaScript !
Je n’ai donc fait que « survoler » le sujet, en espérant avoir quelque chose de plus à vous
montrer dans les mois qui viennent.
Mais il se peut que certains d’entre vous souhaitent utiliser les capacités de Windows
Presentation Foundation au sein de leurs applications WindowsForms classiques.
Ou bien même, il est possible, en tant que développeurs d’applications de type Windows
Presentation Foundation, vous souhaitiez utiliser des contrôles WindowsForms classiques
(par exemple, les contrôles Calendar ou MonthCalendar, ceux-ci n’étant pas disponibles dans
WPF).
Et bien sachez que cela est possible, grâce à un projet dont le nom de code est : Crossbow.
Crossbow est un projet qui à pour but de permettre l’interopérabilité entre les WindowsForms
et Windows Presentation Foundation. Autrement dit, vous allez pouvoir développer des
applications « hybrides », mêlant à la fois WindowsForms et contrôles WPF.
Thomas LEBRUN
[Link] 54
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Chose très importante à retenir : Lorsque vous mettez en place cette l’interopérabilité, si vous
avez deux contrôles WindowsForms sur une page WPF, et que ceux-ci ne sont pas intégrés
dans un UserControl, alors vous allez devoir utiliser deux WindowsFormsHost, un pour
contrôles WindowsForms.
Inversement, si dans votre application WindowsForms, vous avez plus d’un contrôle WPF,
vous allez devoir utiliser autant de contrôles ElementHost qu’il y a de contrôle WPF.
Commençons par voir comment ajouter un contrôle WindowsForms dans une application
WPF.
La première chose à faire, après avoir créé le projet, est d’ajouter deux références : une à
[Link] (pour pouvoir manipuler des contrôles WindowsForms), et l’autre à
WindowsFormsIntegration.
Cette deuxième référence, qui est disponible via la DLL se trouvant dans le répertoire
C:\Program Files\Reference Assemblies\Microsoft\Avalon\v2.0.50215\ (attention au numéro
de version qui peut changer suivant la CTP que vous utilisez), est nécessaire car elle contient
tout ce dont vous avez besoin pour faire de l’interopérabilité WindowsForms – WPF.
En effet, cette DLL n’est pas ajoutée de base au projet que vous créez car il s’agit toujours,
pour le moment, d’une « Tech Preview », autrement dit d’une version de test uniquement.
Une fois les références ajoutées, nous allons devoir indiquer à XAML où se situent les classes
disponibles dans [Link] et [Link].
Pour cela, nous allons utiliser, dans notre XAML, des instructions de mapping,
<?Mapping XmlNamespace="wfi"
ClrNamespace="[Link]"?>
<?Mapping XmlNamespace="wf" ClrNamespace="[Link]"?>
Ce mapping nous sert à dire ceci: « Tous les contrôles dont le nom commencera par le préfixe
indiqué, correspondront à des types se trouvant dans l’espace de nom spécifié ».
Thomas LEBRUN
[Link] 55
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
A partir de là, il ne vous reste plus qu’à ajouter vos contrôles et vous disposez de deux
méthodes pour cela.
Première méthode, en utilisant du code XAML :
<Window x:Class="DemosWindowsFormsHost.Window1"
xmlns=[Link]
xmlns:x="[Link]
xmlns:wfi="clr-
namespace:[Link];assembly=WindowsFormsInteg
ration"
xmlns:wf="clr-
namespace:[Link];assembly=[Link]"
xmlns:s="clr-namespace:System;assembly=mscorlib"
>
<Grid>
<[Link]>
<RowDefinition Height="0.4*" />
<RowDefinition Height="0.6*" />
</[Link]>
[Link] lb = new
[Link]();
[Link]("ListBox WindowsForms !");
[Link]("C'est cool");
[Link](lb);
[Link](host);
}
Ces codes sont suffisament parlant, je ne vais donc pas m’attarder sur leur description car je
préfère vous parler des avantages et inconvénients de l’utilisation de WindowsFormsHost.
Thomas LEBRUN
[Link] 56
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Le gros avantage apporté par la première technique est qu’elle fournit un support complet du
XAML. Cependant, il y a deux inconvénients :
o les contrôles doivent avoir un constructeur par défaut
o il est impossible de définir, via le code XAML, les sous-propriétés. Il faut
passer par le code.
Note : Si, à la compilation de votre projet, vous avez une erreur à propos de la sérialisation, et
que vous utilisez la CTP de Février de Crossbow, essayez de remplacer la référence vers la
DLL [Link] par celle se trouvant ici :
Voici une capture d’écran de ce que vous pouvez obtenir avec, à gauche, une ListBox
WindowsForms et en haut et à droite, un label et un bouton WPF :
Malgré la « jeunesse » du projet, on peut voir que pas mal de travail a été réalisé car, même si
l’application que je vous montre est très sobre, rien ne vous empêche de faire des choses
beaucoup plus complexes.
On regrettera toutefois qu’il ne soit pas possible d’utiliser de RenderTransform ni même
d’animations.
Pour finir, nous allons maintenant vois comment intégrer un contrôle WPF dans une
application WindowsForms.
Là encore, pas de mystère : il va y avoir plusieurs étapes et la première concerne, une fois de
plus, l’ajout des références nécessaires.
Ces références sont les suivantes :
o PresentationCore,
o PresentationFramework,
o WindowsBase,
o UIAutomationTypes,
o UIAutomationProvider,
Thomas LEBRUN
[Link] 57
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Maintenant que les références nécessaires sont ajoutées, il ne vous reste plus qu’à développer
vos pages (ou contrôles) WPF et à les intégrer dans votre application WindowsForms, grâce à
l’ElementHost.
Voici une première démonstration, simple :
[Link] = [Link];
[Link] button = new
[Link]();
[Link] = "Boutton Windows Presentation Foundation";
[Link] =
[Link];
[Link] =
[Link];
[Link](button);
[Link](host);
Thomas LEBRUN
[Link] 58
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
cette ligne permet d’incrémenter la taille, sans que cela soit visible à l’utilisateur, et sans qu’il
se rendre compte de ce problème.
Vous aurez sans doute du mal à le voir, mais le bouton du haut est bien un contrôle
WindowsForms « classique », tandis que le contrôle du bas est un bouton WPF.
Bien entendu, vous n’êtes pas limité à l’ajout de simples contrôles sur votre formulaire : vous
pouvez tout à fait rajouter des contrôles utilisateurs, des pages, etc…
Voyons cela un peu plus en détails, pour pouvoir conclure ce chapitre.
Imaginez par exemple que vous disposez de ce contrôle utilisateur, développé en XAML :
<UserControl x:Class="[Link]"
xmlns="[Link]
xmlns:x="[Link]
<Grid>
<[Link]>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</[Link]>
<ListView [Link]="0">
<ListViewItem> 1er élément </ListViewItem>
<ListViewItem> 2ème élément </ListViewItem>
<ListViewItem> 3ème élément </ListViewItem>
</ListView>
<TextBlock [Link]="1">
TextBlock WPF :)
</TextBlock>
Thomas LEBRUN
[Link] 59
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Ici, rien de bien extraordinaire : notre UserControl est composé d’une ListView, d’un
TextBlock et pour finir, d’une ComboBox, le tout regroupé dans une Grid.
Maintenant, il faut utiliser un ElementHost pour intégrer notre UserControl sur notre
formulaire Windows :
using [Link];
[Link](host2);
Là encore, rien de nouveau : on créé une instance d’un nouvel ElementHost, puis on y ajoute
une nouvelle instance de notre contrôle utilisateur.
On ajoute ensuite notre instance d’ElementHost à notre formulaire et, à l’exécution de
l’application, vous vous rendez compte que votre contrôle n’apparait pas à l’écran (vous
devriez même avoir une erreur de compilation, à propos de la méthode InitializeComponents
de votre UserControl).
En effet, dans sa version actuelle (Crossbow étant toujours un produit en version BETA) ; il y
a une petite manipulation à faire sur le fichier de projet de votre application (.csproj ou
.vbproj) avant que cela ne fonctionne correctement. Avant de vous donner la solution, je vais
vous expliquer pourquoi vous obtenez cette erreur.
Lorsque vous développez une application WPF, le compilateur sait comment il doit parser le
XAML, créer sa représentation binaire (c’est ce que l’on appelle le BAML) et générer le code
correspondant.
Cependant, ici, nous développons une application WindowsForms et le modèle qui a été
utilisé pour créer cette application WPF ne connait rien du tout au XAML.
Thomas LEBRUN
[Link] 60
Windows Presentation Foundation :
La nouvelle génération d’interfaces graphiques
Grossièrement, cette ligne sert à indiquer, au système de compilation, comment générer des
applications WinFX.
Vous indiquez donc que la cible de votre compilation est un assemblage WinFX.
Ainsi, même si la technologie Crossbow est encore jeune, elle semble vraiment avancée et
permet de réaliser, de façon assez simple et rapide, des applications mêlant à la fois WPF et
WindowsForms.
7. Conclusions :
Au travers de cet article, j’ai essayé de couvrir un maximum de choses sur Windows
Presentation Foundation.
Bien sur, il y aurait beaucoup à rajouter et/ou à compléter.
Cependant, vous avez dorénavant les bases suffisantes pour commencer à développer,
aujourd’hui, les applications que nous utiliserons demain !
Thomas LEBRUN
[Link] 61