Vous êtes sur la page 1sur 448

Copyright

2006 Micro Application 20-22, rue des Petits-Htels 75010 Paris 1re dition - Septembre 2006

Auteur Avertissement aux utilisateurs

Jean-Alain BAEYENS Toute reprsentation ou reproduction, intgrale ou partielle, faite sans le consentement de MICRO APPLICATION est illicite (article L122-4 du code de la proprit intellectuelle). Cette reprsentation ou reproduction illicite, par quelque procd que ce soit, constituerait une contrefaon sanctionne par les articles L335-2 et suivants du code de la proprit intellectuelle. Le code de la proprit intellectuelle nautorise aux termes de larticle L122-5 que les reproductions strictement destines lusage priv et non destines lutilisation collective dune part, et dautre part, que les analyses et courtes citations dans un but dexemple et dillustration. Les informations contenues dans cet ouvrage sont donnes titre indicatif et nont aucun caractre exhaustif voire certain. A titre dexemple non limitatif, cet ouvrage peut vous proposer une ou plusieurs adresses de sites Web qui ne seront plus dactualit ou dont le contenu aura chang au moment o vous en prendrez connaissance. Aussi, ces informations ne sauraient engager la responsabilit de lEditeur. La socit MICRO APPLICATION ne pourra tre tenue responsable de toute omission, erreur ou lacune qui aurait pu se glisser dans ce produit ainsi que des consquences, quelles quelles soient, qui rsulteraient des informations et indications fournies ainsi que de leur utilisation. Tous les produits cits dans cet ouvrage sont protgs, et les marques dposes par leurs titulaires de droits respectifs. Cet ouvrage nest ni dit, ni produit par le(s) propritaire(s) de(s) programme(s) sur le(s)quel(s) il porte et les marques ne sont utilises qu seule fin de dsignation des produits en tant que noms de ces derniers. ISBN : 2-7429-6729-X Couverture ralise par Room22. MICRO APPLICATION 20-22, rue des Petits-Htels 75010 PARIS Tl. : 01 53 34 20 20 Fax : 01 53 34 20 00 http://www.microapp.com Support technique galement disponible sur www.microapp.com

Retrouvez des informations sur cet ouvrage ! Rendez-vous sur le site Internet de Micro Application www.microapp.com. Dans le module de recherche, sur la page daccueil du site, entrez la rfrence 4 chiffres indique sur le prsent livre. Vous accdez directement sa fiche produit.

7729

Avant-propos
Le collection Guide du codeur sadresse aux personnes inities la programmation qui souhaitent dcouvrir une technologie particulire. Sans ngliger les aspects thoriques, nous donnons toujours priorit la pratique an que vous puissiez rapidement tre autonome. Avant dentrer dans le vif du sujet, notez ces quelques informations gnrales propos de la collection.

Conventions typographiques
An de faciliter la comprhension de techniques dcrites, nous avons adopt les conventions typographiques suivantes :
j j j j

gras : menu, commande, bote de dialogue, bouton, onglet. italique : zone de texte, liste droulante, case cocher, bouton radio.

Police bton : instruction, listing, texte saisir.

: dans les programmes, indique un retour la ligne d aux contraintes de la mise en page.

Propose conseils et trucs pratiques.

Met laccent sur un point important, souvent dordre technique quil ne faut ngliger aucun prix.

Donne en quelques lignes la dnition dun terme technique ou dune abrviation.

Il sagit dinformations supplmentaires relatives au sujet trait.

Sommaire 1 Introduction . . . . . . . . . . . . . . . . . . . . . . 11
1.1. 1.2. 1.3. Avertissement . . . . . . Prrequis . . . . . . . . . Prsentation de XAML Quest-ce que XAML ? . Petits rappels XML . . . Les principes gnraux . Utiliser XAMLPad . . . Checklist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 12 13 13 14 15 17 19

1.4. 1.5.

Fonctionnalits de base . . . . . . . . . . . . . . . 21
2.1. Afficher du texte . Avec un Label . . . Avec un TextBlock . Introduire du texte Crer un bouton . Afficher un cadre . Afficher une image Checklist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 22 30 38 46 47 48 53

2.2. 2.3. 2.4. 2.5. 2.6.

Disposer les lments lcran . . . . . . . . . . . 55


3.1. 3.2. 3.3. 3.4. 3.5. 3.6. 3.7. 3.8. 3.9. Utiliser les coordonnes . . . . . . . . . . Utiliser une grille . . . . . . . . . . . . . . Mettre en page avec un WrapPanel . . . Utiliser un empilement . . . . . . . . . . . Utiliser le docking . . . . . . . . . . . . . . Autoriser le dlement . . . . . . . . . . . Mlanger les techniques de mise en page Crer une page composite . . . . . . . . . Checklist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 61 68 70 72 77 81 88 90

Les autres contrles de base . . . . . . . . . . . . 91


4.1. 4.2. 4.3. 4.4. 4.5. 4.6. Crer une liste droulante . . . Crer une ComboBox . . . . . Crer une case cocher . . . . Utiliser les boutons radio . . . Placer des info-bulles . . . . . . Utiliser les panneaux onglets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 98 100 102 106 109

Sommaire
4.7. 4.8. 4.9. 4.10. 4.11. 4.12. 4.13. Crer un bouton automatique . . . Utiliser un Slider . . . . . . . . . . Utiliser un Expander . . . . . . . . Utiliser une ViewBox . . . . . . . . Utiliser un Popup . . . . . . . . . . Ajouter de la vido dans la fentre Checklist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 114 118 121 123 126 129

Crer une application . . . . . . . . . . . . . . . . 131


5.1. 5.2. 5.3. Crer une application Windows . . . . . . Grer les vnements . . . . . . . . . . . . . Hberger une application dans un browser Aperu de cette technologie . . . . . . . . . . La scurit et les WBA . . . . . . . . . . . . Hberger et excuter ce type dapplication . . Quand recourir ce modle dapplication ? . Crer une WBA . . . . . . . . . . . . . . . . Enchanement des pages . . . . . . . . . . . . Les pages fonctions . . . . . . . . . . . . . . Crer une application Windows navigable Les applications avec WPF/E . . . . . . . . Checklist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 138 140 140 141 141 142 142 147 149 157 165 167

5.4. 5.5. 5.6. 5.7.

Les menus . . . . . . . . . . . . . . . . . . . . . . 169


6.1. Crer un menu . . . . . . . . . . . Le menu principal . . . . . . . . . . Les sous-menus . . . . . . . . . . . Rendre un lment du menu inactif . Cocher un lment du menu . . . . . Associer une action un menu . . . Rendre le menu dynamique . . . . . Crer un menu contextuel . . . . . Crer une barre doutils . . . . . . Une barre doutils statique . . . . . Un ensemble de barres doutils . . . Checklist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170 170 171 172 173 173 176 178 183 183 185 189

6.2. 6.3.

6.4.

Lier les donnes son interface utilisateur . . . 191


7.1. Lier les donnes un DataSet . . . . . . . . . . . . . . . . . 192

Sommaire
7.2. 7.3. 7.4. Lier les donnes un objet mtier . . . . . . . . . . . . . . . 203 Lier les donnes sans utiliser le code .NET . . . . . . . . . . 207 Checklist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218

Fonctionnalits avances . . . . . . . . . . . . . . 219


8.1. 8.2. 8.3. Appliquer des transformations sur les contrles Crer une ressource . . . . . . . . . . . . . . . . Crer un style . . . . . . . . . . . . . . . . . . . . Utiliser les triggers . . . . . . . . . . . . . . . . . . Crer une animation . . . . . . . . . . . . . . . . . Checklist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220 223 227 238 241 247

8.4.

Les documents . . . . . . . . . . . . . . . . . . . . 249


9.1. 9.2. 9.3. 9.4. 9.5. Utiliser FixedDocument Utiliser FlowDocument . diter un document . . Annoter un document . Checklist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250 254 275 282 288

10

Les outils graphiques . . . . . . . . . . . . . . . . 289


10.1. Le designer de Visual Studio (nom de code CIDER) . 10.2. Dans la gamme expression . . . . . . . . . . . . . . . . Graphic Designer . . . . . . . . . . . . . . . . . . . . . Interactive Designer . . . . . . . . . . . . . . . . . . . . 10.3. Aurora Designer . . . . . . . . . . . . . . . . . . . . . 10.4. ZAM 3D . . . . . . . . . . . . . . . . . . . . . . . . . . 10.5. Checklist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290 303 303 306 310 313 314

11

Le dessin . . . . . . . . . . . . . . . . . . . . . . . 315
11.1. Le dessin en 2D . . . . . . . . . . . . . . . . . . . . . . . . . . 316 11.2. Le dessin en 3D . . . . . . . . . . . . . . . . . . . . . . . . . . 323 11.3. Checklist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327

12

Raliser une application complte. . . . . . . . . 329


12.1. Checklist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349

13

Annexes . . . . . . . . . . . . . . . . . . . . . . . . 351
13.1. XAML sur le Web . . . . . . . . . . . . . . . . . . . . . . . . 352

Sommaire
13.2. Glossaire . . . . . . . . . . . . . . . . . . . . . . . . . . . 13.3. Schma dhritage des diffrentes classes Visual . . . . Schma dhritage des diffrentes classes Visual . . . . . Le dtail de lhritage dans la branche Control. . . . . . . Schma dhritage des diffrentes classes ContentElement Schma dhritage des diffrentes classes Freezable . . . 13.4. Rsum des classes et des attributs utiliss . . . . . . . Classe ArcSegment . . . . . . . . . . . . . . . . . . . . . Classe BezierSegment . . . . . . . . . . . . . . . . . . . . Classe Border . . . . . . . . . . . . . . . . . . . . . . . . . Classe Button . . . . . . . . . . . . . . . . . . . . . . . . . Classe Canvas . . . . . . . . . . . . . . . . . . . . . . . . Classe CheckBox . . . . . . . . . . . . . . . . . . . . . . Classe ColorAnimation . . . . . . . . . . . . . . . . . . . Classe ComboBox . . . . . . . . . . . . . . . . . . . . . . Classe DiffuseMaterial . . . . . . . . . . . . . . . . . . . . Classe DirectionalLight . . . . . . . . . . . . . . . . . . . Classe DockPanel . . . . . . . . . . . . . . . . . . . . . . Classe DocumentViewer . . . . . . . . . . . . . . . . . . . Classe DoubleAnimation . . . . . . . . . . . . . . . . . . Classe DoubleAnimationUsingKeyFrames . . . . . . . . Classe Ellipse . . . . . . . . . . . . . . . . . . . . . . . . . Classe EventTrigger . . . . . . . . . . . . . . . . . . . . . Classe Expander . . . . . . . . . . . . . . . . . . . . . . . Classe Figure . . . . . . . . . . . . . . . . . . . . . . . . . Classe FixedPage . . . . . . . . . . . . . . . . . . . . . . Classe FixedDocument . . . . . . . . . . . . . . . . . . . Classe Floater . . . . . . . . . . . . . . . . . . . . . . . . Classe FlowDocument . . . . . . . . . . . . . . . . . . . . Classe GradientStop . . . . . . . . . . . . . . . . . . . . . Classe Grid . . . . . . . . . . . . . . . . . . . . . . . . . . Classe GridSplitter . . . . . . . . . . . . . . . . . . . . . . Classe GridView . . . . . . . . . . . . . . . . . . . . . . . Classe GridViewColumn . . . . . . . . . . . . . . . . . . Classe Hyperlink . . . . . . . . . . . . . . . . . . . . . . . Classe Image . . . . . . . . . . . . . . . . . . . . . . . . . Classe ImageBrush . . . . . . . . . . . . . . . . . . . . . . Classe Label . . . . . . . . . . . . . . . . . . . . . . . . . Classe Line . . . . . . . . . . . . . . . . . . . . . . . . . . Classe LinearGradientBrush . . . . . . . . . . . . . . . . Classe LineSegment . . . . . . . . . . . . . . . . . . . . . Classe ListBox . . . . . . . . . . . . . . . . . . . . . . . . Classe ListView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359 363 363 364 366 366 368 368 368 368 369 370 371 373 373 374 374 375 375 376 376 376 377 377 377 378 379 379 380 380 380 381 382 382 382 383 383 384 385 385 385 386 387

Sommaire
Classe Menu . . . . . . . . . . Classe MenuItem . . . . . . . . Classe MeshGeometry3D . . . Classe NavigationWindow . . Classe ObjectDataProvider . . Classe Page . . . . . . . . . . . Classe PageContent . . . . . . Classe Paragraph . . . . . . . . Classe Path . . . . . . . . . . . Classe PathFigure . . . . . . . Classe Pen . . . . . . . . . . . Classe PerspectiveCamera . . . Classe Polygon . . . . . . . . . Classe Polyline . . . . . . . . . Classe PolylineSegment . . . . Classe Popup . . . . . . . . . . Classe RadialGradientBrush . Classe RadioButton . . . . . . Classe Rectangle . . . . . . . . Classe RotateTransform . . . . Classe RepeatButton . . . . . . Classe ScaleTransform . . . . Classe ScrollViewer . . . . . . Classe Section . . . . . . . . . Classe Setter . . . . . . . . . . Classe SkewTransform . . . . Classe Slider . . . . . . . . . . Classe SolidColorBrush . . . . Classe SplineDoubleKeyFrame Classe StackPanel . . . . . . . Classe StoryBoard . . . . . . . Classe Style . . . . . . . . . . . Classe Table . . . . . . . . . . Classe TableCell . . . . . . . . Classe TableColumn . . . . . . Classe TableRow . . . . . . . . Classe TabControl . . . . . . . Classe TabItem . . . . . . . . . Classe TextBlock . . . . . . . . Classe TextBox . . . . . . . . . Classe Toolbar . . . . . . . . . Classe ToolbarTray . . . . . . Classe TranslateTransform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387 387 388 388 389 389 390 391 392 392 392 393 393 393 393 394 394 394 395 396 396 396 396 397 397 397 398 399 399 399 400 400 401 401 401 401 401 402 403 404 405 405 406

Sommaire
Classe TreeView . . . . . . . . . . . . . . . . . . . . . . Classe TreeViewItem . . . . . . . . . . . . . . . . . . . Classe Trigger . . . . . . . . . . . . . . . . . . . . . . . Classe ViewBox . . . . . . . . . . . . . . . . . . . . . . Classe Viewport3D . . . . . . . . . . . . . . . . . . . . Classe Window . . . . . . . . . . . . . . . . . . . . . . . Classe WrapPanel . . . . . . . . . . . . . . . . . . . . . Classe XmlDataProvider . . . . . . . . . . . . . . . . . Classes autorises dans la zone internet . . . . . . . . Liste des touches de raccourcis pour les commandes ddition . . . . . . . . . . . . . . . . . . . . . . . . . . Liste des classes par catgories . . . . . . . . . . . . . Liste des couleurs prdnies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406 406 406 407 407 408 409 409 409

13.5. 13.6. 13.7. 13.8.

. . . . 411 . . . . 413 . . . . 415

14

Index . . . . . . . . . . . . . . . . . . . . . . . . . . 421

Ch apit re

1 Introduction

Avertissement ............................................. Prrequis ................................................... Prsentation de XAML ................................. Utiliser XAMLPad ....................................... Checklist ....................................................

12 12 13 17 19

Introduction

1.1 Avertissement
Ce livre vous fera dcouvrir progressivement XAML au moyen dexemples. Nous partirons des fonctionnalits les plus simples et les plus utiles pour aller vers des notions un peu plus complexes. Toutefois, an que vous puissiez facilement revenir par la suite sur une fonctionnalit particulire, les lments sont regroups le plus possible dans des chapitres ddis. la n du livre, vous trouverez un rcapitulatif des classes et des attributs utiliss. Celui-ci se veut non pas un rfrentiel complet mais plutt un rcapitulatif des notions vues. Il sagit dune prsentation du XAML et non de WinFX. Cest pourquoi nous nous attacherons principalement aux techniques accessibles depuis XAML, mme si certains moments nous devrons videmment voir ou raliser le code .NET associ. Au moment o ces lignes ont t crites, le code XAML et la bibliothque WinFX avec laquelle il travaille taient toujours en version bta et susceptibles dtre modis. Il se peut que certaines fonctionnalits aient entre-temps t ajoutes ou retires. Comme nous nous intresserons surtout aux fonctions les plus courantes, il est probable que le contenu de ce livre respecte les rgles en vigueur dans la version dnitive du produit.

1.2 Prrequis
Avant de pouvoir dvelopper avec XAML et WinFX, vous devez au pralable installer le Framework .NET 2.0 ainsi quune version de Visual Studio 2005. Vous pourriez utiliser nimporte quel diteur de texte, et ce y compris Notepad, mais lutilisation de Visual Studio vous facilitera grandement la vie, que ce soit pour la cration des projets ou la compilation de votre application. Il vous apporte galement lIntelliSense, ce qui est un trs gros avantage. Vous devez ensuite installer le kit de dveloppement WinFX. Attention, Windows XP SP2, Windows 2003 ou Windows Vista est requis pour pouvoir linstaller ! Pour raliser les exemples, nous utiliserons dune part "XAMLPad", un petit utilitaire livr avec le kit de dveloppement et dautre part "Microsoft Visual Basic 2005 Express Edition". An de bncier de toutes les fonctionnalits dans Visual Studio, vous devez galement installer lextension pour Visual Studio. Lensemble de ces lments sera repris dans le Framework 3.0, dont la sortie est attendue pour le dbut de lanne 2007.

12 Le guide du codeur

Prsentation de XAML

1.3 Prsentation de XAML


Quest-ce que XAML ?
Le XAML est un des composants de la nouvelle technologie Windows Presentation Fundation (en abrg, WPF). Cette technologie est accessible via le kit de dveloppement WinFX. WinFX doit remplacer lancien API Win32. videmment, pour des raisons de portabilit, lancien API sera encore prsent dans les futures versions de Windows, mais jusqu quand ? Il a initialement t cr spciquement pour Windows Vista, mais Microsoft a dcid de le rendre disponible pour Windows XP (SP2) et Windows 2003. WinFX est intimement li au Framework .NET 2.0. Lavantage dutiliser WinFX par rapport Win32 est quil apporte une approche vectorielle de laffichage et offre des possibilits 3D. WinFX sera en dnitive inclus dans le Framework 3.0, qui contiendra :
j j j j j

Windows Communication Fundation ; Windows Presentation Fundation ; Windows Workow Fundation ; Windows CardSpace ; .NET Framework 2.0.

XAML, quant lui, est un langage de description fond sur la norme XML. Contrairement au XML, les noms des balises et leur contenu doivent respecter une syntaxe stricte et correspondre une classe de WPF. Tout ce qui est fait en XAML peut galement tre fait dans du code traditionnel. De mme, XAML ne supporte quune partie du modle offert par WPF. Il offre en revanche une beaucoup plus grande lisibilit et une sparation entre le code logique et linterface graphique. Le XAML va nous permettre de dcrire les crans de lapplication. Le reste du traitement se fait de manire traditionnelle, via du code .NET. Dans le cadre de ce guide dinitiation, les parties .NET des exemples sont en Visual Basic .NET mais, si vous prfrez, vous pouvez bien entendu utiliser du C# ou nimporte quel autre langage .NET. Lapprentissage du .NET nest pas lobjectif de ce guide ; nanmoins, pour une bonne comprhension des exemples, il sera souvent ncessaire de voir aussi bien la partie XAML que la partie .NET. An de mieux comprendre la place de WinFX, de .NET et de XAML dans larchitecture, vous pouvez vous rfrer au schma ci-dessous.

Le guide du codeur 13

Introduction

Comme vous pouvez le constater, XAML, comme les langages .NET, forme la couche suprieure et reprsente linterface avec le dveloppeur. En dessous, nous retrouvons les couches composes de code manag ainsi que la CLR ncessaire pour lexcution de ce code. La dernire partie est la couche de communication avec Windows lui-mme. noter que WPF est pour sa part compos effectivement de Presentation Framework, de Presentation Core et de Milcore.

Petits rappels XML


Vous navez pas connatre XML pour utiliser XAML. Les quelques notions ncessaires la bonne comprhension vont vous tre expliques dans ce chapitre. Le XML prsente les informations de faon structure et hirarchique sous forme de texte. Un chier XML contient un ou des nuds dans lesquels simbriquent dautres nuds appels nuds enfants. Mais quest-ce quun nud ?
<NomDuNoeud> <NoeudEnfant> Valeur </NoeudEnfant> <NoeudEnfant> Valeur </NoeudEnfant> </NomDuNoeud>

Un nud est tout ce qui se trouve entre une balise ouvrante <NomDuNoeud > et une balise fermante </ NomDuNoeud>. Les attributs sont des informations qui se placent dans la balise ouvrante.
<NomDuNoeud MonAttribut= "valeur">

Lattribut est toujours suivi du symbole = et dune valeur entre guillemets. Si le nud ne contient que des attributs, la syntaxe autorise de ne pas placer de balise fermante. La balise ouvrante se termine alors par le symbole /.
<NomDuNoeud MonAttribut= "valeur" />

Pour commenter du code XML, vous inclurez les commentaires dans une balise spcique.
<!-- votre commentaire -->
14 Le guide du codeur

Prsentation de XAML

Le commentaire peut sans problme stendre sur plusieurs lignes.

Les principes gnraux


Le principe gnral est nalement assez simple, chaque balise XAML identie une instance dune classe de la librairie WinFX. Linstanciation de cet objet est effectue automatiquement. Vous ne devez ni le dclarer ni linstancier avec New dans votre code .NET. Par exemple,
<Window />

permet dinstancier un objet de la classe Window. Si vous dsirez initialiser une proprit de la classe, il suffit dajouter un attribut dans le nud XML ou, selon les cas, de crer un nud enfant. Exemple :
<Window Title= "Titre" />

Cette balise permet dassigner la valeur "Titre" la proprit Titel de la classe Window. Notez que mme les proprits numriques doivent tre assignes comme une chane de caractres. Pour les valeurs boolennes, vous devez assigner True ou False entre guillemets. Pour les collections, il sagit de dnir des nuds enfants. Par exemple :
<Window> <Window.InputBindings> </Window.InputBindings> < /Window>

Le langage XAML est sensible la majuscule Vous devez respecter lcriture exacte dnie dans la documentation, et cela mme si votre projet est en Visual Basic. Ncrivez donc pas WINDOW mais bien Window.

Comme en XAML les noms des attributs des balises XML correspondent aux noms des proprits de la classe associe, nous parlerons indistinctement dans ce livre dattribut ou de proprit.

Le guide du codeur 15

Introduction

Pour mieux comprendre cette notion de correspondance entre XAML et les langages .NET, sachez que les deux bouts de code ci-dessous ont la mme fonction. En XAML :
<Label Name="lblNom" Width="60" Height="20"> mon nom </Label>

En VB .NET :
Dim lblNom as new Label lblNom.Width = 60 lblNom.Height = 20 lblNom.Text = "mon nom"

Comme vous pouvez le constater, ce qui est fait en XAML peut parfaitement tre fait en code .NET. Toutefois, la bonne pratique veut que lon utilise XAML pour dcrire linterface et les langages .NET traditionnels pour les traitements. Pour une mme classe, vous aurez alors vraisemblablement deux chiers de sources, un en XAML et lautre en code .NET. Les deux seront fusionns lors de la compilation. Nous reviendrons sur les diffrents chiers automatiquement gnrs ou non au cours de ce livre, au fur et mesure des besoins et de lexplication des diffrentes notions. Sachez toutefois que du code XAML seul peut dj tre compris par le systme et interprt sans mme devoir utiliser un compilateur. Cest par ce genre de code que nous allons commencer. XAML contient malgr tout quelques petites subtilits que nous allons dtailler. Tout dabord, le code XAML doit contenir un lment root comme le veut XML, mais cet lment doit tre un lment faisant partie du modle dapplication comme Window ou Page ou encore un conteneur tel Grid ou StackPanel. Nous reviendrons ultrieurement sur la notion de conteneur et dlments dapplication. Cet lment root doit contenir comme attribut la dclaration de deux Namespaces au minimum. Cette dclaration se fait en utilisant lattribut classique xmlns.
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >

Sil est ncessaire de faire rfrence dautres namespaces, il sera ncessaire dajouter dautres attributs xmlns en respectant la syntaxe ci-dessous.

16 Le guide du codeur

Utiliser XAMLPad

xmlns:nom="clr-namespace:nom du namespace;assembly=nom de lassembly"

Lassembly peut tre omis si le namespace est contenu dans le mme assembly que le programme. XAML autorise galement lutilisation dattributs particuliers, dont voici les principaux.
Attributs spciques Attribut Utilit

x:Name

Cet attribut a la mme fonction que lattribut Name, qui est gnralement prsent. Ils sont totalement interchangeables mais ne peuvent tre utiliss simultanment. Prfrez Name x:Name et limitez lusage de ce dernier aux objets qui ne disposent pas de la proprit Name. Est encore un moyen de donner un nom mais, typiquement, ce type de nommage est utilis pour nommer des ressources. Il ne sagit en aucun cas du mme usage que x:Name. Attribut plac dans llment root ; il fait le lien avec la classe dnie dans le code behind (.NET). Permet de spcier dautres modieurs que partial et public, qui sont les valeurs par dfaut. Pour dnir une valeur nulle une proprit. Permet dintroduire du code .NET dans le chier XAML. Il sera gnralement utilis en conjonction avec CDATA :
<x:Code> <![CDATA[ Code ]]> </x:Code>

x:Key

x:Class x:ClassModifier x:Null x:Code

x:Static x:Type x:TypeArgument x:Array

Pour accder une valeur statique dune classe. Dans XAML, il a le mme effet que TypeOf dans le code .NET. Pour dterminer le type des arguments qui doivent tre reus. Cet attribut est principalement utilis par PageFunction. Permet dinstancier un array comme valeur dun attribut. Toutefois, il nest pas possible de remplir cet array dans le code XAML.

Ces diffrentes notions seront abordes par lexemple dans la suite de ce livre.

1.4 Utiliser XAMLPad


Lutilitaire XAMLPad est trs simple demploi et permet de visualiser trs rapidement du code XAML. Il est toutefois limit au XAML statique. Cest pour cette raison que certains exemples seront raliss avec Visual Studio.
Le guide du codeur 17

Introduction

XamlPad se prsente comme une fentre en deux parties. La partie suprieure affiche le rsultat du code et la partie infrieure, le code lui-mme.

m Figure 1-1 : Loutil XAMLPad livr avec le kit de dveloppement

En rsum, vous tapez le code en bas, il affiche le rsultat en haut. Cest aussi simple que cela. Pour faciliter la vision, vous disposez de quelques options :
j

Auto Parse, qui est active par dfaut et traite en temps rel votre code

XAML. Ainsi, vous constatez directement limpact de vos changements.

Long code source Si votre code est long, vous pouvez dsactiver loption AutoParse. Cela vous vitera de dsagrables effets de rafrachissement.

j j

Refresh. Nest vraiment utile que si lAuto Parse est dsactive.

Licne dimprimante, qui imprime le rsultat mais pas le code.

Avec les autres options de la barre doutils, vous pouvez changer la police utilise pour le code, choisir de cacher temporairement le code ou encore faire un zoom de la fentre daffichage du rsultat. Consultez la barre de statut, elle vous donne de prcieux renseignements sur votre code en cours de frappe.
18 Le guide du codeur

Checklist

Il est dommage que lIntelliSense ne soit pas disponible dans cet utilitaire. Si vous dsirez en disposer, vous pouvez reproduire les exemples dans Visual Studio. Mais vous devrez alors pralablement crer un projet spcique et demander chaque fois lexcution pour visualiser le rsultat. Vous pouvez vous reporter au chapitre Crer une application
Renvoi Windows page 132 pour vous aider crer votre projet.

1.5 Checklist
Les notions essentielles que nous avons vues dans ce premier chapitre sont :
j j j j

le matriel ncessaire pour dbuter en programmation XAML ; les bases du XML ; comment fonctionne XAML ; comment utiliser loutil XAMLPad.

Le guide du codeur 19

Ch apit re

2 Fonctionnalits de base
Afficher du texte .......................................... Introduire du texte ....................................... Crer un bouton .......................................... Afficher un cadre ......................................... Afficher une image ....................................... Checklist .................................................... 22 38 46 47 48 53

Fonctionnalits de base

Dans ce chapitre, nous allons voir de manire individuelle les diffrents lments de base ncessaires la ralisation dune interface utilisateur. Cela nous permettra daborder laffichage et la saisie de texte, laffichage dune image et lutilisation dun bouton. Avec ce minimum de connaissance, nous pourrons ensuite passer ltape suivante, qui sera le placement des lments. Cest seulement aprs que nous aborderons les autres contrles classiquement utiliss. Dans le but de grouper les fonctionnalits, nous ne nous contenterons pas de survoler ces fonctionnalits mais les verrons assez en profondeur.

2.1 Afficher du texte


XAML offre deux possibilits de base pour laffichage de texte. Dans ce chapitre, nous verrons les deux mthodes et dcouvrirons les avantages de lune et de lautre. Nous dcouvrirons en mme temps de nombreuses possibilits qui pourront tre exploites avec la majorit des contrles. Le premier des contrles est de loin le plus connu puisquil sagit du Label, lautre est le TextBlock, que nous allons dcouvrir ensemble.

Avec un Label
Le Label est probablement le contrle le plus utilis. Il reste trs simple manipuler mais, comme vous allez le constater, il nous rserve dagrables surprises. Pour crer un label, vous devez utiliser la balise du mme nom.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <StackPanel> <Label> Mon premier label. </Label> </StackPanel> </Page>

Ne vous souciez pas pour linstant des balises Page et StackPanel. Nous verrons ultrieurement quoi elles servent et comment les utiliser. Sachez seulement que, sans la balise Page ou une autre balise racine valide, vous ne pourrez visualiser le rsultat. La balise StackPanel sert de conteneur. Nous reviendrons sur les conteneurs dans le chapitre Disposer les
Renvoi lments lcran sur la mise en page (page 56).

22 Le guide du codeur

Afficher du texte

Dans la suite, ces balises ne seront plus systmatiquement reprises au sein des exemples mais elles devront videmment tre prsentes.

b Figure 2-1 : Une simple tiquette

Au lieu de placer le code entre la balise de dbut et la balise de n du nud Label, vous pouvez galement opter pour assigner lattribut Content. Le rsultat sera le mme. La syntaxe devient alors :
<Label Content="Mon premier label."/>

Porte des explications Les attributs que nous allons voir dans cette partie seront galement utilisables pour les autres contrles que nous aborderons ultrieurement.

Comme beaucoup de contrles, le Label occupe un espace rectangulaire. Nous pouvons nous en rendre compte en affichant un bord autour de notre contrle.
<Label BorderBrush="Chocolate" BorderThickness="1"> Mon premier label. </Label>

Les deux attributs sont ncessaires car aucune couleur nest dnie par dfaut et la taille est de zro.

Le guide du codeur 23

Fonctionnalits de base

b Figure 2-2 : Une tiquette dans un cadre

La taille occupe dpend de divers paramtres comme la taille de la fentre. Si vous souhaitez contrler la taille de cette zone, vous pouvez utiliser les attributs Width et Height. Dans lexemple, nous allons xer la taille 200 pixels de large sur 60 pixels de haut.
<Label BorderBrush="Chocolate" BorderThickness="1" Width="200" Height="60"> Mon premier label. </Label>

Comme vous pouvez le constater, la zone occupe a t modie.

b Figure 2-3 : La taille dune tiquette

24 Le guide du codeur

Afficher du texte

Centrage Notez au passage que par dfaut le contrle est centr horizontalement.

Ce nest pas le seul moyen de contrler la taille du Label. XAML met galement notre disposition les attributs MinWidth, MinHeight, MaxWidth et MaxHeight. Avec ces attributs, vous laissez la taille sadapter lenvironnement tout en xant des valeurs limites.
<Label BorderBrush="Chocolate" BorderThickness="1" MinWidth="100" MinHeight="30" MaxWidth="300" MaxHeight="80"> Mon premier label. </Label>

b Figure 2-4 : Une tiquette avec MinWidth et MaxWidth

Si la position du texte ne vous convient pas, vous avez lopportunit de modier lalignement horizontal et vertical. Vous pouvez utiliser les attributs HorizontalContentAlignment et VerticalContentAlignment.
<Label BorderBrush="Chocolate" BorderThickness="1" Width="200" MinHeight="60" HorizontalContentAlignment="Center" VerticalContentAlignment="Bottom"> Mon premier label. </Label>
Le guide du codeur 25

Fonctionnalits de base

Les valeurs possibles sont respectivement Left, Rigth, Center, Stretch et Top pour lalignement horizontal et Bottom, Center et Stretch pour lalignement vertical.

b Figure 2-5 : Alignement du contenu dune tiquette

Ne pas confondre Ne confondez pas ces deux attributs avec les attributs VerticalAlignment et HorizontalAlignment, qui permettent de centrer le contrle dans son conteneur.

<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <Label BorderBrush="Chocolate" BorderThickness="1" HorizontalAlignment="Center" VerticalAlignment="Center"> Mon premier label. </Label> </Page>

Absence de la balise StackPanel Pour une meilleure comprhension, dans cet exemple, la balise StackPanel a t retire. Cest pourquoi le code est prsent complet.

26 Le guide du codeur

Afficher du texte

b Figure 2-6 : Centrer ltiquette

Si la police par dfaut ne vous convient pas, vous disposez de cinq attributs diffrents pour ladapter votre got. Lattribut FontFamily permet de slectionner le type de police comme Arial ou Verdana. Lattribut FontSize dtermine la taille.
<Label HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="Verdana" FontSize="14" FontWeight="Heavy" FontStyle="Italic" FontStretch="UltraExpanded"> Mon premier label. </Label>

b Figure 2-7 : Affichage dans une police diffrente

Le guide du codeur 27

Fonctionnalits de base

Contrairement ce que nous connaissions avant, les possibilits sont bien plus tendues. FontStrech accepte pas moins de dix valeurs diffrentes allant de UltraCondensed UltraExpanded alors que FontWeight accepte quatorze valeurs allant de Thin Heavy. La taille du font peut varier de 1 35 791. En ce qui concerne les couleurs, nous disposons des attributs trs traditionnels Foreground et Background.
<Label HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="Verdana" FontSize="14" FontWeight="Heavy" FontStyle="Italic" FontStretch="UltraExpanded" Foreground="Aquamarine" Background="Blue"> Mon premier label. </Label>

b Figure 2-8 : Couleur de fond et davant-plan

Nous avons vu les principales possibilits offertes avec le contrle Label et qui sont par ailleurs applicables aux autres contrles classiques que nous verrons dans ce chapitre.

Nommer ses contrles Pour pouvoir ultrieurement interagir avec les diffrents contrles que vous avez crs, ils doivent porter un nom. Bien que vous nayez pas interagir avec tous les contrles, je vous conseille de les nommer tous, et ce y compris les Label. Votre code sen trouvera beaucoup plus clair.

28 Le guide du codeur

Afficher du texte

Pour nommer le contrle, vous devez utiliser lattribut Name. Vous vous rendrez vite compte quil est utile dutiliser systmatiquement cet attribut.
<Label Name="lblPremierLabel" HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="Verdana" FontSize="14" FontWeight="Heavy" FontStyle="Italic" FontStretch="UltraExpanded" Foreground="Aquamarine" Background="Blue"> Mon premier label. </Label>

Donner toujours des noms clairs ses contrles La comprhension nale de votre programme sera grandement accrue si les noms donns sont clairs et sans ambigut. Si, sur le moment, cela vous parat superu, lors de modications ultrieures vous serez trs heureux de lavoir fait. Dans les exemples, en plus dun nom explicite, je commence par un prxe qui identie le type de contrle. Il existe dautres conventions de nommage, chacune ayant ses avantages et ses inconvnients. Choisissez-en une et tenez-vous-y.

Vous pouvez par exemple opter pour cette convention de nommage.


Exemple de convention de nommage Type Convention

Nom des classes

CamelCase. Ex. : MaClasse Remarque : CamelCase est un terme courant qui

signie que chaque mot dans le nom donn commence par une majuscule et que le reste du mot est en minuscule. Nom dun membre public
CamelCase suivi de _m. La bonne pratique veut que les membres publics soient vits. Prfrez un membre priv associ une proprit pour y accder. Ex. : NomDeRue_m CamelCase commenant par une minuscule et termin par _m. Ex. : nomDeRue_m CamelCase commenant par une majuscule. Si la proprit est associe un membre, le nom de la proprit sera le mme que le nom du membre associ mais sans le _m. Ex. : NomDeRue

Nom dun membre priv Nom dune proprit publique

Le guide du codeur 29

Fonctionnalits de base

Exemple de convention de nommage Type Convention

Nom dune proprit prive

camelCase commenant par une minuscule Si la proprit est associe un membre, le nom de la proprit sera le mme que le nom du membre associ mais sans le _m. Ex. : nomDeRue CamelCase commenant par une minuscule. Ex. : nomDeRue (en VB, vu que le langage est insensible aux majuscules, il sera probablement utile dajouter le suffixe _v pour viter la confusion avec la proprit) CamelCase termin par le type de contrle. Microsoft prconise maintenant que le type soit crit dans son entiret (TextBox et non Txt). Ex. : nomDeRueTextBox Comme dailleurs dans ce livre, vous trouverez souvent le type de contrle en prxe et non en suffixe. Toutefois, le fait de placer le type la n a lavantage de regrouper les lments concernant une mme donne dans lIntelliSense. La bonne pratique veut que les contrles soient privs. Si tel nest pas le cas, le nom doit commencer par une majuscule.

Nom de variable

Nom dun contrle

Constante Espace de nom numration

Tout en majuscule prcd de _. Ex. : _CHEMINDUFICHIER


CamelCase. Ex. : MonProgramme.Operation CamelCase Ex. : Couleur.Bleu Couleur.Vert

Avec un TextBlock
Lorigine du TextBlock est plutt Web que Windows. Il fait pourtant son entre dans lAPI disponible pour les applications Windows classiques. Contrairement au contrle de type Label, TextBlock nhrite pas de la classe Control. TextBlock est optimis pour laffichage de longs textes. Je ne reviendrai pas sur la manire de modier les couleurs ou la police, il suffit dutiliser lidentique les techniques vues prcdemment. Le TextBlock ncessite un peu plus de mise en forme que le Label, qui se contente dun minimum. En effet, si nous utilisons la commande ci-dessous :
<TextBlock Name="blckTexte"> Nous sommes maintenant arrivs notre deuxime contrle. Comme vous avez dj pu le constater, XAML est la fois simple dutilisation et performant. </TextBlock>
30 Le guide du codeur

Afficher du texte

le rsultat ne sera pas la hauteur de nos esprances.

b Figure 2-9 : Un bloc de texte

Il est possible de dterminer une taille la zone daffichage, et ainsi nous pouvons demander un arrangement automatique du texte.
<TextBlock Name="blckTexte" MaxWidth="200" MaxHeight="70" TextWrapping="Wrap"> Nous sommes maintenant arrivs notre deuxime contrle Comme vous avez dj pu le constater, XAML est la fois simple dutilisation et performant. </TextBlock>

b Figure 2-10 : Un bloc de texte multiligne

Le guide du codeur 31

Fonctionnalits de base

Ce qui est beaucoup plus conforme au rsultat attendu.

Limiter la taille au lieu de la xer Au lieu de xer la taille, choisissez de dlimiter une taille maximale. De cette manire, si nous rduisons la taille de la fentre, le texte sadapte au mieux aux modications.

b Figure 2-11 : Le mme bloc

Lattribut TextWrapping peut prendre les valeurs NoWrap, Wrap mais galement WrapWithOverflow. Dans ce dernier cas, la taille du contrle sera automatiquement agrandie si ncessaire, mme si vous avez dni une taille avec lattribut Height. Bien sr, si pour quelque motif que ce soit la zone rserve au TextBlock devient trop petite, le texte ne pourra plus tre entirement affich. Dans ce cas, lattribut TextTrimming nous permettra dinclure automatiquement les signalant ainsi lutilisateur que le texte est incomplet.
<TextBlock Name="blckTexte" MaxWidth="200" MaxHeight="70" TextWrapping="Wrap" TextTrimming="WordEllipsis"> Nous sommes maintenant arrivs notre deuxime contrle Comme vous avez dj pu le constater, XAML est la fois simple dutilisation et performant. </TextBlock>

b Figure 2-12 : Un bloc de texte avec coupure

32 Le guide du codeur

Afficher du texte

Lattribut TextTrimming, en plus de la valeur par dfaut (None), peut prendre deux valeurs diffrentes. Soit WordEllipsis, comme dans notre exemple, o larrt se fait aprs un mot entier, soit CharacterEllipsis, qui provoque larrt derrire nimporte quel caractre. Comme vous pouvez le constater, le contrle se place trs prs des bords de son conteneur, ce qui nest pas forcment du meilleur effet. Vous pouvez dnir une marge tout autour de votre contrle en utilisant lattribut Margin. Cet attribut nest pas spcique au TextBlock et nous aurions dj pu lutiliser avec le contrle de type Label.
<TextBlock Name="blckTexte" MaxWidth="200" MaxHeight="70" TextWrapping="Wrap" TextTrimming="WordEllipsis" Margin="5,5,5,5" > Nous sommes maintenant arrivs notre deuxime contrle. Comme vous avez dj pu le constater, XAML est la fois simple dutilisation et performant. </TextBlock>

b Figure 2-13 : Marges autour dun contrle

Pour terminer les spcicits du TextBlock par rapport au Label, il nous reste voir lattribut TextAlignment. Les valeurs possibles sont les trs classiques Left, Right, Center et Justify.
<TextBlock Name="blckTexte" MaxWidth="200" MaxHeight="70" TextWrapping="Wrap" TextTrimming="WordEllipsis" Margin="5,5,5,5" TextAlignment="Justify" > Nous sommes maintenant arrivs notre deuxime contrle. Comme vous avez dj pu le constater, XAML est la fois simple dutilisation et performant. </TextBlock>

Le guide du codeur 33

Fonctionnalits de base

b Figure 2-14 : Alignement du texte

De plus, le TextBlock permet denrichir le contenu. Vous pouvez par exemple y inscrire du texte en gras, en italique ou soulign.
<TextBlock Name="blckTexte" MaxWidth="200" MaxHeight="70" TextWrapping="Wrap" TextTrimming="WordEllipsis" Margin="5,5,5,5" TextAlignment="Justify" > Nous sommes maintenant arrivs notre deuxime contrle Comme vous avez dj pu le constater, <Bold>XAML</Bold> est la fois <Underline>simple dutilisation</Underline> et <Italic>performant</Italic>. </TextBlock>

b Figure 2-15 : Enrichissement du texte

34 Le guide du codeur

Afficher du texte

Si ces possibilits denrichissement ne vous suffisent pas, vous pouvez utiliser TextDecoration. Cette proprit nest pas spcique TextBlock, et vous pouvez la retrouver quasiment partout o du texte est affich. Elle est accessible grce la balise TextBlock. TextDecorations, pour un autre contrle, remplace TextBlock par la valeur approprie. Elle permet dajouter des dcorations vos caractres. La description de la dcoration est dnie lintrieur du nud TextDecoration. La dcoration est en ralit un trait qui peut tre plac quatre endroits diffrents. La position est dnie au moyen de la proprit Location. Elle peut tre au-dessus du caractre, au milieu du caractre, sous le caractre ou juste sous le caractre. La taille, la couleur, la forme du trait sont dnies avec un objet de type Pen. Ci-dessous, vous trouverez un code complet reprenant les diffrentes possibilits numres ci-avant.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <StackPanel> <TextBlock TextWrapping="WrapWithOverflow" Margin="5,5,5,5" Width="800" HorizontalAlignment="Center"> <Bold>Non seulement vous pouvez utiliser lenrichissement classique</Bold> mais vous pouvez aussi utiliser un enrichissement plus complexe <LineBreak/>

Le TextBlock suivant utilise une dcoration au milieu du caractre. Le trait est rouge et dune paisseur de 2 points.
<TextBlock> <TextBlock.TextDecorations> <TextDecoration Location="Strikethrough"> <TextDecoration.Pen> <Pen Brush="Red" Thickness="2"/> </TextDecoration.Pen> </TextDecoration> </TextBlock.TextDecorations> comme du barr color </TextBlock> <LineBreak/>

Le TextBlock suivant utilise une dcoration sous le caractre. Le trait est bleu et toujours dune paisseur de 2 points.

Le guide du codeur 35

Fonctionnalits de base

<TextBlock> <TextBlock.TextDecorations> <TextDecoration Location="Underline"> <TextDecoration.Pen> <Pen Brush="Blue" Thickness="2"/> </TextDecoration.Pen> </TextDecoration> </TextBlock.TextDecorations> comme un soulignement en bleu </TextBlock> <LineBreak/>

Le TextBlock suivant utilise une dcoration juste sous le caractre. Le trait est noir et dune paisseur de 1 point.
<TextBlock> <TextBlock.TextDecorations> <TextDecoration Location="Baseline"> <TextDecoration.Pen> <Pen Brush="Black" Thickness="1"/> </TextDecoration.Pen> </TextDecoration> </TextBlock.TextDecorations> comme une fine ligne sous les caractres </TextBlock> <LineBreak/>

Le TextBlock suivant utilise une dcoration au-dessus du caractre. Le trait est rouge et dune paisseur de 2 points.
<TextBlock> <TextBlock.TextDecorations> <TextDecoration Location="OverLine"> <TextDecoration.Pen> <Pen Brush="Red" Thickness="2"/> </TextDecoration.Pen> </TextDecoration> </TextBlock.TextDecorations> ou encore une ligne au dessus </TextBlock> <LineBreak/>

Le TextBlock suivant utilise plusieurs dcorations. Une premire juste sous le caractre. Le trait est rouge, dune paisseur de 1 point et discontinu. La seconde est sous le caractre. Le trait est bleu, dune paisseur de 1 point et est continu. Les deux ensembles ralisent un double trait spcique.

36 Le guide du codeur

Afficher du texte

<TextBlock> <TextBlock.TextDecorations> <TextDecoration Location="Baseline"> <TextDecoration.Pen> <Pen Brush ="Red" Thickness="1"> <Pen.DashStyle> <DashStyle Dashes="1"/> </Pen.DashStyle> </Pen> </TextDecoration.Pen> </TextDecoration> <TextDecoration Location="Underline"> <TextDecoration.Pen> <Pen Brush="Blue" Thickness="1"/> </TextDecoration.Pen> </TextDecoration> </TextBlock.TextDecorations> Bien sur vous pouvez mlanger ces options et utiliser </TextBlock> <LineBreak/>

Ce dernier TextBlock utilise une dcoration sous le caractre. Le trait est dune paisseur de 4 points et dun dgrad allant dun bleu lger un bleu fonc.
<TextBlock> <TextBlock.TextDecorations> <TextDecoration Location="Underline"> <TextDecoration.Pen> <Pen Thickness="4"> <Pen.Brush> <LinearGradientBrush> <LinearGradientBrush .GradientStops> <GradientStop Color="LightBlue" Offset="0"/> <GradientStop Color="DarkBlue" Offset="1"/> </LinearGradientBrush .GradientStops> </LinearGradientBrush> </Pen.Brush> </Pen> </TextDecoration.Pen> </TextDecoration> </TextBlock.TextDecorations> ou encore dutiliser des dgrads

Le guide du codeur 37

Fonctionnalits de base

</TextBlock> <LineBreak/> <LineBreak/> Les possibilits sont infinies ! </TextBlock> </StackPanel> </Page>

b Figure 2-16 : Utiliser des dcorations

Notez au passage lutilisation de la balise LineBreak pour provoquer un passage ligne impos. Dans lexemple, vous aurez pu constater la prsence dun dgrad ;
Renvoi si vous souhaitez en savoir plus sur cette fonctionnalit, elle est

traite au chapitre Crer un style page 229.

2.2 Introduire du texte


Le contrle TextBox est, avec le Label, probablement le plus utilis. Il est aussi un des plus simples. Le code suivant va dj nous permettre dobtenir un TextBox tout fait fonctionnel.
<TextBox Name="txtNom" />

38 Le guide du codeur

Introduire du texte

b Figure 2-17 : Une bote de texte

Nous pouvons appliquer ce contrle tout ce que nous avons dj vu pour le contrle Label.

Appliquer des marges Pour une question de lisibilit et de mise en page, je vous conseille dappliquer systmatiquement des marges vos contrles de type TextBox.

<TextBox Name="txtNom" Margin="3,3,3,3" />

b Figure 2-18 : Un TextBox avec marges

Le guide du codeur 39

Fonctionnalits de base

Lattribut MaxLength va nous permettre de limiter lencodage. Ce qui est bien pratique quand le contenu doit tre enregistr dans une base de donnes. Vous vitez ainsi une perte dinformation linsu de lutilisateur ou des problmes plus tard dans le code. Lattribut CharacterCasing limite lui aussi lencodage en imposant automatiquement le texte en majuscule (valeur Upper) ou en minuscule (valeur Lower). Jaurais galement apprci la possibilit de forcer la premire lettre en majuscule et les autres en minuscules mais, actuellement, ce nest pas prvu.
<TextBox Name="txtNom" Margin="3,3,3,3" MaxLength="20" CharacterCasing="Upper" />

b Figure 2-19 : Majuscules imposes

Un TextBox peut galement tre multiligne. Dans ce cas, vous aurez la possibilit dajuster son utilisation avec les attributs AcceptsReturn, AcceptsTab et TextWrapping. Lattribut AcceptsReturn autorise ou non lutilisation du passage la ligne impos (touche [Entre]). Lattribut AcceptsTab autorise ou non lemploi de la tabulation.

Dplacement par tabulations Si vous autorisez lutilisation de la tabulation, elle ne pourra videmment plus tre utilise pour passer au champ suivant. Toutefois, mais il faut le savoir, la combinaison [Ctrl]+[Tab] remplit aussi cette fonction.

40 Le guide du codeur

Introduire du texte

Lattribut TextWrapping dtermine le comportement du contrle quand le texte frapp arrive en bout de ligne. Les valeurs possibles sont NoWrap, Wrap et WrapWithOverflow. Cette dernire va non seulement provoquer un passage la ligne automatique mais, contrairement Wrap, galement tendre vers le bas la zone prvue initialement.
<TextBox Name="txtNom" Margin="3,3,3,3" MinHeight="80" AcceptsReturn="True" AcceptsTab="True" TextWrapping="WrapWithOverflow" />

b Figure 2-20 : Tabulation dans un TextBox

Dans lexemple ci-dessus, le texte arrive sur la dernire ligne. Si daventure nous continuons la frappe, vous pouvez constater leffet de WrapWithOverflow.

b Figure 2-21 : Zone de dbordement

Le guide du codeur 41

Fonctionnalits de base

Combiner la zone de dbordement et la hauteur maximale Si vous utilisez loption WrapWithOverflow, il est prfrable de xer une taille maximale en utilisant lattribut MaxHeight.

Gestion des lignes Comme vous pouvez le remarquer, rien nindique quil sagisse ou non dun

TextBox multiligne. En fait, un TextBox a toujours les capacits multiligne mais,


si vous nautorisez ni le passage automatique la ligne (Wrap) ni le retour la ligne impos, lencodeur ne pourra pas crer de seconde ligne. Le TextBox est capable de faire dler le texte aussi bien horizontalement que verticalement quand cela est ncessaire.

Les attributs MinLines et MaxLines sont une bonne alternative lutilisation des attributs MinHeight et MaxHeight. MinLines et MaxLines xent respectivement le nombre minimal et maximal de lignes visibles. La taille sera automatiquement adapte en fonction. De cette faon, la dernire ligne visible sera toujours complte, ce qui nest pas le cas en xant les limites de la hauteur en nombre de points.
<TextBox Name="txtNom" Margin="3,3,3,3" MinLines="2" MaxLines="3" AcceptsReturn="True" AcceptsTab="True" TextWrapping="Wrap" />

Selon les comportements que vous aurez dnis pour votre TextBox, lutilisateur sera oblig de faire dler le texte horizontalement et verticalement. Sans aide visuelle, il nest pas toujours ais pour lutilisateur de voir le texte cach. Le mieux dans ce cas est dajouter des barres de dlement. vous de choisir celle quil vous faut.
<TextBox Name="txtNom" Margin="3,3,3,3" MinLines="2" MaxLines="3" MaxWidth="300" AcceptsReturn="True" AcceptsTab="True" TextWrapping="NoWrap" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible" />

42 Le guide du codeur

Introduire du texte

b Figure 2-22 : Dlement dans un TextBox

Les valeurs possibles pour les attributs VerticalScrollBarVisibility et HorizontalScrollBarVisibility sont Auto, Hidden, Disabled et Visible. Pour plus dinformations sur lutilisation des valeurs possibles, reportezRenvoi vous au paragraphe Autoriser le dlement page 77.

Conit entre hauteur et nombre de lignes Si vous utilisez simultanment les attributs MinLines, MaxLines et les attributs MinHeight, MaxHeight, ce sont ces derniers qui auront la prsance. MinLines et MaxLines nauront ds lors aucun effet.

Dans certaines circonstances, vous souhaiterez certainement afficher un TextBox mais sans autoriser lutilisateur en modier le contenu. Pour ce faire, vous disposez de deux possibilits, soit utiliser lattribut IsReadOnly, soit utiliser lattribut IsEnabled. Chacune de ces mthodes offre ses avantages et ses inconvnients. Voyons dabord leffet de IsReadOnly.
<TextBox Name="txtNom" Margin="3,3,3,3" Text="Ce texte est en lecture seule." IsReadOnly="True" />

Le guide du codeur 43

Fonctionnalits de base

b Figure 2-23 : Un TextBox en lecture seule

Visuellement, il ny a aucune diffrence entre un TextBox limit la lecture et un autre TextBox. Toutefois, il ne vous sera pas possible dintroduire du texte dans ce contrle. En revanche, vous pourrez slectionner du texte pour faire un copier en vue de le coller ailleurs.

Valeur par dfaut Il est difficile de concevoir une TextBox non modiable sans valeur par dfaut. Pour donner cette valeur, vous devez utiliser lattribut Text.

En revanche, avec lattribut IsEnabled, lutilisateur visualise directement que le champ est inaccessible.
<TextBox Name="txtNom" Margin="3,3,3,3" Text="Ce texte est en lecture seule." IsEnabled="False" />

Cette technique a toutefois deux dfauts. Premirement, il nest pas possible de slectionner du texte en vue de le copier ailleurs. Deuximement, beaucoup dutilisateurs se plaignent du manque de lisibilit des TextBox dsactivs. Vous pouvez modier les attributs de couleur de votre TextBox pour quil affiche visuellement son tat soit en copiant le style dun TextBox dsactiv, soit en utilisant votre propre charte graphique.

44 Le guide du codeur

Introduire du texte

b Figure 2-24 : Un TextBox dsactiv

Dans cet exemple, le style du champ en lecture seule est proche du style du champ dsactiv tout en tant plus lisible.
<TextBox Name="txtNom" Margin="3,3,3,3" Text="Ce texte est en lecture seule." IsEnabled="False" /> <TextBox Name="txtNom2" Margin="3,3,3,3" Text="Ce contrle est en lecture seule." IsReadOnly="true" Foreground="Gray" Background="Beige" />

b Figure 2-25 : TextBox dsactiv ou en lecture seule

Le guide du codeur 45

Fonctionnalits de base

Introduire un mot de passe Si vous dsirez crer une zone de saisie pour introduire un mot de passe, utilisez la balise PasswordBox en lieu et place de TextBox. Il ny a pas de diffrence majeure dans leur utilisation si ce nest que les caractres affichs sont remplacs par des * et que la proprit Text est remplace par la proprit Password.

2.3 Crer un bouton


Le bouton est galement un contrle indispensable, ne serait-ce que pour les clbres boutons OK et Annuler. Comme pour le Label, vous pouvez lutiliser selon deux variantes lgrement diffrentes.
<Button Name="btnOk" Width="80" Height="30" > Ok </Button> <Button Name="btnCancel" Content="Annuler" Width="80" Height="30" />

b Figure 2-26 : Affichage de simples boutons

46 Le guide du codeur

Afficher un cadre

Fixer la taille des boutons Gnralement, la taille des boutons prsents dans un mme cran est xe. Ne pas respecter cette rgle produit le plus souvent un trs mauvais effet visuel.

De manire gnrale, le bouton OK sera prsent comme bouton par dfaut. De mme manire, le bouton Annuler devrait tre associ la touche [Echap]. Pour quun bouton soit le bouton par dfaut, il suffit dutiliser lattribut IsDefault. Pour associer un bouton la touche [Echap], il suffit dutiliser lattribut IsCancel.
<Button Name="btnOk" IsDefault="True" Width="80" Height="30" > Ok </Button> <Button Name="btnCancel" Content="Annuler" Width="80" Height="30" IsCancel="True"/>

Nous devons encore pouvoir associer le bouton avec une action bien dnie. Toutefois, cette opration faisant appel du code .NET, nous reviendrons dessus dans le chapitre sur les vnements (page 138).

2.4 Afficher un cadre


Comme nous lavons vu prcdemment, certains contrles possdent leurs propres attributs pour raliser un cadre autour deux. Ce nest toutefois pas le cas de tous. Le contrle Border est l pour pallier ce problme. Ce contrle est en dnitive trs couramment utilis. Il permet de crer des cadres partout o vous en avez besoin.
<Border Background="LightBlue" BorderBrush="DarkBlue" BorderThickness="2" Width="200" Height="100"/>

b Figure 2-27 : Crer un bord Le guide du codeur 47

Fonctionnalits de base

Si vous souhaitez arrondir les coins, il suffit dutiliser lattribut CornerRadius.


<Border Background="LightBlue" BorderBrush="DarkBlue" BorderThickness="2" Width="200" Height="100" CornerRadius="20"/>

b Figure 2-28 : Bord coins arrondis

2.5 Afficher une image


Les images peuvent tre utiles soit pour amliorer la prsentation soit pour diffuser de linformation telle quune photo. Pour afficher une image avec XAML, nous utiliserons la balise Image.
<Image Name="imgPhoto"> <Image.Source> C:\Documents and Settings\All Users\Documents\ Mes images\chantillons dimages\Hiver.jpg </Image.Source> </Image>

48 Le guide du codeur

Afficher une image

b Figure 2-29 : Afficher une photo

Erreur dans le code Le contenu de la balise Image est volontairement scind en deux lignes pour une question de lisibilit de lexemple. Toutefois, si vous dsirez le reproduire, il sera ncessaire de regrouper le chemin du chier sur une mme ligne.

Le nud ls ImageSource permet de dnir le chier qui sera affich. Les formats supports sont bmp, gif, ico, jpg, png et tiff. Vous pouvez galement xer les dimensions de limage avec les diffrents attributs MinWidth, MaxWidth, MinHeight, MaxHeight ou encore, comme dans lexemple ci-dessous, en faire une miniature en utilisant les attributs Width et Height.
<Image Name="imgPhoto" Width="100" Height="100" > <Image.Source> C:\Documents and Settings\All Users\Documents\ Mes images\chantillons dimages\Hiver.jpg </Image.Source> </Image>
Le guide du codeur 49

Fonctionnalits de base

b Figure 2-30 : Afficher une miniature

Il existe une seconde possibilit pour afficher des images mais il sagit alors non pas directement dun contrle placer dans votre page mais dune image utilise dans un contrle ; par exemple insrer limage comme fond dun bouton, dun cadre ou dune page.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <Page.Background> <ImageBrush ImageSource="\Emoticons\no.gif" /> </Page.Background> <StackPanel> <Label> Une fentre avec une image de fond </Label> </StackPanel> </Page>

50 Le guide du codeur

Afficher une image

b Figure 2-31 : Afficher une image comme fond de page

ImageBrush dispose dattributs tout fait particuliers pour grer lapparence de limage. Il nest pas question de taille puisque celle-ci dpend du conteneur. En revanche, il est toutefois possible de contrler la taille relative en utilisant lattribut Viewport. Si vous lassociez TileMode, vous pouvez par exemple crer une mosaque.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <Page.Background> <ImageBrush Viewport="0.5,0.5,0.5,0.5" TileMode="TILE" ImageSource="\Emoticons\no.gif" /> </Page.Background> <StackPanel> <Label> Une fentre avec une image de fond </Label> </StackPanel> </Page>

Le guide du codeur 51

Fonctionnalits de base

b Figure 2-32 : Afficher une mosaque comme fond de page

Il est aussi possible de paramtrer ltirement de limage et son alignement en utilisant les attributs Stretch, AlignmentX.et AlignmentY.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <Page.Background> <ImageBrush Stretch="None" AlignmentY="Bottom" AlignmentX="Right" ImageSource="\Emoticons\no.gif" /> </Page.Background> <StackPanel> <Label> Une fentre avec une image de fond </Label> </StackPanel> </Page>

52 Le guide du codeur

Checklist

b Figure 2-33 : Afficher une image non tire

2.6 Checklist
Voici les points essentiels que nous avons abords dans ce chapitre :
j j j j j j j

laffichage des textes et leurs manipulations avec des Label et TextBlock ; laffichage et la saisie des textes avec TextBox ; la saisie dun mot de passe avec PasswordBox ; laffichage des boutons avec Button ; laffichage des images avec Image et ImageBrush ; la ralisation de cadres avec Border ; lutilisation des attributs les plus communs et utilisables avec la majorit des contrles ; lutilisation des dcorateurs avec TextDecoration.

Le guide du codeur 53

Ch apit re

3 Disposer les lments lcran


Utiliser les coordonnes ............................... Utiliser une grille ......................................... Mettre en page avec un WrapPanel ............... Utiliser un empilement .................................. Utiliser le docking ........................................ Autoriser le dlement ................................. Mlanger les techniques de mise en page ....... Crer une page composite ............................ Checklist .................................................... 56 61 68 70 72 77 81 88 90

Disposer les lments lcran

Avec les contrles vus au chapitre prcdent, nous possdons assez dlments pour raliser un cran complet et complexe. Ce qui nous manque maintenant, cest une mthode pour organiser tout cela. XAML ne se contente pas dune mthode mais nous en fournit plusieurs, chacune ayant ses avantages et ses inconvnients.

3.1 Utiliser les coordonnes


Lutilisation de Canvas est la mthode la plus proche de la technique utilise avec les anciens API. Si vous avez dj programm sous Windows, vous savez certainement que les contrles taient positionns relativement au coin suprieur gauche de la fentre. Pour positionner les contrles dans un Canvas, cest pareil. Comme premier exemple, plaons dans un cran des tiquettes et des botes de texte pour pouvoir introduire le nom, le prnom et ladresse dune personne.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <Canvas> <Label Name="lblNom" Canvas.Top="10" Canvas.Left="10"> Nom </Label> <TextBox Name="txtNom" Canvas.Top="10" Canvas.Left="80" Width="150" MaxLength="30" CharacterCasing="Upper" /> <Label Name="lblPrenom" Canvas.Top="10" Canvas.Left="240"> Prnom </Label> <TextBox Name="txtPrenom" Canvas.Top="10" Canvas.Left="300" Width="130" MaxLength="30"/> <Label Name="lblAdr" Canvas.Top="40" Canvas.Left="10"> Rue </Label> <TextBox Name="txtAdr" Canvas.Top="40" Canvas.Left="80" Width="350" MaxLength="80"/> <Label Name="lblCP" Canvas.Top="70" Canvas.Left="10"> Code postal </Label>
56 Le guide du codeur

Utiliser les coordonnes

<TextBox Name="txtCP" Canvas.Top="70" Canvas.Left="80" Width="50" MaxLength="5"/> <Label Name="lblLocalite" Canvas.Top="70" Canvas.Left="150"> Localit </Label> <TextBox Name="txtLocalite" Canvas.Top="70" Canvas.Left="200" Width="230" MaxLength="50"/> </Canvas> </Page>

b Figure 3-1 : Prsentation avec un Canvas

Comme vous pouvez le constater, le placement lcran se fait au moyen des attributs Canvas.Top et Canvas.Left. Il sagit de proprits attaches. Une proprit attache est en fait une proprit du parent, ici du Canvas, mais pour laquelle chaque enfant peut assigner une valeur diffrente. Cest pourquoi, bien que proprit de Canvas, lattribut Canvas.Top est par exemple un attribut des lments contenus dans le Canvas et non du Canvas lui-mme. La balise Canvas dispose elle-mme de quelques attributs. Lattribut Background vous permet de changer la couleur du fond si la couleur standard ne vous satisfait pas.
<Canvas Background="LightCoral">

Le guide du codeur 57

Disposer les lments lcran

b Figure 3-2 : La couleur du fond dun Canvas

Un autre attribut intressant est lattribut IsEnabled. En effet, si vous lui assignez la valeur False, lensemble des contrles contenus dans le Canvas seront eux aussi dsactivs.

Dsactiv et non lecture seule Noubliez pas toutefois les diffrences que nous avons vues prcdemment entre dsactiver et lecture seule pour un contrle tel que la bote de texte.

<Canvas IsEnabled="False" Background="LightCoral">

b Figure 3-3 : Un Canvas dsactiv

58 Le guide du codeur

Utiliser les coordonnes

Les attributs Canvas.Top et Canvas.Left ne sont pas les seuls utilisables pour positionner un contrle. Vous pouvez galement utiliser Canvas.Right et Canvas.Bottom, ce qui permet de placer un contrle relativement nimporte quel coin du Canvas. Ajoutons le code suivant devant la balise de n du nud Canvas.
<Border Width="100" Height="120" BorderThickness="1" Background="White" BorderBrush="Black" Canvas.Top="10" Canvas.Right="10"> <TextBlock Name="blkPhoto" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="20"> Photo </TextBlock> </Border> <Label Name="lblCopyright" Canvas.Bottom="10" Canvas.Right="10" Content="Micro Application 2006" />

b Figure 3-4 : Un Canvas avec diffrents points de rfrence

Le guide du codeur 59

Disposer les lments lcran

b Figure 3-5 : Le mme Canvas agrandi

Comme vous pouvez le constater, le fait de positionner un contrle non pas partir du coin suprieur gauche mais dun autre coin ne fait pas que changer le systme de coordonnes. Lors du redimensionnement de lcran, les contrles suivent le coin partir duquel ils sont positionns. Cette facult pourra tre utilise dans de nombreuses circonstances pour obtenir un cran beaucoup plus exible.

Fixer une taille minimale son Canvas Si vous ne xez pas une taille minimale votre Canvas, les lments contenus vont invitablement se chevaucher si la fentre est rduite au-del de la taille critique.

En remplaant la balise Canvas dans lexemple par celle ci-dessous, nous empcherons ce comportement chaotique.
<Canvas Background="LightBlue" MinWidth="550" MinHeight="200">

60 Le guide du codeur

Utiliser une grille

3.2 Utiliser une grille


Cette mthode est gnralement la mthode la plus recommande car elle offre un trs haut niveau dadaptabilit du contenu de lcran sa taille et donc galement aux changements de rsolution. Elle est toutefois plus complexe mettre en uvre. Lide est de placer un contrle par cellule de la grille. Il y a donc lieu de bien dnir la grille pour obtenir le rsultat voulu. Essayons de reproduire lexemple prcdent mais avec la balise Grid au lieu de Canvas. Lobjectif de lutilisation dune grille tant une plus grande adaptabilit, nous ne xerons pas la taille des contrles. Si nous tudions lcran tel quil est dsir, nous pouvons en dduire quil ncessite 4 lignes et 5 colonnes.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <Grid>

La premire chose faire lorsque lon utilise une grille, cest de dnir les lignes et les colonnes.
<Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> <ColumnDefinition /> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions>

Nous pouvons ensuite utiliser les contrles tout en dnissant leurs positions dans la grille en utilisant Grid.Row et Grid.Column.
<Label Name="lblNom" Grid.Row="0" Grid.Column="0"> Nom </Label> <TextBox Name="txtNom" Grid.Row="0" Grid.Column="1" MaxLength="30" CharacterCasing="Upper" /> <Label Name="lblPrenom" Grid.Row="0" Grid.Column="2">
Le guide du codeur 61

Disposer les lments lcran

Prnom </Label> <TextBox Name="txtPrenom" Grid.Row="0" Grid.Column="3" MaxLength="30"/> <Label Name="lblAdr" Grid.Row="1" Grid.Column="0"> Rue </Label> <TextBox Name="txtAdr" Grid.Row="1" Grid.Column="1" MaxLength="80"/> <Label Name="lblCP" Grid.Row="2" Grid.Column="0"> Code postal </Label> <TextBox Name="txtCP" Grid.Row="2" Grid.Column="1" MaxLength="5"/> <Label Name="lblLocalite" Grid.Row="2" Grid.Column="2" > Localit </Label> <TextBox Name="txtLocalite" Grid.Row="2" Grid.Column="3" MaxLength="50"/> <Border BorderThickness="1" Background="White" Grid.Row="0" Grid.Column="4" BorderBrush="Black"> <TextBlock Name="blkPhoto" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="20"> Photo </TextBlock> </Border> <Label Name="lblCopyright" Content="Micro Application 2006" Grid.Row="3" Grid.Column="4"/> </Grid> </Page>

Comme vous pouvez le constater, la dnition de la grille se fait au dbut en utilisant les collections RowDefinitions et ColumnDefinitions. Ces collections contiennent autant dlments que de lignes ou de colonnes dsires. la place des attributs Canvas.Top et autre Canvas.Left, ce sont les attributs Grid.Column et Grid.Row.

Dbut de numrotation La numrotation des lignes et des colonnes commence 0. La ligne 1 est donc bel et bien la seconde ligne.

Malheureusement, comme vous pouvez le voir ci-dessous, le rsultat obtenu nest pas vraiment la hauteur des esprances.
62 Le guide du codeur

Utiliser une grille

b Figure 3-6 : Affichage avec une grille

Commenons par le plus simple, le fond dcran nest pas color. Pour cela, pas de soucis, il suffit dutiliser le mme attribut que pour Canvas.
<Grid Background="LightBlue">

Autre problme vident, la zone de saisie de ladresse est limite la deuxime colonne. Pour rsoudre ce problme, il est possible dtendre le contrle sur plusieurs colonnes en utilisant lattribut Grid.ColumnSpan.
<TextBox Name="txtAdr" Grid.Row="1" Grid.Column="1" MaxLength="80" Grid.ColumnSpan="3"/>

Il en va de mme pour la zone photo qui est limite une ligne. La solution est quasiment identique except que lattribut est Grid.RowSpan.
<Border BorderThickness="1" Background="White" Grid.Row="0" Grid.Column="4" Grid.RowSpan="3" BorderBrush="Black"> <TextBlock Name="blkPhoto" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="20"> Photo </TextBlock> </Border>

Le guide du codeur 63

Disposer les lments lcran

Avec lajout de ces nouveaux attributs, lcran est enn un peu plus ressemblant.

b Figure 3-7 : Le mme exemple un peu plus complet

Quelques amnagements sont encore ncessaires pour parfaire le travail.


<Label Name="lblCopyright" Content="Micro Application 2006" Grid.Row="3" Grid.Column="3" Grid.ColumnSpan="2" VerticalAlignment="Bottom" HorizontalAlignment="Right"/>

Le code ainsi modi va permettre de placer le copyright en bas droite de lcran, et ce quelle que soit sa dimension comme ctait le cas avec le canevas. Placez galement lattribut ci-dessous dans chaque balise TextBox et dans la balise Border.
Margin="2,2,2,2"

Le gros problme restant est llargissement inconsidr des botes de texte, qui dnature fortement leffet visuel de lcran. Pour y remdier, il suffit dassigner les attributs MaxHeight et VerticalAlignment chaque TextBox.

64 Le guide du codeur

Utiliser une grille

Par exemple en les xant aux valeurs suivantes :


MaxHeight="20" VerticalAlignment="Top"

Pour contrler le comportement de la fentre en cas de redimensionnement, vous pouvez ajuster les dimensions des lignes et des colonnes. Nhsitez pas utiliser les dimensions minimales et maximales.
<Grid.ColumnDefinitions> <ColumnDefinition Width="70"/> <ColumnDefinition MinWidth="60"/> <ColumnDefinition Width="50"/> <ColumnDefinition MinWidth="60"/> <ColumnDefinition MinWidth="120" MaxWidth="200"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition MinHeight="22"/> <RowDefinition MinHeight="22"/> <RowDefinition MinHeight="76"/> <RowDefinition MinHeight="20"/> </Grid.RowDefinitions>

b Figure 3-8 : Lexemple complet

Redimensionnez la fentre et voyez ce qui se passe. Bien sr, comme pour Canvas, vous pouvez utiliser lattribut IsEnabled pour dsactiver lensemble de la grille.

Visualiser la grille Parfois, pour faciliter la mise en page, il est intressant de voir les limites des cellules. Pour cela, utilisez lattribut ShowGridLines.

Le guide du codeur 65

Disposer les lments lcran

En complment de ces possibilits, XAML offre la possibilit de crer des bords mobiles pour permettre lutilisateur dajuster la taille que ce soit en largeur ou en hauteur. Cette possibilit doit tre mise en uvre en utilisant un GridSplitter. Cette balise va vous permettre de dnir dans la grille sur quelle cellule ou groupe de cellules vous dsirez placer la bordure mobile et dans quel sens. An de vous montrer cette fonctionnalit, nous allons construire un tableau de 3 lignes et 4 colonnes. La hauteur de la premire ligne pourra tre adapte ainsi que la largeur de la premire colonne. La premire partie du code est classique. Notez toutefois que 4 lignes et non 3 sont dnies. Nous reviendrons sur le pourquoi la n de lexercice. Ensuite, les 2 GridSplitter sont dnis. Le premier dans le sens vertical, via lattribut ResizeDirection= "Columns", lautre dans le sens horizontal avec ResizeDirection= "Rows". La position est donne respectivement avec Grid.Column et Grid.Row. ColSpan et RowSpan permettent dtendre la visibilit du bord sur lensemble des cellules.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <Grid> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition/> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition Height="5"/> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <GridSplitter Grid.Column="0" Grid.RowSpan="4" ResizeDirection="Columns" ShowsPreview="False"/> <GridSplitter Grid.Row="1" Grid.ColumnSpan="4" ResizeDirection="Rows" HorizontalAlignment="Stretch" ShowsPreview="True"/> </Grid> </Page>

66 Le guide du codeur

Utiliser une grille

b Figure 3-9 : Les bords mobiles

Lattribut ShowsPreview modie le comportement de telle sorte que, si vous souhaitez la prvisualisation, le bord ne bouge que quand vous lchez le bouton de la souris. Dans lintervalle, cest une ligne repre qui prvisualise la future position du bord.

b Figure 3-10 : Les bords mobiles avec prvisualisation

4 lignes au lieu de 3 Maintenant, comme promis, pourquoi 4 et non 3 lignes. Comme vous avez pu le constater, la hauteur de la ligne a t xe 5. En fait, cette astuce est utilise pour pallier un comportement diffrent entre le bord horizontal et vertical. Cette diffrence aura probablement disparu dans la version dnitive et

Le guide du codeur 67

Disposer les lments lcran

cette ligne supplmentaire naura plus lieu dtre mais, dans le doute, il vaut mieux savoir comment contourner le problme. Donc, si pour un bord vertical celui-ci se place correctement droite de la colonne, pour une ligne horizontale il napparat pas. En utilisant HorizontalAlignment= Stretch , le bord devient visible mais occupe toute la hauteur. Lide est donc dutiliser une ligne supplmentaire pour contenir le bord ainsi cr.

3.3 Mettre en page avec un WrapPanel


La mise en page avec un WrapPanel nest pas du tout adapte lexemple prcdent. En effet, avec un WrapPanel les contrles sont placs ct les uns des autres et sont renvoys automatiquement la ligne lorsque la n de celle-ci est atteinte.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <WrapPanel> <TextBlock Width="200" TextWrapping="WrapWithOverflow" Margin="5,5,5,5" TextAlignment="Justify"> <Bold>WrapPanel</Bold> La mise en page avec un WrapPanel nest pas du tout adapte lexemple prcdent. En effet avec un WrapPanel les contrles sont placs cot les un des autres et sont renvoys automatiquement la ligne lorsque la fin de celle-ci est atteinte. </TextBlock>

Les diffrents contrles doivent tre indiqus dans lordre dans lequel vous dsirez les voir apparatre. Ils sont affichs de gauche droite et de haut en bas.
<TextBlock Width="200" TextWrapping="WrapWithOverflow" Margin="5,5,5,5" TextAlignment="Justify"> <Bold>StackPanel</Bold> Lutilisation dun StackPanel offre encore des possibilits plus restreinte que le WrapPanel. Toutefois, contrairement au WrapPanel, il offre une structure moins mobile et donc beaucoup plus controlable. Dans un StackPanel, chaque contrle occupe une ligne. </TextBlock> <TextBlock Width="200" TextWrapping="WrapWithOverflow" Margin="5,5,5,5" TextAlignment="Justify">
68 Le guide du codeur

Mettre en page avec un WrapPanel

<Bold>Grid</Bold>: Cette mthode est gnralement la mthode la plus recommande car elle offre un trs haut niveau dadaptabilit du contenu de lcran sa taille et donc galement aux changements de rsolution. Elle est toutefois plus complexe mettre en uvre. </TextBlock> </WrapPanel> </Page>

b Figure 3-11 : Utilisation dun WrapPanel

Si vous redimensionnez la fentre, le WrapPanel se charge de replacer les contrles.

b Figure 3-12 : Le mme exemple redimensionn

Le guide du codeur 69

Disposer les lments lcran

3.4 Utiliser un empilement


Lutilisation dun StackPanel offre encore des possibilits plus restreintes que le WrapPanel. Toutefois, contrairement au WrapPanel, il offre une structure moins mobile et donc beaucoup plus facile contrler. Dans un StackPanel, chaque contrle occupe une ligne.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <StackPanel> <TextBlock TextWrapping="WrapWithOverflow" Margin="5,5,5,5" TextAlignment="Justify"> <Bold>WrapPanel</Bold> La mise en page avec un WrapPanel nest pas du tout adapte lexemple prcdent. En effet avec un WrapPanel les contrles sont placs cot les un des autres et sont renvoys automatiquement la ligne lorsque la fin de celle-ci est atteinte. </TextBlock>

Les diffrents contrles doivent tre indiqus dans lordre dans lequel vous dsirez les voir apparatre. Ils sont affichs de haut en bas.
<TextBlock TextWrapping="WrapWithOverflow" Margin="5,5,5,5" TextAlignment="Justify"> <Bold>StackPanel</Bold> Lutilisation dun StackPanel offre encore des possibilits plus restreinte que le WrapPanel. Toutefois, contrairement au WrapPanel, il offre une structure moins mobile et donc beaucoup plus controlable. Dans un StackPanel, chaque contrle occupe une ligne. </TextBlock> <TextBlock TextWrapping="WrapWithOverflow" Margin="5,5,5,5" TextAlignment="Justify"> <Bold>Grid</Bold>: Cette mthode est gnralement la mthode la plus recommande car elle offre un trs haut niveau dadaptabilit du contenu de lcran sa taille et donc galement aux changements de rsolution. Elle est toutefois plus complexe mettre en uvre. </TextBlock> </StackPanel> </Page>

70 Le guide du codeur

Utiliser un empilement

b Figure 3-13 : Utilisation dun StackPanel

b Figure 3-14 : Le mme code

Longueur de ligne Contrairement lexemple tel quil est dans le chapitre sur le WrapPanel, o nous avions dni la largeur avec la proprit Width, comme avec StackPanel les lments sont automatiquement placs lun sous lautre il nest pas ncessaire de xer la largeur.

Le guide du codeur 71

Disposer les lments lcran

3.5 Utiliser le docking


Avec un DockPanel vous aurez la possibilit de coller vos contrles sur les diffrents bords. Comme rien ne vaut un exemple, regardons le code ci-dessous, qui est driv des exemples prcdents.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <DockPanel>

Le contrle suivant sera coll sur le bord suprieur.


<Border BorderThickness="1" BorderBrush="Black" DockPanel.Dock="Top" Margin="2,2,2,2" > <TextBlock TextWrapping="WrapWithOverflow" Margin="5,5,5,5" TextAlignment="Justify"> <Bold>WrapPanel</Bold> La mise en page avec un WrapPanel nest pas du tout adapte lexemple prcdent. En effet, avec un WrapPanel les contrles sont placs ct les uns des autres et sont renvoys automatiquement la ligne lorsque la fin de celle-ci est atteinte. </TextBlock> </Border>

Ce contrle-ci sera en revanche coll sur le bord droit.


<Border BorderThickness="1" BorderBrush="Black" DockPanel.Dock="Right" Margin="2,2,2,2" Width="200"> <TextBlock TextWrapping="WrapWithOverflow" Margin="5,5,5,5" TextAlignment="Justify"> <Bold>StackPanel</Bold> Lutilisation dun StackPanel offre encore des possibilits plus restreintes que le WrapPanel. Toutefois, contrairement au WrapPanel, il offre une structure moins mobile et donc beaucoup plus contrlable. Dans un StackPanel, chaque contrle occupe une ligne. </TextBlock> </Border>

Ce dernier contrle sera quant lui coll sur le bord gauche.


<Border BorderThickness="1" BorderBrush="Black" DockPanel.Dock="Left" Width="200" Margin="2,2,2,2" HorizontalAlignment="Left">
72 Le guide du codeur

Utiliser le docking

<TextBlock TextWrapping="WrapWithOverflow" Margin="5,5,5,5" TextAlignment="Justify"> <Bold>Grid</Bold>: Cette mthode est gnralement La mthode la plus recommande car elle offre un trs haut niveau dadaptabilit du contenu de lcran sa taille et donc galement aux changements de rsolution. Elle est toutefois plus complexe mettre en uvre. </TextBlock> </Border> </DockPanel> </Page>

Tout dabord, des balises Border ont t ajoutes an de mieux visualiser le rsultat. Elles nont aucun but particulier si ce nest une meilleure comprhension du rsultat. Du fait de leur prsence, la taille des diffrents blocs est xe dans les balises Border et non plus dans les balises TextBlock. Les marges sont galement prsentes pour bien diffrencier les divers lments. Voyons maintenant le rsultat.

b Figure 3-15 : Exemple dutilisation dun DockPanel

Si nous ajoutons un cadre, celui-ci prendra automatiquement toute la place restant disponible.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <DockPanel> <Border BorderThickness="1" BorderBrush="Black" Margin="2,2,2,2" HorizontalAlignment="Center">
Le guide du codeur 73

Disposer les lments lcran

<TextBlock TextWrapping="WrapWithOverflow" Margin="5,5,5,5" TextAlignment="Justify"> <Bold>Grid</Bold>: Cette mthode est gnralement La mthode la plus recommande car elle offre un trs haut niveau dadaptabilit du contenu de lcran sa taille et donc galement aux changements de rsolution. Elle est toutefois plus complexe mettre en uvre. </TextBlock> </Border> </DockPanel> </Page>

b Figure 3-16 : Exemple dutilisation dun DockPanel

Lordre des contrles a une importance capitale quant au rsultat obtenu. Si nous ajoutons un cinquime cadre et que nous xions lattribut DockPanel.Dock Bottom, le cadre noccupera pas lentiret du bas dcran comme cest le cas pour le cadre du haut.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <DockPanel> <Border BorderThickness="1" BorderBrush="Black" DockPanel.Dock="Top" Margin="2,2,2,2" > <TextBlock TextWrapping="WrapWithOverflow" </TextBlock> </Border> <Border BorderThickness="1" BorderBrush="Black"

74 Le guide du codeur

Utiliser le docking

DockPanel.Dock="Right" Margin="2,2,2,2" Width="200"> <TextBlock TextWrapping="WrapWithOverflow" </TextBlock> </Border> <Border BorderThickness="1" BorderBrush="Black" DockPanel.Dock="Left" Width="200" Margin="2,2,2,2" HorizontalAlignment="Left"> <TextBlock TextWrapping="WrapWithOverflow" </TextBlock> </Border> <Border BorderThickness="1" BorderBrush="Black" DockPanel.Dock="Bottom" Margin="2,2,2,2" > <TextBlock TextWrapping="WrapWithOverflow" Margin="5,5,5,5" TextAlignment="Justify"> <Bold>WrapPanel</Bold> La mise en page avec un WrapPanel nest pas du tout adapte lexemple prcdent. En effet avec un WrapPanel les contrles sont placs cot les un des autres et sont renvoys automatiquement la ligne lorsque la fin de celle-ci est atteinte. </TextBlock> </Border> <Border BorderThickness="1" BorderBrush="Black" Margin="2,2,2,2" HorizontalAlignment="Center"> <TextBlock TextWrapping="WrapWithOverflow"

</TextBlock> </Border> </DockPanel> </Page>

b Figure 3-17 : Exemple dutilisation dun DockPanel

Le guide du codeur 75

Disposer les lments lcran

En revanche, si dans le code nous dplaons ce dernier cadre avant les cadres de gauche et de droite, elle occupe alors toute la largeur.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <DockPanel> <Border BorderThickness="1" BorderBrush="Black" DockPanel.Dock="Top" Margin="2,2,2,2" > <TextBlock TextWrapping="WrapWithOverflow" </TextBlock> </Border> <Border BorderThickness="1" BorderBrush="Black" DockPanel.Dock="Bottom" Margin="2,2,2,2" > <TextBlock TextWrapping="WrapWithOverflow" </TextBlock> </Border> <Border BorderThickness="1" BorderBrush="Black" DockPanel.Dock="Right" Margin="2,2,2,2" Width="200"> <TextBlock TextWrapping="WrapWithOverflow" </TextBlock> </Border> <Border BorderThickness="1" BorderBrush="Black" DockPanel.Dock="Left" Width="200" Margin="2,2,2,2" HorizontalAlignment="Left"> <TextBlock TextWrapping="WrapWithOverflow" </TextBlock> </Border> <Border BorderThickness="1" BorderBrush="Black" Margin="2,2,2,2" HorizontalAlignment="Center"> <TextBlock TextWrapping="WrapWithOverflow" </TextBlock> </Border> </DockPanel> </Page>

76 Le guide du codeur

Autoriser le dlement

b Figure 3-18 : Exemple dutilisation dun DockPanel

Suivant cette mme technique, vous pouvez ordonner les contrles pour obtenir la segmentation qui vous convient.

3.6 Autoriser le dlement


Comme vous laurez probablement dj remarqu, lorsque la fentre ne peut plus contenir lensemble des lments, les barres de dlement napparaissent pas sur les bords. Le ScrollViewer est l pour pallier ce problme.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <ScrollViewer ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto"> <StackPanel> <Border MinWidth="200" MinHeight="200" BorderBrush="Black" BorderThickness="1"> <TextBlock TextWrapping="Wrap" Margin="0,0,0,20"> Cet exemple dmontre lutilisation dun ScrollView. </TextBlock> </Border> </StackPanel> </ScrollViewer> </Page>
Le guide du codeur 77

Disposer les lments lcran

b Figure 3-19 : Exemple dutilisation dun ScrollViewer

Si nous rduisons la fentre, les barres de dlement apparaissent.

b Figure 3-20 : Barres de dlement en action

La balise ScrollViewer gre la fois la barre horizontale et verticale. Dans lexemple, les attributs ScrollViewer.HorizontalScrollBarVisibility et ScrollViewer.VerticalScrollBarVisibility sont initialiss Auto. Cela correspond lusage le plus frquent pour les barres de dlement. En mode automatique, les barres ne sont visibles que lorsquelles deviennent obligatoires. Les autres valeurs possibles sont Disabled, qui a pour effet de ne pas avoir de barre de dlement dans la direction correspondante ; Hidden, qui naffiche pas
78 Le guide du codeur

Autoriser le dlement

la barre de dlement, mais le contenu se comporte comme si celle-ci tait prsente, cest--dire quil ny aura pas de passage la ligne automatique ; la dernire valeur possible est Visible, qui fonctionne comme Auto la diffrence prs que la barre de dlement est visible mme si elle nest pas utile. Dans ce dernier cas, elle sera grise.
<ScrollViewer ScrollViewer.HorizontalScrollBarVisibility="Visible" ScrollViewer.VerticalScrollBarVisibility="Visible">

b Figure 3-21 : Barres de dlement grises

Valeur par dfaut Si vous ne spciez que la balise ScrollViewer, la barre horizontale sera cache et inactive (Hidden) alors que la barre verticale sera visible (Visible).

Lutilisation dun ScrollViewer ne se limite pas au bord de la fentre. Vous pouvez parfaitement en intgrer dautres dans linterface.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <ScrollViewer ScrollViewer.HorizontalScrollBarVisibility="Visible"

Le guide du codeur 79

Disposer les lments lcran

ScrollViewer.VerticalScrollBarVisibility="Hidden"> <StackPanel> <Border Width="200" Height="200" BorderBrush="Black" BorderThickness="1"> <ScrollViewer ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Visible"> <TextBox TextWrapping="Wrap" AcceptsReturn="True"> Cet exemple dmontre lutilisation dun ScrollView. </TextBox> </ScrollViewer> </Border> </StackPanel> </ScrollViewer> </Page>

b Figure 3-22 : ScrollViewer sur un contrle

Tapez du texte dans la bote de texte et vous verrez apparatre la barre de dlement.

80 Le guide du codeur

Mlanger les techniques de mise en page

3.7 Mlanger les techniques de mise en page


Toutes les mthodes que nous venons de voir permettent chacune de rsoudre certaines situations mais, bien souvent, vous vous trouvez en face dun problme o vous devriez, pour partie, utiliser telle mthode et pour partie telle autre mthode. En XAML, vous pouvez utiliser autant de mthodes de mise en page que vous voulez, et cela dans le mme cran. Bien sr, pour y arriver, il faut respecter quelques rgles. Le principe est simple. Il sagit ni plus ni moins que le principe de la poupe russe. Si une page ne peut contenir quun seul objet, disons un Grid, celui-ci peut contenir des contrles mais galement un autre conteneur comme un Canvas. Le Canvas peut son tour contenir un Grid ou un DockPanel, par exemple. Il ny a quasiment plus de limite pour raliser la mise en page de vos rves. Mais, attention, plus complexe sera votre cran, plus complexe sera votre structure et plus la ralisation sera ardue et longue ! De fait, il existe non pas une mthode pour raliser la mise en page mais une innit de mthodes avec chacune leurs avantages et leurs inconvnients. Lexemple qui suit est titre purement ducatif et aurait vraisemblablement pu tre rsolu diffremment. Toutefois, son objectif est purement didactique et, de ce point de vue, il remplit pleinement son rle. Nous allons au travers de cet exemple non seulement voir comment intgrer diffrents conteneurs mais galement en proter pour nouveau voir certaines fonctionnalits des contrles courants.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >

Nous commenons par dnir une barre de dlement horizontale et une verticale.
<ScrollViewer ScrollViewer.HorizontalScrollBarVisibility="Visible" ScrollViewer.VerticalScrollBarVisibility="Visible">

Le premier conteneur dni est un DockPanel. Il va nous permettre de dcouper la fentre en quatre zones. Une pour len-tte, une pour le bas de page et deux pour le corps de la fentre.
<DockPanel>
Le guide du codeur 81

Disposer les lments lcran

Tout dabord len-tte, qui contient un Canvas.


<Border BorderThickness="2" DockPanel.Dock="Top" BorderBrush="LightGreen"> <Canvas Background="DarkSeaGreen" MinHeight="40" > <Label FontSize="24" FontFamily="Engravers MT" Content="Ma bibliothque" /> </Canvas> </Border>

Ensuite le bas dcran, qui de faon quil occupe toute la largeur de la fentre doit tre dni ce moment. Il contient galement un Canvas dans lequel le contrle est positionn depuis le coin infrieur droit.
<Canvas DockPanel.Dock="Bottom" Background="Green" MinHeight="30"> <Label Name="lblCopyright" Content="Le concepteur 2006" Canvas.Bottom="3" Canvas.Right="10" VerticalAlignment="Bottom" HorizontalAlignment="Right"/> </Canvas>

La partie droite du corps contient un WrapPanel. Cette partie sera xe lors dun redimensionnement horizontal.
<Border DockPanel.Dock="Right" MinWidth="200" MaxWidth="400" BorderThickness="1" BorderBrush="Black" Background="LightGreen"> <WrapPanel> <Image Width="190" Margin="2,2,2,2"> <Image.Source> C:\Documents and Settings\All Users\ Documents\Mes images\ chantillons dimages\Hiver.jpg </Image.Source> </Image> <TextBox TextWrapping="Wrap" Width="195" Margin="2,2,2,2" AcceptsReturn="True" /> <TextBox TextWrapping="Wrap" Margin="2,2,2,2" AcceptsReturn="True" /> </WrapPanel> </Border>

Le dernier volet est coll sur le bord gauche et contient une grille. La grille sert alors positionner les diffrentes zones de saisie.

82 Le guide du codeur

Mlanger les techniques de mise en page

<Border DockPanel.Dock="Left" MinWidth="280" MinHeight="200" BorderThickness="1" BorderBrush="Black" Background="LightGreen"> <Grid>

La grille contient 2 colonnes et 6 lignes. La largeur de premire colonne est xe et plus troite que la seconde, tandis que la hauteur de la troisime ligne est xe un minimum de 40 points pour que la ComboBox reste suffisamment visible.
<Grid.ColumnDefinitions> <ColumnDefinition Width="80" /> <ColumnDefinition MinWidth="200"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> <RowDefinition MinHeight="40"/> <RowDefinition /> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <Label Name="lblLivre" Grid.Row="0" Grid.Column="0"> Livre </Label> <TextBox Name="txtLivre" Grid.Row="0" Grid.Column="1" MaxLength="30" Height="23" Text="TL" VerticalAlignment="Top" Margin="2,2,2,2"/> <Label Name="lblAuteur" Grid.Row="1" Grid.Column="0"> Auteur </Label> <TextBox Name="txtAuteur" Grid.Row="1" Grid.Column="1" MaxLength="30" CharacterCasing="Upper" Height="23" VerticalAlignment="Top" Margin="2,2,2,2"/> <Label Name="lblColl" Grid.Row="2" Grid.Column="0"> Collection </Label> <ComboBox Name="txtColl" Grid.Row="2" Grid.Column="1" IsEditable="True" VerticalAlignment="Top" Margin="2,2,2,2"> <ComboBoxItem> Fiction </ComboBoxItem> <ComboBoxItem>
Le guide du codeur 83

Disposer les lments lcran

Horreur </ComboBoxItem> <ComboBoxItem IsSelected="True"> Policier </ComboBoxItem> <ComboBoxItem> Historique </ComboBoxItem> <ComboBoxItem> Amour </ComboBoxItem> </ComboBox> <Label Name="lblISBN" Grid.Row="3" Grid.Column="0"> Numro ISBN </Label> <TextBox Name="txtISBN" Grid.Row="3" Grid.Column="1" MaxLength="15" Height="23" VerticalAlignment="Top" Margin="2,2,2,2"/> <Label Name="lblGenre" Grid.Row="4" Grid.Column="0"> Genre </Label> <TextBox Name="txtGenre" Grid.Row="4" Grid.Column="1" MaxLength="50" Height="23" VerticalAlignment="Top" Margin="2,2,2,2"/> <Grid Grid.Row="5" Grid.Column="0" Grid.ColumnSpan="2"> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <Button Grid.Row="0" Grid.Column="0" Content="Prcdent" Width="80" Height="30" /> <Button Grid.Row="0" Grid.Column="1" Content="Suivant" Width="80" Height="30" /> </Grid> </Grid> </Border> </DockPanel> </ScrollViewer> </Page>

84 Le guide du codeur

Mlanger les techniques de mise en page

m Figure 3-23 : Mise en page mixte

Erreur dans le code Le contenu de la balise image est volontairement scind en 3 lignes pour une question de lisibilit de lexemple. Toutefois, si vous dsirez le reproduire, il sera ncessaire de regrouper le nom du chier sur une mme ligne.

Analysons cet exemple. La mise en page se fait au moyen dun DockPanel inclus dans un ScrollViewer. Ce DockPanel est compos de 4 zones. La premire zone est le titre "Ma bibliothque". Il sinscrit naturellement en haut dcran. Nous utilisons donc lattribut Top pour le docking. Un cadre vert clair entoure la zone de titre. Ce cadre est ralis avec la balise Border.
<Border BorderThickness="2" DockPanel.Dock="Top" BorderBrush="LightGreen"> <Canvas Background="DarkSeaGreen" MinHeight="40" > <Label FontSize="24" FontFamily="Engravers MT" Content="Ma bibliothque" /> </Canvas> </Border>

Comme vous le voyez, cest le nud Border qui est le parent de ce groupe. Cest donc lui qui doit tre positionn par rapport notre DockPanel. Les autres
Le guide du codeur 85

Disposer les lments lcran

lments suivent invitablement le mouvement. Le contrle Border inclut un Canvas, ce qui va nous permettre de positionner notre titre sur la base de coordonnes. Grce lutilisation du Canvas, nous pourrions avoir dautres contrles dans la barre de titre Pour obtenir la couleur du fond de notre barre de titre, il nous a suffi dutiliser lattribut Background du Canvas. Pour viter un crasement exagr, la hauteur minimale du Canvas est xe 40. Pour obtenir le bas dcran, nous faisons de mme mais cette fois sans utiliser de bord. Cest donc directement le Canvas qui reoit lattribut DockPanel.Dock="Bottom".
<Canvas DockPanel.Dock="Bottom" Background="Green" MinHeight="30"> <Label Name="lblCopyright" Content="Le concepteur 2006" Canvas.Bottom="3" Canvas.Right="10" VerticalAlignment="Bottom" HorizontalAlignment="Right"/> </Canvas>

An quils prennent toute la largeur de la fentre, nous commenons par dnir len-tte et le bas de page. Les autres zones de notre DockPanel sont dnies aprs. La troisime zone dnie est la zone de droite.
<Border DockPanel.Dock="Right" MinWidth="200" MaxWidth="400" BorderThickness="1" BorderBrush="Black" Background="LightGreen"> <WrapPanel> <Image Width="190" Margin="2,2,2,2"> <Image.Source> C:\Documents and Settings\All Users\ Documents\Mes images\ chantillons dimages\Hiver.jpg </Image.Source> </Image> <TextBox TextWrapping="Wrap" Width="195" Margin="2,2,2,2" AcceptsReturn="True" /> <TextBox TextWrapping="Wrap" Margin="2,2,2,2" AcceptsReturn="True" /> </WrapPanel> </Border>

Dans cette zone, les contrles sont positionns au moyen dun WrapPanel.

86 Le guide du codeur

Mlanger les techniques de mise en page

Il est galement inclus dans un Border, simplement an dobtenir un n cadre noir autour. La dernire zone, celle de gauche, est ralise grce un Grid dans lequel les diffrents contrles sont positionns dans les cellules formes par la grille. Le Grid est lui-mme inclus dans un Border pour dnir un n cadre noir. Le fond est galement dni dans la balise Border, mais nous aurions tout aussi bien pu le dnir dans la balise Grid.
<Border DockPanel.Dock="Left" MinWidth="280" MinHeight="200" BorderThickness="1" BorderBrush="Black" Background="LightGreen"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="80" /> <ColumnDefinition MinWidth="200"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> <RowDefinition MinHeight="40"/> <RowDefinition /> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> </Grid> </Border>

Si nous examinons le contenu de plus prs, nous remarquons la prsence dun Grid lintrieur de notre Grid.
<Grid Grid.Row="5" Grid.Column="0" Grid.ColumnSpan="2"> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <Button Grid.Row="0" Grid.Column="0" Content="Prcdent" Width="80" Height="30" /> <Button Grid.Row="0" Grid.Column="1 Content="Suivant" Width="80" Height="30" /> </Grid>

Pourquoi ce Grid ? Tout simplement parce que les boutons doivent tre centrs dans la grille et que les colonnes dnies dans notre premier Grid sont de largeur diffrente. Ce nouveau Grid inclut, grce lattribut Grid.ColumnSpan,
Le guide du codeur 87

Disposer les lments lcran

les deux colonnes. Dans ce nouveau Grid, qui occupe en dnitive toute la ligne, deux colonnes, cette fois de largeur identique, sont rednies.

Effet du redimensionnement La rgle du DockPanel, qui dtermine que le dernier lment occupe lespace restant, aura pour consquence lorsque vous redimensionnez la fentre que seule la zone de gauche va sadapter dans les deux sens. La taille des autres parties reste xe dans une direction.

Cet exemple dmontre quel point il est possible dintgrer les diffrents composants les uns dans les autres mais galement que chaque choix, et ce y compris lordre de chaque balise, va avoir un impact sur le rsultat nal. Comme les zones sont dnies volontairement dans un ordre bien dtermin, les contrles qui y sont inclus vont galement tre ordonns en fonction. Cet tat de fait peut ventuellement tre prjudiciable la qualit de votre interface graphique. En effet, lordre dapparition des contrles va galement rgir le dplacement du curseur avec la touche [Tab]. La solution ce problme est simple et dj connue de ceux qui ont lhabitude du dveloppement traditionnel. XAML met notre disposition lattribut TabIndex, qui va simplement rednir lordre de parcours avec la touche [Tab].

3.8 Crer une page composite


Une page ou une fentre peut tre compose de diffrentes pages. Pour cela, vous disposez de la balise Frame, qui va vous permettre dintgrer dans votre fentre ou votre page le contenu dautres pages. Prenons un exemple simple.
<Window x:Class="Window1" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Frame" > <StackPanel> <Label> Une page avec 2 frames. </Label> <WrapPanel> <Frame Source="Page1.xaml" BorderBrush="Black" BorderThickness="1" Width="200" Height="100"/>

88 Le guide du codeur

Crer une page composite

<Frame Source="Page2.xaml" BorderBrush="Black" BorderThickness="1" Width="200" Height="100"/> </WrapPanel> </StackPanel> </Window> Page1.xaml contient : <Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <StackPanel> <Label> Frame 1 </Label> </StackPanel> </Page> Page2.xaml contient : <Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <StackPanel> <Label> Frame 2 </Label> </StackPanel> </Page>

b Figure 3-24 : Utilisation de frames

Le guide du codeur 89

Disposer les lments lcran

Contenu dun frame Si vous pouvez utiliser des frames aussi bien au sein dune balise Window que dune balise Page, la page rfrence par la balise Frame ne pourra en aucun cas tre une page utilisant la balise Window.

3.9 Checklist
Dans ce chapitre, nous avons essentiellement vu comment disposer les lments lcran et principalement :
j j j

j j j j

le positionnement par utilisation des coordonnes en utilisant Canvas ; le positionnement en utilisant une grille avec la classe Grid ; le positionnement en utilisant les panneaux de type StackPanel, WrapPanel et DockPanel ; le mlange de ces diffrentes mthodes ; autoriser le dlement avec ScrollViewer ; raliser des pages composes de plusieurs pages avec Frame ; comprendre et utiliser les attributs attachs.

90 Le guide du codeur

Ch apit re

4 Les autres contrles de base


Crer une liste droulante ............................. 92 Crer une ComboBox ................................... 98 Crer une case cocher ............................. 100 Utiliser les boutons radio ............................ 102 Placer des info-bulles .................................. 106 Utiliser les panneaux onglets .................... 109 Crer un bouton automatique ...................... 112 Utiliser un Slider ........................................ 114 Utiliser un Expander ................................... 118 Utiliser une ViewBox .................................. 121 Utiliser un Popup ....................................... 123 Ajouter de la vido dans la fentre ............... 126 Checklist .................................................. 129

Les autres contrles de base

4.1 Crer une liste droulante


Pour faire un choix parmi une liste, vous pouvez utiliser ce contrle. Toutefois, la liste ne doit pas tre trop longue sinon le choix devient vite fastidieux. Pour raliser une liste de choix, vous devez utiliser une balise ListBox. lintrieur du nud ainsi dni, vous devrez pour chaque lment de la liste ajouter un nud enfant utilisant la balise ListBoxItem.
<ListBox Name="lstLangue" MaxWidth="80"> <ListBoxItem>Franais</ListBoxItem> <ListBoxItem>Anglais</ListBoxItem> <ListBoxItem>Allemand</ListBoxItem> <ListBoxItem>Italien</ListBoxItem> <ListBoxItem>Espagnol</ListBoxItem> </ListBox>

b Figure 4-1 : Une simple liste de choix

Outre les attributs que nous avons dj voqus comme MaxWidth, repris dans lexemple, deux attributs sont particulirement intressants pour ce contrle. Il sagit tout dabord de SelectedIndex, qui permet de dnir une valeur par dfaut.
<ListBox Name="lstLangue" SelectedIndex="3" MaxWidth="80"> <ListBoxItem>Franais</ListBoxItem> <ListBoxItem>Anglais</ListBoxItem> <ListBoxItem>Allemand</ListBoxItem> <ListBoxItem>Italien</ListBoxItem> <ListBoxItem>Espagnol</ListBoxItem> </ListBox>

92 Le guide du codeur

Crer une liste droulante

b Figure 4-2 : La prslection dans une liste de choix

Comme vous pouvez le constater en comparant le rsultat avec lcran ci-dessous, la prslection ne saffiche pas de la mme manire quun lment slectionn par lutilisateur.

b Figure 4-3 : Un lment slectionn dans une liste de choix

Particularit de la numrotation Les diffrentes lignes de la liste de choix sont numrotes non pas de 1 n mais bien de 0 n-1 ; n tant le nombre dlments de la liste. Pour slectionner le premier, vous devez donc mettre comme valeur 0. Dans lexemple, la valeur slectionne est bien la quatrime, SelectedIndex vaut 3.

Le guide du codeur 93

Les autres contrles de base

Il existe une autre faon pour indiquer quel lment doit tre prslectionn. Cette mthode a lavantage dtre beaucoup plus visuelle car il sagit de modier dans la balise de llment voulu lattribut IsSelected. Le rsultat obtenu est le mme quavec lattribut SelectedIndex.
<ListBox Name="lstLangue" MaxWidth="80"> <ListBoxItem>Franais</ListBoxItem> <ListBoxItem>Anglais</ListBoxItem> <ListBoxItem>Allemand</ListBoxItem> <ListBoxItem IsSelected="true">Italien</ListBoxItem> <ListBoxItem>Espagnol</ListBoxItem> </ListBox>

Le second attribut intressant est lattribut SelectionMode, qui permet dautoriser ou dinterdire la slection de plusieurs valeurs. Si vous optez pour plusieurs valeurs, il existe deux modes possibles, en assignant soit la valeur Multiple, ce qui permet de slectionner ou de dslectionner plusieurs valeurs en cliquant simplement avec la souris, soit la valeur Extend, ce qui permet dutiliser les touches [Ctrl] et [Maj] pour raliser votre slection. La touche [Ctrl] permet dajouter votre slection llment sur lequel vous cliquez sans dslectionner les lments dj choisis. La touche [Maj] permet quant elle de slectionner tous les lments repris entre le dernier lment slectionn et llment sur lequel vous cliquez.
<ListBox Name="lstLangue" SelectionMode="Multiple" MaxWidth="80"> <ListBoxItem>Franais</ListBoxItem> <ListBoxItem>Anglais</ListBoxItem> <ListBoxItem>Allemand</ListBoxItem> <ListBoxItem>Italien</ListBoxItem> <ListBoxItem>Espagnol</ListBoxItem> </ListBox>

b Figure 4-4 : Une liste de choix slection multiple

94 Le guide du codeur

Crer une liste droulante

Si vous dsirez raliser une prslection de plusieurs valeurs, il suffit de modier lattribut IsSelected de chaque lment prslectionner.
<ListBox Name="lstLangue" MaxWidth="80" SelectionMode="Multiple"> <ListBoxItem>Franais</ListBoxItem> <ListBoxItem IsSelected="true">Anglais</ListBoxItem> <ListBoxItem>Allemand</ListBoxItem> <ListBoxItem IsSelected="true">Italien</ListBoxItem> <ListBoxItem>Espagnol</ListBoxItem> </ListBox>

Prslectionner un lment avec SelectedValue Au lieu dutiliser SelectedIndex, vous pourriez utiliser lattribut SelectedValue. Toutefois, dans le code XAML, cela me semble peu opportun et plus compliqu. Il nen va pas ncessairement de mme si vous initialisez la valeur depuis le code .NET.

Si vous dsirez rendre une liste inaccessible lutilisateur, vous devrez utiliser lattribut IsEnabled. Ce contrle ne supporte pas lattribut IsReadOnly.
<ListBox Name="lstLangue" IsEnabled="False" MaxWidth="80"> <ListBoxItem>Franais</ListBoxItem> <ListBoxItem>Anglais</ListBoxItem> <ListBoxItem>Allemand</ListBoxItem> <ListBoxItem IsSelected="true">Italien</ListBoxItem> <ListBoxItem>Espagnol</ListBoxItem> </ListBox>

b Figure 4-5 : Liste de choix dsactive

Le guide du codeur 95

Les autres contrles de base

Problme de lisibilit Cette faon de procder ne convient pas bien car, comme vous pouvez le constater, bien quune valeur soit prslectionne, elle nest pas visible. Pour rsoudre ce problme, assignez la valeur Blue lattribut Background de la balise ListBoxItem correspondante.

<ListBox Name="lstLangue" MaxWidth="80"> <ListBoxItem>Franais</ListBoxItem> <ListBoxItem>Anglais</ListBoxItem> <ListBoxItem>Allemand</ListBoxItem> <ListBoxItem Background="Blue" IsSelected="true"> Italien </ListBoxItem> <ListBoxItem>Espagnol</ListBoxItem> </ListBox>

b Figure 4-6 : Liste de choix dsactive modie

Limite de cette modication Cette solution nest envisageable que si le contrle reste toujours ltat inactif. Dans le cas contraire, llment modi avec Background apparatra toujours comme slectionn.

96 Le guide du codeur

Crer une liste droulante

Si vous souhaitez que le contrle soit actif mais que certaines valeurs soient dsactives, il suffit de placer lattribut IsEnabled dans ltat False pour chacun des lments.
<ListBox Name="lstLangue" MaxWidth="80"> <ListBoxItem>Franais</ListBoxItem> <ListBoxItem>Anglais</ListBoxItem> <ListBoxItem>Allemand</ListBoxItem> <ListBoxItem IsEnabled="False">Italien</ListBoxItem> <ListBoxItem IsEnabled="False">Espagnol</ListBoxItem> </ListBox>

b Figure 4-7 : Une liste de choix dont certains lments sont dsactivs

Si la hauteur de la liste nest pas suffisante, une barre de dlement sera automatiquement ajoute.
<ListBox Name="lstLangue" MaxWidth="80" MaxHeight="45"> <ListBoxItem>Franais</ListBoxItem> <ListBoxItem>Anglais</ListBoxItem> <ListBoxItem>Allemand</ListBoxItem> <ListBoxItem IsEnabled="False">Italien</ListBoxItem> <ListBoxItem IsEnabled="False">Espagnol</ListBoxItem> </ListBox>

Le guide du codeur 97

Les autres contrles de base

b Figure 4-8 : Une liste avec sa barre de dlement

4.2 Crer une ComboBox


Trs proche de la liste de choix (ListBox), la ComboBox a toutefois gnralement ma prfrence. Elle occupe moins de place lcran et permet de rechercher un lment en tapant le dbut de la valeur. Elle offre galement la possibilit dintroduire une valeur diffrente de celles proposes dans la liste mais uniquement si vous dsirez offrir cette possibilit. Pour crer une ComboBox, vous devrez utiliser la balise du mme nom. lintrieur du nud ainsi cr, vous devrez pour chaque lment crer un nud enfant en utilisant la balise ComboBoxItem.
<ComboBox Name="cboPays" MaxWidth="80" SelectedIndex="4"> <ComboBoxItem>France</ComboBoxItem> <ComboBoxItem>Belgique</ComboBoxItem> <ComboBoxItem>Allemagne</ComboBoxItem> <ComboBoxItem>Suisse</ComboBoxItem> <ComboBoxItem>Italie</ComboBoxItem> <ComboBoxItem>Espagne</ComboBoxItem> </ComboBox>

b Figure 4-9 : Une simple ComboBox

98 Le guide du codeur

Crer une ComboBox

Comme pour le contrle ListBox, lattribut SelectedIndex permet de


Renvoi slectionner une valeur par dfaut. Voir page 92.

Lattribut IsEditable permet de dnir si oui ou non vous pouvez encoder une valeur diffrente dune des valeurs de la liste.
<ComboBox Name="cboPays" SelectedIndex="4" IsEditable="True" Height="20" Margin="2,2,2,2"> <ComboBoxItem>France</ComboBoxItem> <ComboBoxItem>Belgique</ComboBoxItem> <ComboBoxItem>Allemagne</ComboBoxItem> <ComboBoxItem>Suisse</ComboBoxItem> <ComboBoxItem>Italie</ComboBoxItem> <ComboBoxItem>Espagne</ComboBoxItem> </ComboBox>

b Figure 4-10 : Une ComboBox ditable

Le fait que ce contrle soit ditable a pour consquence quil possde la fois des attributs de ListBox et de TextBox. Cest pourquoi vous pouvez par exemple assigner lattribut Text, qui aura pour effet de placer cette valeur dans la zone de saisie.
Lattribut IsReadOnly Lattribut IsReadOnly provoque un comportement inattendu. En effet, le fait de placer le contrle en lecture seule au moyen de cet attribut nempche pas lutilisateur de choisir dans la liste et ainsi de changer la valeur. Cet attribut naffecte que la zone de saisie du texte. Si vous dsirez que la valeur ne puisse tre change, il est ncessaire dassigner la valeur False lattribut IsEnabled.

Le guide du codeur 99

Les autres contrles de base

Si pour une raison particulire vous dsirez retirer la possibilit de rechercher dans la liste en tapant successivement les lettres du dbut du mot recherch, lattribut IsTextSearchEnabled doit tre mis False.
<ComboBox Name="cboPays" SelectedIndex="4" IsTextSearchEnabled="False" Height="20" Margin="2,2,2,2"> <ComboBoxItem>France</ComboBoxItem> <ComboBoxItem>Belgique</ComboBoxItem> <ComboBoxItem>Allemagne</ComboBoxItem> <ComboBoxItem>Suisse</ComboBoxItem> <ComboBoxItem>Italie</ComboBoxItem> <ComboBoxItem>Espagne</ComboBoxItem> </ComboBox>

Toutefois, il est prfrable de ne pas changer cette option.

4.3 Crer une case cocher


La case cocher fait partie de la panoplie des contrles indispensables pour raliser une interface graphique de qualit. Comme tous les contrles vus prcdemment, il sutilise trs facilement. Il suffit dutiliser la balise CheckBox.
<CheckBox Name="chkDispo" Margin="5,5,2,2" IsChecked="True"> Disponible en semaine </CheckBox>

b Figure 4-11 : Une case cocher

100 Le guide du codeur

Crer une case cocher

Lattribut IsChecked reoit une valeur boolenne qui indique si par dfaut la case est coche ou non. Si vous ne souhaitez pas que la case soit coche par dfaut, vous pouvez bien sr omettre tout simplement cet attribut. Parfois, vous aurez besoin dune case cocher autorisant ltat indtermin. Cest lattribut IsThreeState qui va autoriser ce comportement.
<CheckBox Name="chkDispo" Margin="5,5,2,2" IsThreeState="True" > Disponible en semaine </CheckBox>

b Figure 4-12 : Une case cocher dans ltat indtermin

Si vous souhaitez utiliser ce contrle uniquement pour afficher une information mais que vous ne souhaitiez pas que lutilisateur puisse modier ltat de la case cocher, vous devez ici encore utiliser obligatoirement lattribut IsEnabled.
<CheckBox Name="chkDispo" Margin="5,5,2,2" IsEnabled="False" IsChecked="True" Content="Disponible en semaine" />

Le guide du codeur 101

Les autres contrles de base

b Figure 4-13 : Une case cocher dsactive

Lattribut Content Dans ce dernier exemple, le texte est assign lattribut Content au lieu de le placer dans le nud. Le rsultat est identique, cest une question de got personnel.

4.4 Utiliser les boutons radio


Le contrle RadioButton est un autre moyen de faire un choix dans une liste. La syntaxe pour ajouter un bouton radio est fort simple.
<RadioButton Name="rbUse" IsChecked="True"> Jutilise XAML </RadioButton>

Comme pour la case cocher, nous retrouvons lattribut IsChecked. la diffrence de la case cocher, les boutons radio sont associs les uns aux autres. Ce qui fait que, quand vous slectionnez un bouton radio, les autres sont automatiquement dslectionns.
<RadioButton Name="rbUseVB" IsChecked="True"> Jutilise VB.NET </RadioButton> <RadioButton Name="rbUseCSharp">
102 Le guide du codeur

Utiliser les boutons radio

Jutilise C# </RadioButton> <RadioButton Name="rbUsedelphi"> Jutilise Delphi.NET </RadioButton>

b Figure 4-14 : Utiliser des boutons radio

Si vous dsirez avoir dans un mme cran plusieurs listes de boutons radio indpendantes les unes des autres, vous devez les intgrer dans un ensemble. Dans les versions prcdentes, nous aurions d utiliser une RadioButtonList mais elle nest actuellement plus disponible en XAML. Pour regrouper des boutons radio dans des ensembles diffrents, le moyen le plus simple est de leur ajouter un attribut GroupName. Assignez la mme valeur cet attribut pour tous les boutons radio devant tre associs.
<RadioButton Name="rbUseVB" IsChecked="True" GroupName="grpLanguage"> Jutilise VB.NET </RadioButton> <RadioButton Name="rbUseCSharp" GroupName="grpLanguage"> Jutilise C# </RadioButton> <RadioButton Name="rbUsedelphi" GroupName="grpLanguage"> Jutilise Delphi.NET </RadioButton> <RadioButton Name="rbUse10" GroupName="grpFramework"> Jutilise le Framework 1.0 </RadioButton> <RadioButton Name="rbUse11" IsChecked="True"

Le guide du codeur 103

Les autres contrles de base

GroupName="grpFramework"> Jutilise le Framework 1.1 </RadioButton> <RadioButton Name="rbUse20" GroupName="grpFramework"> Jutilise le Framework 2.0 </RadioButton>

b Figure 4-15 : Utiliser des boutons radio

Une autre solution consiste utiliser un contrle conteneur spar pour chaque liste de boutons radio. Dans lexemple ci-dessous, nous utiliserons deux StackPanel supplmentaires. Cest pourquoi, pour cet exemple, le code complet vous est nouveau prsent.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <StackPanel> <StackPanel> <RadioButton Name="rbUseVB" IsChecked="True"> Jutilise VB.NET </RadioButton> <RadioButton Name="rbUseCSharp"> Jutilise C# </RadioButton> <RadioButton Name="rbUsedelphi"> Jutilise Delphi.NET </RadioButton> </StackPanel> <StackPanel>

104 Le guide du codeur

Utiliser les boutons radio

<RadioButton Name="rbUse10"> Jutilise le Framework 1.0 </RadioButton> <RadioButton Name="rbUse11" IsChecked="True"> Jutilise le Framework 1.1 </RadioButton> <RadioButton Name="rbUse20"> Jutilise le Framework 2.0 </RadioButton> </StackPanel> </StackPanel> </Page>

Le rsultat est identique la mthode prcdente. Toutefois, lutilisation dune mthode ou dune autre peut inuencer la mise en page.

Liste de choix non modiable Pour rendre une liste de choix non modiable, vous devez utiliser lattribut IsEnabled. Celui-ci doit tre appliqu sur chaque bouton radio. Toutefois, si elle est incluse dans un conteneur qui lui est spcique, vous pouvez spcier lattribut IsEnabled dans le conteneur. Cette faon de faire est bien plus pratique bien des gards.

Normalement, il devrait tre possible dutiliser un contrle de type GroupBox au lieu dun Canvas. Toutefois, dans la version bta utilise au moment dcrire ces lignes, cette possibilit ntait pas supporte. Le contrle GroupBox existe bel et bien mais ne supporte quun enfant et ne permet ds lors pas de regrouper les boutons radio. Son utilisation se limite laffichage du traditionnel contour. Son utilit reste malgr tout vidente pour rendre votre interface claire et bien comprhensible pour lutilisateur.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <StackPanel> <GroupBox BorderThickness="1" BorderBrush="Black" Header="Language" Width="150"> <StackPanel> <RadioButton Name="rbUseVB" IsChecked="True"> Jutilise VB.NET </RadioButton> <RadioButton Name="rbUseCSharp"> Jutilise C# </RadioButton>
Le guide du codeur 105

Les autres contrles de base

<RadioButton Name="rbUsedelphi"> Jutilise Delphi.NET </RadioButton> </StackPanel> </GroupBox> <GroupBox BorderThickness="1" BorderBrush="Black" Header="Framework" Width="150"> <StackPanel> <RadioButton Name="rbUse10"> Jutilise le Framework 1.0 </RadioButton> <RadioButton Name="rbUse11" IsChecked="True"> Jutilise le Framework 1.1 </RadioButton> <RadioButton Name="rbUse20"> Jutilise le Framework 2.0 </RadioButton> </StackPanel> </GroupBox> </StackPanel> </Page>

b Figure 4-16 : Utilisation dun GroupBox

Notez au passage lutilisation de lattribut Header pour indiquer le titre de votre GroupBox.

4.5 Placer des info-bulles


Bien que, contrairement aux contrles vus prcdemment, la bulle dinformation ne puisse exister sans un autre contrle, une place privilgie a t rserve cette fonctionnalit car les bulles dinformation sont souvent trop peu utilises
106 Le guide du codeur

Placer des info-bulles

en dehors des programmes commerciaux. Pourtant, elles apportent un rel plus votre dveloppement et, surtout, elles vitent pas mal dincomprhension et de confusion pour lutilisateur de votre interface. Pour des questions de place lcran, les tiquettes prcdant les diffrents champs de saisie ou de choix sont gnralement fortement rsumes et trs peu explicites. Les bulles dinformation sont l pour pallier ce manque et constituent le premier niveau daide. Pour raliser une telle bulle, vous devez utiliser lattribut ToolTip du contrle auquel la bulle dinformation doit tre associe. titre dexemple, nous allons associer une bulle dinformation une bote de saisie de texte.
<TextBox Name="txtNom" Margin="3,3,3,3" ToolTip="Dans ce champ vous devez introduire le nom de famille de votre contact." />

b Figure 4-17 : Une info-bulle

Cette faon de faire est toutefois limite la prsentation sur une seule ligne. Pour amliorer notre info-bulle, nous devons utiliser une syntaxe lgrement plus complique en la dnissant comme un nud ls.
<TextBox Name="txtNom" Margin="3,3,3,3"> <TextBox.ToolTip> <TextBlock MaxWidth="200" TextWrapping="WrapWithOverflow" > Dans ce champ vous devez introduire le nom de famille de votre contact. </TextBlock> </TextBox.ToolTip> </TextBox>

Le guide du codeur 107

Les autres contrles de base

De cette faon, le texte dinformation est alors inclus dans un bloc de texte, ce qui permet dajuster les attributs daffichage pour obtenir le rsultat souhait. Dans lexemple, la taille de la bulle est limite 150 pixels et le texte passe automatiquement la ligne en tendant la zone autant que ncessaire.

b Figure 4-18 : Une info-bulle sur plusieurs lignes

Outre le passage la ligne, cette faon daborder le problme offre galement la possibilit denrichir la prsentation du contenu.
<TextBox Name="txtNom" Margin="3,3,3,3"> <TextBox.ToolTip> <TextBlock MaxWidth="200" TextWrapping="WrapWithOverflow" > <Image Width="16" Height="16"> <Image.Source> C:\Windows\Microsoft.NET\Windows\ v6.0.5070\Avalon\avalonArp.ico </Image.Source> </Image> Dans ce champ vous devez introduire le <Bold>nom</Bold> de <Underline>famille </Underline> de votre contact. </TextBlock> </TextBox.ToolTip> </TextBox>

108 Le guide du codeur

Utiliser les panneaux onglets

b Figure 4-19 : Gras et italique dans une info-bulle

4.6 Utiliser les panneaux onglets


Une dernire faon de raliser une mise en page est dutiliser un panneau onglets.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <TabControl MinWidth="300" MinHeight="300"> <TabItem Header="Photo1"> <Image Source="C:\Documents and Settings\ All Users\Documents\Mes images\ chantillons dimages\Collines.jpg" /> </TabItem> <TabItem Header="Photo2"> <Image Source="C:\Documents and Settings\ All Users\Documents\Mes images\ chantillons dimages\ Coucher de soleil.jpg" /> </TabItem> <TabItem Header="Photo3"> <Image Source="C:\Documents and Settings\ All Users\Documents\Mes images\ chantillons dimages\Hiver.jpg" /> </TabItem> <TabItem Header="Photo4"> <Image Source="C:\Documents and Settings\ All Users\Documents\Mes images\

Le guide du codeur 109

Les autres contrles de base

</TabItem> </TabControl> </Page>

chantillons dimages\Nnuphars.jpg" />

b Figure 4-20 : Utilisation des onglets

Bien quil reprsente une surface, le TabControl est plus proche des contrles de type TextBox que du Canvas, par exemple. En effet, chaque nud TabItem ne peut avoir quun seul enfant. Pour pallier ce problme, la solution est trs simple et revient
Renvoi appliquer les rgles qui sont vues dans le chapitre Mlanger les

techniques de mise en page (voir page 81).

Ajoutez ce TabItem notre code prcdent.


<TabItem Header="Miniatures" IsSelected="True"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions>
110 Le guide du codeur

Utiliser les panneaux onglets

<Image Grid.Column="0" Grid.Row="0" Source="C:\Documents and Settings\All Users\ Documents\Mes images\chantillons dimages\ Collines.jpg" /> <Image Grid.Column="0" Grid.Row="1" Source="C:\Documents and Settings\All Users\ Documents\Mes images\chantillons dimages\ Coucher de soleil.jpg" /> <Image Grid.Column="1" Grid.Row="0" Source="C:\Documents and Settings\All Users\ Documents\Mes images\chantillons dimages\ Hiver.jpg" /> <Image Grid.Column="1" Grid.Row="1" Source="C:\Documents and Settings\All Users\ Documents\Mes images\chantillons dimages\ Nnuphars.jpg" /> </Grid> </TabItem>

b Figure 4-21 : Utilisation des onglets

Utilisation de IsSelected Remarquez au passage lutilisation de IsSelected pour spcier un onglet par dfaut diffrent du premier.

Le guide du codeur 111

Les autres contrles de base

4.7 Crer un bouton automatique


Nous avons dj vu le bouton classique prcdemment mais, dans certaines circonstances, son utilisation peut se rvler peu pratique. Prenons un exemple : si vous dsirez utiliser un bouton pour faire dler des donnes dans un cran, avec un bouton traditionnel vous devrez cliquer de manire rpte. Pour viter cela, vous disposez dun bouton particulier appel RepeatButton qui va rpter automatiquement le clic tant que vous maintiendrez la pression sur le bouton.
<RepeatButton Name="btnSuivant" Width="80" Height="30"> Suivant </RepeatButton>

Pour obtenir un contrle efficace du comportement de ce bouton rptition, nous disposons tout dabord de lattribut Interval, qui dtermine le temps entre deux appels de laction associe au bouton.
<RepeatButton Name="btnSuivant" Width="80" Height="30" Interval="100"> Suivant </RepeatButton>

Dans lexemple, lopration Suivant sera effectue tous les diximes de seconde. Pour viter que la rptition ne dmarre directement, vous pouvez imposer un dlai. Si la pression sur le bouton est infrieure au dlai, il se comportera comme un bouton normal. En revanche, si la pression se prolonge au-del du dlai x, la rptition de tche va pouvoir dmarrer. Pour contrler ce dlai, vous disposez de lattribut Delay.
<RepeatButton Name="btnSuivant" Delay="500" Interval="100"> Suivant </RepeatButton>

Dans cet exemple, le dlai est x une demi-seconde (500 millimes).

112 Le guide du codeur

Crer un bouton automatique

b Figure 4-22 : Le bouton rptition

Dure du traitement La dure du traitement raliser chaque rptition ne peut excder lintervalle prvu entre chaque rptition. Dans le cas contraire, le traitement pourrait se poursuivre encore un certain temps aprs que lutilisateur eut relch le bouton.

Comme vous pouvez le constater, visuellement, il ny a aucune diffrence entre les deux types de boutons. Si vous dsirez visuellement identier ce type de bouton, vous pouvez adapter pour lui votre charte graphique en changeant par exemple la couleur du fond. Pour rappel, vous disposez pour cela de lattribut Background. Vous pouvez galement jouer sur leffet visuel li la forme du curseur de la souris.
<RepeatButton Name="btnSuivant" Delay="500" Interval="100" Cursor="Hand"> Suivant </RepeatButton>

Dans lexemple ci-dessus, le curseur de la souris est transform en une main lors du passage sur le bouton.

Le guide du codeur 113

Les autres contrles de base

4.8 Utiliser un Slider


Le Slider offre un moyen trs visuel pour introduire une valeur numrique. Il est souvent utilis lorsque la valeur a une action directe sur linterface utilisateur, comme un zoom. Ce contrle dispose en plus des attributs courants, dun nombre important dattributs permettant de lui donner le comportement voulu. Commenons par un Slider simple permettant de dnir une valeur entre 0 et 100.
<Slider Width="200" VerticalAlignment=Center Minimum="0" Maximum="100" Value="50"/>

b Figure 4-23 : Utilisation dun Slider

Gnralement, ce genre de contrle dispose de repres visuels. Il existe deux possibilits pour les ajouter, en utilisant soit lattribut TickFrequency, qui vous permet de dnir lcart entre chaque repre :
<Slider Width="200" VerticalAlignment="Center" Minimum="0" Maximum="100" Value="50" TickFrequency="10" TickPlacement="BottomRight"/>

soit lattribut Ticks :


<Slider Width="200" VerticalAlignment="Center" Minimum="0" Maximum="100" Value="50" Ticks="10,20,30,40,50,60,70,80,90" TickPlacement="BottomRight"/>

114 Le guide du codeur

Utiliser un Slider

Ce dernier est plus contraignant mais permet davoir des repres qui sont irrguliers. En plus des repres visuels, vous pouvez ajouter automatiquement la valeur dans un ToolTip.
<Slider Width="200" VerticalAlignment="Center" Minimum="0" Maximum="100" Value="50" Ticks="10,20,30,40,50,60,70,80,90" TickPlacement="BottomRight" AutoToolTipPlacement="TopLeft" AutoToolTipPrecision="0" />

b Figure 4-24 : Un Slider avec repres visuels

Limiter les valeurs aux repres Avec lattribut IsSnapToTickEnabled, les valeurs sont automatiquement arrondies au repre le plus proche.

Il est galement possible de modier la valeur sans dplacer le curseur mais en cliquant sur la barre. LargeChange permet de dnir la valeur qui sera ajoute ou retire automatiquement chaque clic. Les attributs Delay et Interval permettent de moduler automatiquement la rptition de laction.

Le guide du codeur 115

Les autres contrles de base

<Slider Width="200" VerticalAlignment="Center" Minimum="0" Maximum="100" Value="50" Ticks="10,20,30,40,50,60,70,80,90" TickPlacement="BottomRight" AutoToolTipPlacement="TopLeft" AutoToolTipPrecision="0" LargeChange="10" Delay="500" Interval="200" />

Vous pouvez galement dnir une zone visuelle o devrait se trouver la valeur. Cette zone est un attribut purement visuel mais ne limite en rien les valeurs possibles.
<Slider Width="200" VerticalAlignment="Center" Minimum="0" Maximum="100" Value="50" Ticks="10,20,30,40,50,60,70,80,90" TickPlacement="BottomRight" AutoToolTipPlacement="TopLeft" AutoToolTipPrecision="0" LargeChange="10" Delay="500" Interval="200" IsSelectionRangeEnabled="True" SelectionStart="20" SelectionEnd="80" />

b Figure 4-25 : Un Slider avec une zone

Si vous prfrez un Slider vertical, aucun problme, la proprit Orientation vous permet de choisir entre horizontal (par dfaut) ou vertical.
<Slider HorizontalAlignment="Center" Minimum="0" Maximum="100" Value="50" Ticks="10,20,30,40,50,60,70,80,90" TickPlacement="BottomRight" AutoToolTipPlacement="TopLeft" AutoToolTipPrecision="0"
116 Le guide du codeur

Utiliser un Slider

LargeChange="10" Delay="500" Interval="200" IsSelectionRangeEnabled="True" SelectionStart="20" SelectionEnd="80" Height="200" Orientation="Vertical" />

b Figure 4-26 : Un Slider vertical

Dnition de la taille En orientation verticale, la taille est contrle non plus par lattribut Width mais bien par lattribut Height.

Bien sr, ce contrle accepte les attributs habituels.


<Slider HorizontalAlignment="Center" BorderBrush="Black" BorderThickness="1" Foreground="Blue" Background="LightGray" Minimum="0" Maximum="100" Value="50" Ticks="10,20,30,40,50,60,70,80,90" TickPlacement="BottomRight" AutoToolTipPlacement="TopLeft" AutoToolTipPrecision="0" LargeChange="10" Delay="500" Interval="200" IsSelectionRangeEnabled="True" SelectionStart="20" SelectionEnd="80" Height="200" Orientation="Vertical" />

Le guide du codeur 117

Les autres contrles de base

b Figure 4-27 : Un Slider color

4.9 Utiliser un Expander


Si vous avez beaucoup dinformations afficher sur votre cran, il peut rapidement devenir surcharg et peu lisible. Pour remdier cela, vous pouvez comme nous lavons vu prcdemment utiliser les onglets. Pour plus dinformations sur lutilisation des onglets, voyez le
Renvoi chapitre Utiliser les panneaux onglets page 109.

Une autre solution est dutiliser un Expander. Celui-ci a la facult dafficher ou de cacher son contenu en ne laissant alors visible que son titre.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Expander" > <StackPanel> <Expander Header="Informations" IsExpanded="false"> <TextBlock> Cette zone contient un texte dinformation </TextBlock> </Expander>

118 Le guide du codeur

Utiliser un Expander

Un Expander peut parfaitement contenir plus dun contrle utilisateur mais, dans ce cas, ils devront tre encapsuls dans un conteneur.
<Expander Header="Contenu" IsExpanded="true"> <StackPanel> <WrapPanel> <Label Width="60"> Nom: </Label> <TextBox Name="txtNom" Width="150"/> </WrapPanel> <WrapPanel> <Label Width="60"> Prnom: </Label> <TextBox Name="txtprenom" Width="150"/> </WrapPanel> </StackPanel> </Expander> <Expander Header="Plus"> <WrapPanel> <Label Width="60"> Tl: </Label> <TextBox Name="txttel" Width="150"/> </WrapPanel> </Expander> <Button Width="80"> Ok </Button> </StackPanel> </Page>

b Figure 4-28 : Utilisation dExpander Le guide du codeur 119

Les autres contrles de base

Pour ouvrir ou fermer un Expander, il suffit dutiliser les ches sur sa droite ; lorientation des ches indique sil est ouvert ou ferm. Si les ches sont diriges vers le bas, le contenu est cach. A contrario, si les ches sont diriges vers le haut, le contenu est affich.

b Figure 4-29 : Lutilisateur a ouvert tous les Expander

Comme vous pouvez le constater, il est possible de mettre plusieurs Expander dans une mme page. En revanche, un Expander ne peut avoir quun seul nud enfant. Celui-ci sera ds lors souvent un conteneur comme un StackPanel. Notez dans lexemple lutilisation combine de StackPanel et de WrapPanel. Lattribut Header permet de dterminer le titre, alors que lattribut IsExpanded indique si la zone est cache (false) ou affiche (true). Par dfaut, le contenu est cach. Notez que le bouton ne sera jamais cach car il nest pas repris dans une balise
Expander.

Direction dexpansion Si vous souhaitez que la zone souvre vers le haut plutt que vers le bas, utilisez lattribut ExpandDirection et assignez-lui la valeur Up.

120 Le guide du codeur

Utiliser une ViewBox

4.10 Utiliser une ViewBox


La ViewBox permet de dnir une zone cran dont le contenu pourra tre automatiquement adapt la taille de la zone. Ladaptation se fait en tendant verticalement, horizontalement ou dans les deux sens le contenu.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <StackPanel> <Viewbox MaxWidth="150" MaxHeight="150" Stretch="Fill" StretchDirection="Both"> <TextBlock> TEXT </TextBlock> </Viewbox> </StackPanel> </Page>

b Figure 4-30 : Affichage dune ViewBox

Grce loption Stretch="Fill", le contenu occupe automatiquement lentiret de la ViewBox. Lattribut StretchDirection vous permet de limiter lagrandissement au sens horizontal ou vertical. Si vous changez la largeur de 150 en 50, le contenu est modi en fonction.

Le guide du codeur 121

Les autres contrles de base

b Figure 4-31 : La mme ViewBox modie

Selon la valeur donne lattribut Stretch, le rsultat sera fort diffrent. Pour bien comprendre le fonctionnement de chacune de ces valeurs, voici un autre exemple.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <WrapPanel> <Border BorderBrush="Black" BorderThickness="1" Margin="5,5,5,5"> <Viewbox Width="70" Height="100" Stretch="None" StretchDirection="Both"> <Image Source="c:\Mir.bmp" Width="50" Height="50"/> </Viewbox> </Border> <Border BorderBrush="Black" BorderThickness="1" Margin="5,5,5,5"> <Viewbox Width="70" Height="100" Stretch="Fill" StretchDirection="Both"> <Image Source="c:\Mir.bmp" Width="50" Height="50"/> </Viewbox> </Border> <Border BorderBrush="Black" BorderThickness="1" Margin="5,5,5,5"> <Viewbox Width="70" Height="100" Stretch="Uniform" StretchDirection="Both">

122 Le guide du codeur

Utiliser un Popup

<Image Source="c:\Mir.bmp" Width="50" Height="50"/> </Viewbox> </Border> <Border BorderBrush="Black" BorderThickness="1" Margin="5,5,5,5"> <Viewbox Width="70" Height="100" Stretch="UniformToFill" StretchDirection="Both"> <Image Source="c:\Mir.bmp" Width="50" Height="50"/> </Viewbox> </Border> </WrapPanel> </Page>

b Figure 4-32 : Effet de lattribut Stretch

Pour une question de clart de lexemple, la taille de limage est xe dans le code 50 sur 50 et est place dans quatre ViewBox identiques lexception de la valeur de lattribut Stretch. Les balises Border sont uniquement prsentes pour dlimiter visuellement lemplacement des ViewBox. Le rsultat parle de lui-mme.

4.11 Utiliser un Popup


Le Popup permet douvrir une zone cran contenant nimporte quel contenu XAML. Il est parfois confondu tort avec les tooltips, dont il peut simuler lutilisation. En effet, lattribut PlacementTarget permet dassocier le Popup un autre lment de lcran tandis que PlacementRectangle permet den dnir les dimensions. Pour utiliser un Popup, il faut aussi utiliser du code .NET. Pour bien comprendre son utilisation, il est ncessaire de comprendre galement la gestion des vnements. Si tel nest pas votre cas, sachez seulement que, lorsque vous cliquez sur le bouton Cliquer pour ouvrir, la mthode
Le guide du codeur 123

Les autres contrles de base

AffichePopup est excute et que, lorsque vous cliquez sur le bouton Cliquer pour fermer, cest la mthode CachePopup qui est excute.

La gestion des vnements sera aborde dans un chapitre spcique


Renvoi page 138.

<Page x:Class="Page1" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <StackPanel> <Button Name="MonBouton" Click="AffichePopup"> Cliquez pour ouvrir </Button> <Popup Name="MonPopup" PlacementTarget="{Binding ElementName=MonBouton}" PlacementRectangle="30,20,100,40"> <Border BorderThickness="1" BorderBrush="Black"> <StackPanel Margin="5,5,5,5" Background="AliceBlue"> <Label> Ceci nest pas un tooltip mais un popup et peut tre une page part entire </Label> <Button Click="CachePopup"> Cliquez pour fermer </Button> </StackPanel> </Border> </Popup> </StackPanel> </Page> Interaction logic for Page1.xaml Partial Public Class Page1 Inherits Page Public Sub New() InitializeComponent() End Sub Public Sub AffichePopup(ByVal sender As Object, ByVal e As RoutedEventArgs) Me.MonPopup.IsOpen = True End Sub

124 Le guide du codeur

Utiliser un Popup

Public Sub CachePopup(ByVal sender As Object, ByVal e As RoutedEventArgs) Me.MonPopup.IsOpen = False End Sub End Class

b Figure 4-33 : Le Popup ferm

Comme vous pouvez le constater, rien ne suggre quil puisse y avoir un Popup.

b Figure 4-34 : Le Popup ouvert

Le guide du codeur 125

Les autres contrles de base

4.12 Ajouter de la vido dans la fentre


Pour visionner une vido ou simplement jouer de la musique, vous pouvez utiliser la classe MediaElement. Elle sutilise assez simplement mais dispose bien sr de proprits et mthodes pour la gestion telles simplement les mthodes Play, Pause et Stop.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Grid Background="Black"> <Border Width="300" Height="200" Name="Movie" BorderBrush="White" CornerRadius="2" BorderThickness="2"> <MediaElement LoadedBehavior="Play" Source="c:\News.wmv" /> </Border> </Grid> </Page>

b Figure 4-35 : Visionner une vido

MediaElement est simplement place dans un cadre. La proprit Source permet de dnir le chier multimdia qui devra tre utilis. La proprit LoadedBehavior permet de dterminer laction qui sera prise directement aprs le chargement du contrle. La proprit UnloadedBehavior a le mme effet mais lors du dchargement du contrle. Les valeurs possibles sont Stop, Play, Close, Pause, NoSet et Manual.

126 Le guide du codeur

Ajouter de la vido dans la fentre

cran vide Il est possible que lemplacement o devrait se trouver la vido reste vide. Il sagit dun problme de pilote de la carte cran qui nest pas adapt. En effet, MediaElement requiert un pilote rcent et adapt. Si cest votre cas, essayez de mettre jour votre pilote. Cest aussi pour cette raison que lcran vous est prsent sous Windows Vista et non sous Windows XP comme les autres crans.

Il existe galement une classe SoundPlayer et une MediaPlayer. SoundPlayer ne peut tre utilise directement en XAML mais uniquement en code .NET. De manire gnrale, lutilisation de MediaElement est trs largement privilgie, et tout particulirement dans le code XAML. Il est possible galement dutiliser les Triggers pour manipuler la vido depuis, par exemple, des boutons. Dans lexemple qui suit, un bouton Play permet de dmarrer la vido et un bouton Pause permet de larrter. Si vous voulez plus dinformations sur les triggers, reportez-vous au
Renvoi chapitre Utiliser les Triggers page 238.

<Window x:Class="Window1" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="WindowsApplication8" Height="300" Width="300" > <Window.Triggers>

Le trigger suivant sera dclench lors du clic sur le bouton btnPlay.


<EventTrigger RoutedEvent="Button.Click" SourceName="btnPlay"> <EventTrigger.Actions> <BeginStoryboard Name= "Debut"> <Storyboard>

Le storyboard a dni une MediaTimeLine qui est une TimeLine spcique aux lments multimdias. Cest ici quest dnie la source.
<MediaTimeline Source="c:\news.wmv" Storyboard.TargetName="laVideo"/> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger>

Le guide du codeur 127

Les autres contrles de base

Le trigger suivant sera dclench lors du clic sur le bouton btnPause.


<EventTrigger RoutedEvent="Button.Click" SourceName="btnPause"> <EventTrigger.Actions>

La commande suivante met en pause le storyboard appel Debut.


<PauseStoryboard BeginStoryboardName="Debut" /> </EventTrigger.Actions> </EventTrigger> </Window.Triggers> <StackPanel>

Aucune source nest dnie pour le MediaElement.


<MediaElement Height="100" Width="150" Name="laVideo"/> <Button Name="btnPlay" >Play</Button> <Button Name="btnPause" >Pause</Button> </StackPanel> </Window>

b Figure 4-36 : Fentre de visualisation

Si vous cliquez sur le bouton Play, la vido dmarre.

128 Le guide du codeur

Checklist

b Figure 4-37 : La vido affiche

Mthodes de MediaElement Vous pouvez remarquer qu aucun moment nous navons utilis les mthodes Start et Pause de la classe MediaElement.

4.13 Checklist
Ce chapitre a t loccasion de passer en revue les diffrents contrles permettant de raliser une interface utilisateur complte. Cest--dire :
j

crer et manipuler les listes droulantes, que ce soient les ListBox ou les
ComboBox ;

j j j j j j j j j j

utiliser les cases cocher (CheckBox) ; utiliser les boutons radio (RadioButton) et les grouper ; crer des info-bulles (ToolTip) ; crer un panneau onglets (TabControl) ; congurer un bouton pour le rendre autorptitif ; utiliser un curseur (Slider) pour dterminer une valeur ; utiliser des Expander pour rendre linterface plus lisible ; utiliser une ViewBox ; crer des fentres Popup ; manipuler le multimdia avec MediaElement.

Le guide du codeur 129

Ch apit re

5 Crer une application


Crer une application Windows .................... Grer les vnements ................................ Hberger une application dans un browser .... Les pages fonctions ................................... Crer une application Windows navigable ...... Les applications avec WPF/E ...................... Checklist .................................................. 132 138 140 149 157 165 167

Crer une application

5.1 Crer une application Windows


Aprs avoir manipul le XAML avec XAMLPad, voyons maintenant comment raliser une application. Dans le domaine, nous jouerons la conformit avec le trs traditionnel "Hello World". Pour commencer, ouvrez Visual Studio. Choisissez Fichier, Nouveau, Projet.

m Figure 5-1 : Choix du type de projet

Dans la fentre des projets, choisissez le type WinFX Windows Application.

Ce type nest pas prsent Si vous ne trouvez pas ce type de projet dans Visual Studio, cest que vous navez pas install le kit de dveloppement ou, selon les versions, ladd-in pour Visual Studio. Vous le trouverez sur le site de Microsoft.

Donnez un nom lapplication, par exemple HelloWorld.

b Figure 5-2 : Lexplorateur de solution dans un projet WinFX

132 Le guide du codeur

Crer une application Windows

b Figure 5-3 : Lexplorateur de solution dans un projet WinForm

Au lieu du traditionnel Form1.vb, vous retrouvez quatre chiers diffrents. Ils sont associs par paire : les chiers MyApp.xaml et MyApp.xaml.vb, dune part, et les chiers Window1.xaml et Window1.xaml.vb, dautre part. Chaque paire de chiers prend en charge la gestion dune classe. Il est vrai que, si vous avez dj travaill avec Visual Studio 2005, vous savez que derrire le chier Form1.vb se cachait un chier Form1.Designer.vb. Le but dans les deux cas est le mme : sparer le code daffichage du code de traitement. Mais revenons notre projet et examinons pour commencer le chier MyApp.xaml. <Application x:Class="MyApp" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="Window1.xaml"> <Application.Resources> </Application.Resources> </Application> A priori, il est probable que vous nayez pas changer ce chier sauf lattribut

StartupUri, qui dnit la classe instancier et excuter au dmarrage de lapplication. Il ne serait pas de bon ton de conserver pour votre classe le nom par dfaut. Remplacez Window1.xaml par HelloWorld.xaml.

Le chier code .Net associ est encore plus simple.


Interaction logic for MyApp.xaml Partial Public Class MyApp Inherits Application End Class

Comme vous le voyez, ce niveau rien dire. Dans la majorit des cas, vous naurez pas ajouter du code dans cette partie. Nhsitez pas, toutefois,

Le guide du codeur 133

Crer une application

changer le nom MyApp en un nom plus cohrent. Faites-le galement dans le chier xaml et renommez aussi les chiers.

Proprits de lapplication Quand vous changez le nom du chier MyApp, la proprit Action de gnration du chier devient Page. Vous devez remettre la valeur ApplicationDefinition. Pour y accder, cliquez du bouton droit sur le nom du chier et choisissez Proprits.

b Figure 5-4 : Proprits dun chier

Nom des classes Si le nom des classes diffre entre le chier XAML et le chier xaml.vb, vous aurez immanquablement une erreur la compilation. Les chiers peuvent porter un autre nom que la classe mais il est de bon aloi de garder le mme.

Passons maintenant au chier dcrivant la fentre de lapplication.


Nom des classes et des chiers Les classes et les chiers ont t renomms pour porter le nom HelloWorld.

134 Le guide du codeur

Crer une application Windows

<Window x:Class="HelloWorld" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Ma premire application" > <Grid> </Grid> </Window>

Comme vous pouvez le constater, Microsoft vous propose par dfaut lutilisation dune grille. Contrairement aux exemples vus jusqu prsent, la premire balise est une balise Window et non plus une balise Page. La balise Window est utilise pour dnir une fentre de type Windows. Nous reviendrons ultrieurement sur lutilisation de la balise Page. Ajoutons le code suivant entre les balises Grid.
<Label VerticalAlignment="Center" HorizontalAlignment="Center"> Bonjour le monde. </Label>

Nous pouvons maintenant excuter lapplication. Appuyez sur la touche [F5].

b Figure 5-5 : Ma premire application

La balise Window dispose comme les autres balises dun grand nombre dattributs. Certains comme Width ou MinHeight ont dj t vus dans dautres chapitres et nous ne reviendrons pas dessus. En revanche, il existe quelques autres attributs fort intressants. Vous avez dj pu voir dans les exemples laction de lattribut Title, qui permet de dnir le titre de la fentre. Pour positionner la fentre, vous disposez de lattribut WindowsStartupLocation, qui va dterminer la position initiale de la fentre.
WindowStartupLocation="CenterScreen"

Le guide du codeur 135

Crer une application

Les valeurs possibles sont CenterScreen pour centrer la fentre dans lcran, idal pour la fentre principale ; CenterOwner pour centrer la fentre dans la fentre qui la contient, idal pour les sous-fentres ; et Manual pour vous permettre de choisir la position vous-mme. Cette dernire valeur est utiliser en conjonction avec les attributs Top et Left.
<Window x:Class="HelloWorld" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Ma premire application" WindowStartupLocation="Manual" Top="100" Left="300" >

Un autre attribut intressant est lattribut SizeToContent. Sil est x True, la taille de la fentre lors de la cration sera automatiquement adapte au contenu.
SizeToContent="WidthAndHeight"

b Figure 5-6 : Utilisation de SizeToContent

Il est possible de nadapter la taille quen largeur en utilisant la valeur Width ou uniquement en hauteur en utilisant la valeur Height. Vous pouvez galement opter pour dmarrer automatiquement en mode maximis ou minimis.
WindowState="Maximized"

Il est galement possible de modier le comportement et les possibilits de redimensionnement des fentres en utilisant lattribut ResizeMode.
ResizeMode="CanResizeWithGrip"

b Figure 5-7 : Utilisation de ResizeMode

136 Le guide du codeur

Crer une application Windows

Notez le grip en bas droite. Vous pouvez galement opter pour interdire le redimensionnement avec la valeur NoResize. La taille de la fentre nest pas la seule chose que nous puissions modier, il est galement possible de modier son affichage en ajoutant lattribut WindowStyle. Par dfaut, sa valeur est SingleBorderWindow, mais vous pouvez ajouter un effet 3D.
WindowStyle="ThreeDBorderWindow"

b Figure 5-8 : Fentre avec effet 3D

Ou lui donner le look dune fentre doutils.


WindowStyle="ToolWindow"

b Figure 5-9 : Fentre doutils

Ou encore afficher la fentre sans aucun bord.


WindowStyle="None"

b Figure 5-10 : Fentre sans bordure

Le guide du codeur 137

Crer une application

Pour certaines fentres, vous souhaiterez peut-tre quil ne soit pas possible de les recouvrir avec une autre. Si cest le cas, utilisez lattribut Topmost.
Topmost="True"

Par dfaut, toutes les fentres sont automatiquement reprises dans la barre des tches. Si, pour la fentre principale, cette option par dfaut est judicieuse, ce nest pas toujours le cas pour les autres fentres. Pour viter quune fentre ne soit reprise dans la barre des tches, il suffit dutiliser lattribut ShowInTaskbar.
ShowInTaskbar="False"

5.2 Grer les vnements


Pour illustrer lutilisation des vnements, reprenons lexemple prcdent. Pour une simple question de facilit, dans ce nouvel exemple la grille est toutefois remplace par un StackPanel.
<Window x:Class="HelloWorld" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Ma premire application" WindowStartupLocation="Manual" Top="100" Left="300" Name="HelloWorld" > <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> <Label Name="lblTexte"> Bonjour le monde. </Label> <Button Name="btnRepondre"> Rpondre </Button> </StackPanel> </Window>

Centrage Les attributs ralisant le centrage sont dplacs du Label au StackPanel. Sans cela, vu le type de fonctionnement du StackPanel, le centrage vertical dans la fentre naurait pas lieu.

138 Le guide du codeur

Grer les vnements

Un bouton a galement t ajout la fentre. La question est maintenant de savoir comment associer une action au bouton. Comme vous pouvez limaginer, laction sera ralise dans le code .NET au sein dune mthode de la classe. Ceci tant entendu, le problme se rsume alors associer le bouton la mthode voulue. Tout dabord, il faut savoir que la mthode doit tre associe non pas au bouton lui-mme mais un vnement du bouton. En loccurrence, lvnement Click. Commenons par crire dans le code VB une mthode que vous dsirez excuter.
Public Sub Click_Repondre(ByVal sender As Object _ , ByVal e As RoutedEventArgs) Me.lblTexte.Content = "Merci" Me.btnRepondre.IsEnabled = False End Sub

Cette mthode va remplacer le texte "Bonjour le monde" par "Merci". La signature de la mthode, cest--dire les diffrents paramtres, doit absolument respecter la dnition reprise dans lexemple. Elle correspond par ailleurs strictement la dnition des mthodes charges de rpondre aux vnements dans lenvironnement .NET. Le nom est quant lui entirement libre, mais choisissez toujours un nom parlant.

Utiliser lIntelliSense Pour bncier de lIntelliSense et ainsi retrouver facilement les noms des membres que vous aurez dnis dans votre code XAML, nhsitez pas utiliser le mot cl ME mme sil est facultatif.

Maintenant que nous avons dni la mthode, il ne reste plus quune simple tape faire, raliser lassociation entre lvnement et la mthode. Nous pourrions classiquement le faire en .NET mais il est plus judicieux de le faire dans le code XAML.
<Button Name="btnSuite" Click="Click_Repondre"> Suite </Button>

Cest aussi simple que cela. Le nom de lattribut correspond au nom de lvnement et la valeur est le nom de la mthode appeler.

Le guide du codeur 139

Crer une application

b Figure 5-11 : Cliquer sur Rpondre

b Figure 5-12 : Rpondre a t cliqu

La mme technique peut tre applique avec nimporte quel vnement de nimporte quelle classe.

5.3 Hberger une application dans un browser


Aperu de cette technologie
Il est possible de crer avec XAML des applications qui sexcutent non pas dans une fentre Windows mais dans un navigateur Internet. On parle alors de smart client. Ce type dapplication est galement appel Web Browser Application ou WBA. Il sagit dune application online qui sexcute dans un browser et qui nest pas installe localement. En rsum, en accdant une URL le programme est tlcharg et excut sans quil ne soit install. Contrairement une application ASP.NET, le programme sexcute sur le poste client et non sur le serveur. Il fait le lien avec les serveurs de donnes exactement comme le ferait une application Windows classique. Comme lapplication sexcute sur le poste client, elle nest plus soumise aux restrictions imposes par le HTML. Vous pouvez dans ce type dapplication
140 Le guide du codeur

Hberger une application dans un browser

tirer parti de toute la puissance des API WinFX ou presque, et ce y compris les fonctionnalits 3D. Toutefois, comme pour lASP.NET, le dveloppement se fait en mode Page. Contrairement une application ASP.NET, les pages sont codes dans un mme module. Leur accs se fera alors sans devoir faire appel au serveur. En revanche, le fait que lapplication soit excute sur le poste client rend ncessaire la prsence de WinFX sur le poste client. Il ne sagit donc pas dune technologie universelle indpendante de la plate-forme utilise comme lest le HTML.

La scurit et les WBA


Lapplication nest pas installe sur votre PC mais est excute quand vous accdez une adresse web depuis votre navigateur. Donc, a priori, vous ne connaissez pas forcment lapplication qui va sexcuter. Ce qui pourrait entraner de graves risques pour la scurit de votre PC. Pour ces raisons, lapplication est excute dans une Sandbox (aussi appel bac sable) ; cest--dire un environnement o les privilges attribus lapplication sont rduits. Par dfaut, lapplication sera excute dans la zone Internet. De cette manire, la scurit de votre ordinateur est assure au mme titre quavec une application web traditionnelle. Le fait dexcuter lapplication dans un environnement ferm a pour consquence que certaines fonctionnalits ne peuvent tre utilises. Les droits attribus la Sandbox peuvent tre tendus en modiant la zone dexcution, comme vous pouvez le faire avec nimporte quel site. Par exemple, vous pouvez placer lapplication dans la zone intranet au lieu de la zone Internet. De cette manire, vous allez rcuprer un certain nombre de fonctionnalits.

Hberger et excuter ce type dapplication


Lapplication est stocke sur un serveur web. En ce qui concerne IIS, vous devez disposer de la version 5 ou suprieure. Le serveur ne doit pas ncessairement contenir WinFX. En revanche, un minimum de conguration est ncessaire. La conguration du serveur dpasse largement le cadre de cet ouvrage mais, si vous tes intress, vous pouvez trouver les informations ncessaires sur le site de Microsoft. Sur le client, WinFX doit tre install. Le browser doit tre Internet Explorer 6 ou suprieur ou nimporte quel browser qui implmente Microsoft WebBrowser Control. Vous pouvez galement parfaitement excuter des applications de ce type et qui sont prsentes sur votre PC.

Le guide du codeur 141

Crer une application

Quand recourir ce modle dapplication ?


Par ses spcicits, les WBA sont particulirement utiles pour les applications contenu ou logique complexe pour lesquelles vous ne souhaitez pas installer un client local. L o les deux clients doivent exister, le fait que le code puisse tre facilement transpos entre smart client et client riche est aussi un atout. Il est clair quil sera plus ais dutiliser ce type dapplication dans un environnement intranet homogne.

Crer une WBA


Pour crer une WBA dans Visual Studio, vous devez crer un nouveau projet et choisir le type WinFX Web Browser Application, anciennement connue sous le nom dExpress Application.

m Figure 5-13 : Crer une WBA

Le contenu du projet est trs semblable au contenu pour une application Windows.

b Figure 5-14 : Contenu dune WBA

142 Le guide du codeur

Hberger une application dans un browser

Vous y retrouvez les deux paires de chiers mais, cette fois, au lieu de Window1 les chiers se nomment Page1. Voyons le contenu de ces quatre chiers et les diffrences par rapport ceux raliss dans lapplication Windows (voir p. 132). Si ce nest ladresse de lURI, les chiers MyApp.xaml et MyApp.xaml.vb sont identiques ceux dj vus.
<Application x:Class="MyApp" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="Page1.xaml" > <Application.Resources> </Application.Resources> </Application> Interaction logic for MyApp.xaml Partial Public Class MyApp Inherits Application End Class

En revanche, les chiers Page1.xaml et Page1.xaml.vb hritent non plus dun objet de classe Window mais bien dun objet de la classe Page.
<Page x:Class="Page1" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Page1" > <Grid> </Grid> </Page> Imports Imports Imports Imports Imports Imports Imports Imports System System.Windows System.Windows.Controls System.Windows.Data System.Windows.Documents System.Windows.Media System.Windows.Media.Imaging System.Windows.Navigation

Le guide du codeur 143

Crer une application

Imports System.Windows.Shapes Interaction logic for Page1.xaml Partial Public Class Page1 Inherits Page Public Sub New() InitializeComponent() End Sub End Class

Il ny a en dnitive pas de diffrences notables. Pour changer les noms des classes et des chiers, vous devez utiliser
Renvoi la technique dcrite dans le paragraphe Crer une application

Windows page 132.

Maintenant, intgrons le code utilis dans notre application Windows.


<Page x:Class="Page1" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Page1" > <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> <Label Name="lblTexte"> Bonjour le monde. </Label> <Button Name="btnRepondre" Click="Click_Repondre"> Rpondre </Button> </StackPanel> </Page> Imports Imports Imports Imports Imports Imports Imports Imports Imports System System.Windows System.Windows.Controls System.Windows.Data System.Windows.Documents System.Windows.Media System.Windows.Media.Imaging System.Windows.Navigation System.Windows.Shapes

Interaction logic for Page1.xaml Partial Public Class Page1

144 Le guide du codeur

Hberger une application dans un browser

Inherits Page Public Sub New() InitializeComponent() End Sub Public Sub Click_Repondre(ByVal sender As Object _ , ByVal e As RoutedEventArgs) Me.lblTexte.Content = "Merci" Me.btnRepondre.IsEnabled = False End Sub End Class

Excutez lapplication en utilisant par exemple la touche [F5].

b Figure 5-15 : Excution dune WBA

Lapplication est trs semblable lapplication Windows mais elle est bien excute dans le navigateur. Si nous cliquons sur le bouton Rpondre, lapplication ragit comme prvu.

b Figure 5-16 : vnement activ dans la WBA

Le guide du codeur 145

Crer une application

Erreur de scurit Si vous utilisez une version express de Visual Studio, vous recevrez peut-tre une erreur de scurit lors de la premire excution. Fermez puis rouvrez votre projet et lerreur disparatra delle-mme.

Si dans votre page vous ne devez pas utiliser de mthode, vous pouvez opter pour une page XAML seule. Il sagit alors dune page statique. Le code XAML sera directement excut lors du chargement de la page. Faites un copier-coller du code XAML dans NotePad. Supprimez lattribut Class et lattribut Click an dobtenir le code suivant :
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Page1" > <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> <Label Name="lblTexte"> Bonjour le monde. </Label> <Button Name="btnRepondre"> Rpondre </Button> </StackPanel> </Page>

Sauvez le document et, depuis lExplorateur Windows, double-cliquez dessus ou tapez son adresse dans Internet Explorer. La mme page est charge mais, bien entendu, le bouton neffectue plus aucune action. Comme il est possible de modier la taille dune fentre Windows, il est galement possible de modier la taille de la page mais aussi de la fentre du navigateur. Les attributs WindowWidth et WindowHeight permettent de contrler la taille de la fentre du navigateur alors que les attributs Width et Height contrlent la taille de la page. Modiez les valeurs de ces attributs dans lexemple ci-dessous pour bien comprendre leur porte.
<Page x:Class="Page1" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Page1" WindowTitle="Ma page"
146 Le guide du codeur

Hberger une application dans un browser

<Border BorderThickness="1" BorderBrush="Black"> <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> <Label Name="lblTexte"> Bonjour le monde. </Label> <Button Name="btnRepondre" Click="Click_Repondre"> Rpondre </Button> </StackPanel> </Border> </Page>

>

WindowWidth="500" WindowHeight="300" Width="470" Height="200"

Titre de la fentre Le titre de la fentre est donn non pas par lattribut Title de la balise Page mais bien par lattribut WindowTitle.

Enchanement des pages


Pour naviguer entre les pages, WinFX met notre disposition la classe NavigationService. An dillustrer son utilisation, nous allons remplacer dans lexemple prcdent laffichage du mot "merci" dans ltiquette par laffichage dune page "Merci". Crons tout dabord la nouvelle page afficher.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Page2" > <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> <Label Name="lblTexte"> Merci. </Label> </StackPanel> </Page>
Le guide du codeur 147

Crer une application

La page tant entirement statique, il est inutile de crer une contre-partie VB. videmment, si votre seconde page est plus labore, rien nempche de crer une page complte avec du contenu XAML et .NET. Maintenant, voyons comment raliser lappel de cette page depuis le code .NET de notre premire page.
Public Sub Click_Repondre(ByVal sender As Object _ , ByVal e As RoutedEventArgs) Me.NavigationService.Navigate(New Uri("Page2.xaml", UriKind.Relative)) End Sub

Lappel la page se fait comme prcdemment dans lvnement Click associ au bouton en utilisant la mthode Navigate de la proprit NavigationService. Cette mthode reoit comme paramtre une URI qui donne ladresse de la page afficher. LURI peut tre absolue ou relative.

b Figure 5-17 : Navigation entre pages

Barre de navigation dInternet Explorer Notez que la barre de navigation du navigateur ne permet pas de raliser les habituelles oprations Prcdente, Suivante. Vous devez pour cela utiliser la barre de navigation spcique. b Figure 5-18 : Barre de navigation

Si vous ne souhaitez pas voir apparatre la barre de navigation, il suffit dassigner False lattribut ShowsNavigationUI de la balise Page.
148 Le guide du codeur

Les pages fonctions

<Page x:Class="Page1" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Page1" ShowsNavigationUI="False" >

b Figure 5-19 : Sans barre de navigation

NavigationService dispose galement des mthodes GoBack et GoForward pour provoquer un passage la page prcdente ou la page suivante. Les mthodes CanGoBack et CanGoForward vous informent sur la possibilit ou non dappeler les mthodes respectives.

5.4 Les pages fonctions


Les pages fonctions sont un type de page particulier. Ce type de page est appel depuis une autre page et peut recevoir des paramtres. Il dispose dune mthode OnReturn qui provoque le retour dans la page appelante et qui, de plus, permet de renvoyer une valeur. Il nest pas ncessaire de connatre la page appelante. Pour rcuprer la valeur en retour, il faudra utiliser la gestion des vnements. Nous aurons besoin de cette petite classe utilitaire dveloppe pour lexemple ci-aprs.
Public Class Data Public Val As Integer Public Texte As String End Class

Le guide du codeur 149

Crer une application

Il ny a pas grand-chose dire sur cette classe. Elle servira pour le transfert de donnes entre les pages. La premire page qui est automatiquement charge lors du dmarrage de lapplication est une page classique qui hrite de Page.
<Page x:Class="Page1" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Page1" > <StackPanel> <Label Name="valeur"/> <Label Name="texte"/> <Button Name="btnPageSuiv" Click="PageSuivante"> Page suivante </Button> </StackPanel> </Page>

Dans le chier Page1.xaml, deux Label sont dnies mais sont vierges. Elles serviront afficher les valeurs reues. Le bouton sert demander la navigation vers la page suivante. Lappel se fera dans la mthode PageSuivante.
Partial Public Class Page1 Inherits Page

Dans le code .NET associ, nous dclarons un membre du type de la page qui sera appel. Il est important de dclarer que la page se mettra lcoute des vnements, ce qui est ralis avec WithEvents.
Private WithEvents pageSuiv As Page2 Public Sub New() InitializeComponent() End Sub Sub PageSuivante(ByVal sender As Object, ByVal e As RoutedEventArgs)

La transmission des paramtres la page se fait par le constructeur. Lappel de la page elle-mme se fait exactement comme une page normale.
pageSuiv = New Page2("dfaut") Me.NavigationService.Navigate(pageSuiv) End Sub

Il faut dnir la mthode qui sera appele lors du retour. Pour quelle soit effectivement appele, il faut lassocier lvnement avec Handles. Notez que
150 Le guide du codeur

Les pages fonctions

le type de la valeur reue est prcis.


Private Sub return_handler( _ ByVal sender As Object, _ ByVal e As ReturnEventArgs(Of Data)) _ Handles pageSuiv.Return

Les valeurs reues sont places dans les contrles Label et le bouton est dsactiv.
valeur.Content = e.Result.Texte texte.Content = e.Result.Val btnPageSuiv.IsEnabled = False End Sub End Class

Nous devons maintenant dnir la page 2, qui sera une PageFunction. Notez la dnition du type de paramtre et la prsence de la dclaration du namespace de lapplication. Le namespace tant dans lassembly du programme, il nest pas ncessaire de prciser lassembly. La TextBox recevra la valeur reue en paramtre, qui pourra ainsi tre modie. La mthode associe lvnement Click du bouton aura pour effet de fermer la page.
<PageFunction x:Class="Page2" x:TypeArguments="app:Data" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:app="clr-namespace:WinFxBrowserApplication1" Title="Page2" > <StackPanel> <TextBox Name="texte"/> <Button Click="Fin"> Fin </Button> </StackPanel> </PageFunction>

Mme dans le code .NET, ds la dclaration de la page, il faut dcrire les paramtres reus.
Partial Public Class Page2 Inherits PageFunction(Of Data) Private donne As New Data

Le constructeur reoit le paramtre.


Public Sub New(ByVal initVal As String) InitializeComponent()

Le guide du codeur 151

Crer une application

donne.Texte = initVal donne.Val = 100 texte.Text = initVal End Sub

Pour fermer la fentre et revenir la page appele, on utilise OnReturn, qui doit imprativement retourner un objet de type ReturnEventArgs qui est un type gnrique.
Sub Fin(ByVal sender As Object, ByVal e As RoutedEventArgs) donne.Texte = texte.Text Dim retour As New ReturnEventArgs(Of Data)(donne) OnReturn((retour) End Sub End Class

Lors du dmarrage de lapplication, nous recevons la premire page.

b Figure 5-20 : La page 1

Aprs avoir cliqu sur le bouton, la deuxime page est affiche. Et nous pouvons changer la valeur dans la bote de texte.

b Figure 5-21 : La page 2

152 Le guide du codeur

Les pages fonctions

Aprs avoir cliqu sur le bouton de n, la premire page est nouveau affiche.

b Figure 5-22 : La page 1 modie

Il est galement possible dutiliser cette technique dans un Frame. Vous pouvez par exemple raliser une fentre complte avec un menu et divers lments qui doivent perdurer tout au long de la navigation et utiliser le Frame comme zone daffichage des diffrents contenus. En somme, il sagit dun genre de page matre. Pour illustrer cela, imaginons que notre page de dmarrage est la page StartPage dcrite ci-dessous.
<Page x:Class="StartPage" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="StartPage" > <DockPanel VerticalAlignment="Top"> <Image DockPanel.Dock="Top" Source="c:\photo.jpg" MinWidth="300"> </Image> <Menu DockPanel.Dock="Top" Height="30"> <MenuItem Header="Page 1" Click="GoToPage1"/> <MenuItem Header="Page 2" Click="GoToPage2"/> <MenuItem Header="Page 3" Click="GoToPage3"/> </Menu> <StatusBar DockPanel.Dock="Bottom" Background="LightBlue"> <Label> Micro Application </Label>

Le guide du codeur 153

Crer une application

</StatusBar> <Frame Name="zoneContenu" Source="HomePage.xaml" MinHeight="150"/> </DockPanel> </Page>

Il sagit dune page classique dont le menu servira naviguer et contenant un Frame qui reoit HomePage.xaml, dont le contenu est en dnitive la page daccueil.
Partial Public Class StartPage Inherits Page Public Sub New() InitializeComponent() End Sub Sub GotoPage1(ByVal sender As Object, ByVal e As RoutedEventArgs) Dim nvPage As New Page1 zoneContenu.Navigate(nvPage) End Sub Sub GotoPage2(ByVal sender As Object, ByVal e As RoutedEventArgs) Dim nvPage As New Page2 zoneContenu.Navigate(nvPage) End Sub Sub GotoPage3(ByVal sender As Object, ByVal e As RoutedEventArgs) Dim nvPage As New Page3 zoneContenu.Navigate(nvPage) End Sub End Class

Si nous examinons le code .NET de la page, nous pouvons constater qu chaque action du menu une nouvelle page est affiche en provoquant la navigation dans le Frame uniquement. Notre page matre reste donc bel et bien toujours affiche.
coute des vnements Contrairement lexemple prcdent, le programme appelant ne se met pas lcoute de la valeur de retour car, dans cet exemple, elle ne nous intresse pas. Rien nempche de la faire si tel est le besoin.

La page daccueil HomePage.xaml est galement une page tout fait classique.

154 Le guide du codeur

Les pages fonctions

<Page x:Class="HomePage" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <StackPanel> <Label> Ceci est la page principale </Label> </StackPanel> </Page>

Examinons maintenant la classe Page1. Page2 et Page3 sont construites sur le mme modle.
<PageFunction x:Class="Page1" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib" x:TypeArguments="sys:String" > <StackPanel> <Label> Ceci est la page 1 </Label> <Button Click="Retour"> Retour </Button> </StackPanel> </PageFunction>

Page1 est une page de type PageFunction construite de la mme manire

Rfrence au namespace System Notez la prsence dune rfrence au namespace System et lassembly mscorlib pour pouvoir dnir le type String comme argument.

Partial Public Class Page1 Inherits PageFunction(Of String) Public Sub New() InitializeComponent() End Sub Sub Retour(ByVal sender As Object, ByVal e As RoutedEventArgs) Dim retour As New ReturnEventArgs(Of String)("De Page1")

Le guide du codeur 155

Crer une application

OnReturn(retour) End Sub End Class

Le code .NET est galement extrmement simple. La seule chose noter est la prsence de OnReturn, dont nous avons vu prcdemment le fonctionnement. Lors du lancement du programme, la page daccueil est affiche.

b Figure 5-23 : Page daccueil

Si dans le menu vous choisissez Menu1, la page 1 est son tour affiche mais dans le Frame, laissant tout le contexte inchang.

b Figure 5-24 : Page 1

156 Le guide du codeur

Crer une application Windows navigable

Si vous cliquez sur Retour, la page daccueil est nouveau affiche.

Particularit de navigation Si au lieu de cliquer sur Retour vous demandez une autre page dans le menu, par exemple pour demander la page 3, celle-ci saffiche sans problme mais, dans le cas o vous cliquez ce moment sur Retour, cest non pas la page daccueil qui est affiche mais bien la page 1, page qui est en ralit la base de lappel de la PageFunction.

Si vous souhaitez que la page daccueil soit systmatiquement raffiche, il vous suffit de vous mettre lcoute de la valeur de retour, comme nous lavons fait dans le premier exemple ; et, dans la mthode qui traite le retour, vous pouvez imposer dafficher la page daccueil dans le Frame. Cette faon de travailler apporte normment de souplesse. Rien ne vous empche par exemple de travailler avec plusieurs Frame. Finalement, le modle en page peut facilement suivre un comportement semblable aux applications Windows classiques. Noubliez toutefois pas que lutilisateur peut galement utiliser la barre de navigation.

5.5 Crer une application Windows navigable


Il existe un troisime modle dapplication qui est un hybride entre les deux technologies vues ci-dessus. Il sagit dune application Windows classique dans le sens o elle est lance depuis le PC client, sexcute directement dans une fentre Windows et nest donc pas soumise aux contraintes scuritaires propres aux WBA. En revanche, il sagit dun modle applicatif par navigation entre des pages exactement comme les WBA. Ce modle est parfait si vous dsirez excuter une application la fois dans un browser et nativement dans Windows. Avec un minimum de modications, une application WBA devient une application Windows navigable. Voyons comment faire. Tout dabord, vous devez crer une nouvelle application WinFX. Ensuite, importez dans ce projet les pages de votre application WBA. Si nous reprenons les pages ralises dans lexemple du chapitre prcdent, nous devons donc avoir quatre chiers XAML : MyApp, Window1, Page1 et Page2. Il ne nous reste maintenant plus quune seule chose faire, remplacer le contenu de Window1.xaml par le code suivant :
Le guide du codeur 157

Crer une application

<NavigationWindow x:Class="Window1" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Ma premire application Windows en mode page" Source="Page1.xaml" />

b Figure 5-25 : Application navigable : premire page

b Figure 5-26 : Application navigable : deuxime page

Window1.xaml.vb Dans lexemple, ce chier est inutile et peut tre effac. Si vous dsirez le conserver, vous devrez modier lhritage de la classe pour y faire apparatre NavigationWindow en lieu et place de Window.

Lutilisation dune application WBA en tant quapplication Windows client nest pas la seule utilit de NavigationWindow. Cette faon de travailler est aussi trs utile pour raliser un assistant Wizard, par exemple. Il sagit non plus alors dune application complte faite sur ce modle mais uniquement dune partie
158 Le guide du codeur

Crer une application Windows navigable

de celle-ci. Le reste de lapplication tant classiquement compos de fentres de type Window simple. Voici un exemple extrmement simpli. Tout dabord, la fentre classique, qui fait appel lassistant via un bouton, mais cela peut tout aussi bien tre un menu.
<Window x:Class="ClassicWindow" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> <Label Name="lblTexte"> Fentre classique. </Label> <Button Name="btnWizard" Click="Wizard"> Wizard </Button> </StackPanel> </Window> Imports Imports Imports Imports Imports Imports Imports Imports System System.Windows System.Windows.Controls System.Windows.Data System.Windows.Documents System.Windows.Media System.Windows.Media.Imaging System.Windows.Shapes

Interaction logic for Window1.xaml Partial Public Class HelloWorld Inherits Window Public Sub New() InitializeComponent() End Sub Public Sub Wizard(ByVal sender As Object, ByVal e As RoutedEventArgs) Dim wiz As New Window1 wiz.ShowDialog() End Sub End Class

La mthode Wizard qui est associe lvnement Click du bouton instancie et affiche une fentre de type Window1. Comme vous pouvez le constater dans ce qui suit, Window1 est une fentre de type NavigationWindow.

Le guide du codeur 159

Crer une application

<NavigationWindow x:Class="Window1" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Mon premier wizard" Source="Page1.xaml" Width="280" Height="160" />

Page1 est automatiquement charg dans la fentre navigable.


<Page x:Class="Page1" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Page1" > <StackPanel> <RadioButton Name="radA" MaxWidth="50" Margin="5,5,5,5"> A. </RadioButton> <RadioButton Name="radB" MaxWidth="50" Margin="5,5,5,5"> B. </RadioButton> <WrapPanel HorizontalAlignment="Center"> <Button Width="80" Margin="5,5,5,5" Click="Prec" > Retour </Button> <Button Width="80" Margin="5,5,5,5" Click="Suiv" > Suivant </Button> </WrapPanel> </StackPanel> </Page> Imports Imports Imports Imports Imports Imports Imports Imports Imports System System.Windows System.Windows.Controls System.Windows.Data System.Windows.Documents System.Windows.Media System.Windows.Media.Imaging System.Windows.Navigation System.Windows.Shapes

160 Le guide du codeur

Crer une application Windows navigable

Interaction logic for Page1.xaml Partial Public Class Page1 Inherits Page Public Sub New() InitializeComponent() End Sub Public Sub Prec(ByVal sender As Object _ , ByVal e As RoutedEventArgs) Me.NavigationService.GoBack() End Sub Public Sub Suiv(ByVal sender As Object _ , ByVal e As RoutedEventArgs) If Me.radA.IsChecked Then Me.NavigationService.Navigate( _ New Uri("Page1A.xaml", UriKind.Relative)) Else Me.NavigationService.Navigate( _ New Uri("Page1B.xaml", UriKind.Relative)) End If End Sub End Class

b Figure 5-27 : Premire page du Wizard

Notez que le bouton Retour dclenche la mthode GoBack de la fentre de navigation tout comme si vous aviez appuy sur la che [Retour}Arrire]. Si nous choisissons loption A, la mthode nous fait naviguer vers la page Page1A.xaml.
<Page x:Class="Page1A" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Page1A" > <StackPanel>
Le guide du codeur 161

Crer une application

<RadioButton Name="rad1" MaxWidth="50" Margin="5,5,5,5"> 1. </RadioButton> <RadioButton Name="rad2" MaxWidth="50" Margin="5,5,5,5"> 2. </RadioButton> <WrapPanel HorizontalAlignment="Center"> <Button Width="80" Margin="5,5,5,5" Click="Prec"> Retour </Button> <Button Width="80" Margin="5,5,5,5" Click="Suiv"> Suivant </Button> </WrapPanel> </StackPanel> </Page> Imports Imports Imports Imports Imports Imports Imports Imports Imports System System.Windows System.Windows.Controls System.Windows.Data System.Windows.Documents System.Windows.Media System.Windows.Media.Imaging System.Windows.Navigation System.Windows.Shapes

Partial Public Class Page1A Inherits Page Public Sub New() InitializeComponent() End Sub Public Sub Prec(ByVal sender As Object _ , ByVal e As RoutedEventArgs) Me.NavigationService.GoBack() End Sub Public Sub Suiv(ByVal sender As Object _ , ByVal e As RoutedEventArgs) If Me.rad1.IsChecked Then Me.NavigationService.Navigate( _ New Uri("Page1A1.xaml", UriKind.Relative)) Else Me.NavigationService.Navigate( _
162 Le guide du codeur

Crer une application Windows navigable

New Uri("Page1A2.xaml", UriKind.Relative)) End If End Sub End Class

b Figure 5-28 : Deuxime page du Wizard

Cette fois, le choix 2 nous conduit vers une dernire page.


<Page x:Class="Page1A2" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Page1A2" > <StackPanel> <Label HorizontalContentAlignment="Center"> Le choix est temin. </Label> <WrapPanel HorizontalAlignment="Center"> <Button Width="80" Margin="5,5,5,5" Click="Prec"> Retour </Button> <Button Width="80" Margin="5,5,5,5" Click="Terminer"> Terminer </Button> </WrapPanel> </StackPanel> </Page> Imports Imports Imports Imports Imports Imports Imports Imports Imports System System.Windows System.Windows.Controls System.Windows.Data System.Windows.Documents System.Windows.Media System.Windows.Media.Imaging System.Windows.Navigation System.Windows.Shapes

Le guide du codeur 163

Crer une application

Interaction logic for Page1.xaml Partial Public Class Page1A2 Inherits Page Public Sub New() InitializeComponent() End Sub Public Sub Prec(ByVal sender As Object _ , ByVal e As RoutedEventArgs) Me.NavigationService.GoBack() End Sub Public Sub Terminer(ByVal sender As Object _ , ByVal e As RoutedEventArgs) DirectCast(Me.Parent, NavigationWindow).Close() End Sub End Class

b Figure 5-29 : Troisime page du Wizard

Pour fermer la fentre, il est ncessaire de convertir la proprit Parent en une NavigationWindow que nous savons quelle est. Si nous demandons le retour en arrire, les ches avant et arrire deviennent accessibles.

b Figure 5-30 : Retour la deuxime page du Wizard

164 Le guide du codeur

Les applications avec WPF/E

Boutons de navigation La fentre ne rend accessibles les boutons de navigation que si la navigation dans ce sens est possible. Vous pouvez galement connatre cette information en utilisant les proprits CanGoBack et CanGoForward.

5.6 Les applications avec WPF/E


WPF/E, abrviation pour Windows Presentation Fundation for Everywhere, a pour but comme son nom lindique de pouvoir excuter des applications WPF sur toutes les plates-formes. Les informations disponibles sur ce sujet sont encore trs fragmentaires. Toutefois, on peut dores et dj dire que ces applications vont gnralement tre excutes dans un browser. Toutefois, il ne faut pas confondre application WBA et application WPF/E. En effet, en dehors des contraintes de scurit, les WBA disposent de toute la puissance de WPF alors que WPF/E ne sera quun sous-ensemble de WPF. Alors, pourquoi WPF/E ? WPF/E pourra sexcuter sur des plates-formes o WPF nest pas install. En fait, WPF/E, linstar de Flash, sera install sur le poste client comme un Add-in du browser. Cet Add-in ne devrait pas peser plus de deux mga-octets. Cest pourquoi une partie du potentiel de WPF doit tre amput. Si, actuellement, il nest pas encore possible de savoir exactement ce qui sera exactement inclus, il est en revanche dj acquis que la 3D ne sera pas prsente. En ce qui concerne la syntaxe XAML, pas de soucis, elle est identique mais bien sr limite aux fonctionnalits prsentes. WPF/E sera disponible pour Internet Explorer, Mozilla, Firefox, Opera et Safari. Au niveau du systme dexploitation, Windows ( partir de 2000) sera bien sr support ainsi que Mac OS X 10. Pour Linux et Solaris, lespoir demeure mais sans aucune certitude. Il en est de mme pour les anciennes versions de Windows (Windows 95, 98 et Me). Des versions pour les PC de poche et autres tlphones portables utilisant les systmes Windows sont galement prvues. Normalement, une premire prversion doit voir le jour dans le courant du troisime trimestre 2006 alors que la version dnitive est attendue pour le premier semestre 2006. En ce qui concerne les units lgres, il faudra attendre le second semestre 2007.

Le guide du codeur 165

Crer une application

m Figure 5-31 : Architecture de WPF/E

Comme vous pouvez le constater, XAML pourra interagir avec le JavaScript mais galement excuter du code intermdiaire (compil) .NET. Ce dernier pourra tre excut directement par lAdd-in. Le code XAML pourra tre intgr la page HTML ou utilis comme une ressource externe. Voici tout dabord comment devrait se prsenter une page avec une application WPF/E en ressource externe.
<html> <body> <object id="wpfehost" size=""> <param name=source value=monAppliction.wpfe/> </body> </html>

Lapplication WPF/E contiendra le XAML compress (baml) mais aussi le code IL (.NET compil) et les ressources (images, mdia...). Maintenant, voyons comment devrait se prsenter une application WPF/E intgre la page HTML.
<html> <head> <!Script XAML--> <script id="monScriptXaml" type="text/xaml"> <? Xml version="1.0" ?>

166 Le guide du codeur

Checklist

<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> ... </Canvas> </script> </head> <body> ... <object id="wpfe" classid="..." codebase="xcpctrl.cab#version=0,0,3,0" height="300" width="400"> <param name="SourceElement" value="monScriptXaml"/> <param name="WindowslessMode" value="True"/> <param name="BackgroundColor value="#00000000"/> </object> ... </body> </html>

Comme vous lavez vu dans le diagramme darchitecture, vous pouvez manipuler des objets WPF/E depuis le code JavaScript. Voici en quelques lignes comment faire.
<script type="text/javascript"> void Fuction maFonction() { var wpfeObject = document.getElementById("wpfe") ; var ctrl = wpfeObject.FindName("LeNomDeMonControleDansXAML") ; ctrl.SetValue("NomDeLaProprit", valeur) ; } </script>

Vous pouvez par ce moyen crer des pages qui utilisent la fois le HTML, le JavaScript et WPF/E au travers de XAML et si ncessaire de code .NET. Ces technologies peuvent non seulement cohabiter mais galement interagir.

5.7 Checklist
Dans ce chapitre essentiellement dirig sur la gestion dune application, nous avons vu :
j j

comment est compose une application Windows et comment la raliser ; comment raliser une application laquelle on accdera depuis un navigateur web (application WBA) ; comment utiliser PageFunction ;
Le guide du codeur 167

Crer une application

j j j

j j j

comment raliser une page matre pour naviguer dans lapplication ; comment grer la scurit pour les applications WBA ; comment transformer simplement une application WBA en application Windows ; comment raliser un assistant (Wizard) ; comment grer les vnements dans XAML ; les bases du futur modle dapplication WPF/E.

168 Le guide du codeur

Ch apit re

6 Les menus

Crer un menu .......................................... Crer un menu contextuel ........................... Crer une barre doutils .............................. Checklist ..................................................

170 178 183 189

Les menus

6.1 Crer un menu


Le menu principal
Traditionnellement, le menu principal se prsente horizontalement en haut de fentre sur un fond gris clair. Pour crer notre menu, nous allons utiliser les classes Menu et MenuItem. La proprit VerticalAlignment va nous permettre de placer le menu sous la barre de titre comme souhait.
<Window x:Class="AvalonMenu.Window1" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Les menus avec Avalon"> <Menu VerticalAlignment="Top" Height="20"> <MenuItem Header="Fichier"/> <MenuItem Header="Edition"/> <MenuItem Header="Aide"/> </Menu> </Window>

Hauteur du menu La proprit Height est obligatoire sinon le menu occupera toute la hauteur disponible dans notre fentre.

b Figure 6-1 : Le menu principal

Dans lexemple prcdent, la fentre principale ne pourra contenir que le menu. Cest toutefois le cas de beaucoup dapplications et essentiellement des applications MDI. Si tel nest pas votre objectif, la solution est simple et dj connue. Il nous suffit de placer le menu dans un conteneur tel quune grille, un StackPanel ou encore un DockPanel.
170 Le guide du codeur

Crer un menu

<Window xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Les menus avec XAML" > <DockPanel> <Menu VerticalAlignment="Top" Height="20" DockPanel.Dock="Top"> <MenuItem Header="Fichier"/> <MenuItem Header="Edition"/> <MenuItem Header="Aide"/> </Menu> </DockPanel> </Window>

Le rsultat sera identique, la diffrence prs quil est maintenant possible de placer dautres contrles ou dautres conteneurs dans la fentre.

Les sous-menus
Pour crer un sous-menu, un menu vertical, il suffit de dnir un ou des MenuItem dans le nud MenuItem du menu principal. Chaque nouveau MenuItem peut son tour contenir dautres MenuItem ls.
<Window xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Les menus avec XAML" > <DockPanel> <Menu VerticalAlignment="Top" Height="20" DockPanel.Dock="Top"> <MenuItem Header="Fichier"> <MenuItem Header="Ouvrir"/> <MenuItem Header="Fermer"/> </MenuItem> <MenuItem Header="Edition"> <MenuItem Header="Copier"/> <MenuItem Header="Coller"/> <Separator /> <MenuItem Header="Livre"> <MenuItem Header="Prcdent"/> <MenuItem Header="Suivant"/> </MenuItem> </MenuItem> <MenuItem Header="Aide"/> </Menu>
Le guide du codeur 171

Les menus

</DockPanel> </Window>

b Figure 6-2 : Les sous-menus

Placer des sparations dans le menu Notez lutilisation de la balise Separator pour crer un sparateur.

Rendre un lment du menu inactif


Pour rendre un lment dun menu inactif (gris), vous devez assigner la valeur False lattribut IsEnabled.
<MenuItem Header="Fichier"> <MenuItem Header="Ouvrir"/> <MenuItem Header="Fermer" IsEnabled="False"/> </MenuItem>

b Figure 6-3 : Les sous-menus

172 Le guide du codeur

Crer un menu

Cocher un lment du menu


Pour cocher un lment dun menu, utilisez la proprit IsChecked. Si elle est True, llment du menu correspondant sera coch.
<MenuItem Header="Aide"> <MenuItem Header="En ligne" IsChecked="True"/> </MenuItem>

b Figure 6-4 : Les sous-menus

Associer une action un menu


Pour associer une mthode au clic sur un lment du menu, il suffit dassigner le nom de la mthode lattribut Click de llment correspondant. Reprenons lexemple prcdent complet et adaptons-le pour rendre le menu Fermer disponible quand on clique sur Ouvrir et rendre en revanche ce dernier indisponible. Nous ferons linverse avec Fermer. Dans le mme ordre dide, nous supprimerons ou activerons la coche lors du clic sur le menu en ligne.

Raliser soi-mme lexemple Si vous souhaitez reproduire cet exemple, vous devrez crer un projet dans Visual Studio.

Le code XAML devient :


<Window x:Class="Window1" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Les menus avec XAML" > <DockPanel>

Le guide du codeur 173

Les menus

<Menu VerticalAlignment="Top" Height="20" DockPanel.Dock="Top"> <MenuItem Header="Fichier"> <MenuItem Name="mnuOuvrir" Header="Ouvrir" Click="Click_Ouvrir"/> <MenuItem Name="mnuFermer" Header="Fermer" IsEnabled="False" Click="Click_Fermer"/> </MenuItem> <MenuItem Header="Edition"> <MenuItem Header="Copier"/> <MenuItem Header="Coller"/> <Separator /> <MenuItem Header="Livre"> <MenuItem Header="Prcdent"/> <MenuItem Header="Suivant"/> </MenuItem> </MenuItem> <MenuItem Header="Aide"> <MenuItem Name="mnuEnLigne" Header="En ligne" IsChecked="True" Click="Click_EnLigne"/> </MenuItem> </Menu> </DockPanel> </Window>

Importance des noms Jusqu maintenant, dans les menus, je navais pas pris la peine de donner des noms. Comme vous pouvez le constater, cela se rvle rapidement ncessaire.

Les mthodes qui seront appeles lors des vnements Click respectifs sont dnies dans le code VB.NET associ.
Imports Imports Imports Imports Imports Imports Imports Imports System System.Windows System.Windows.Controls System.Windows.Data System.Windows.Documents System.Windows.Media System.Windows.Media.Imaging System.Windows.Shapes

Interaction logic for Window1.xaml Partial Public Class Window1 Inherits Window

174 Le guide du codeur

Crer un menu

Public Sub New() InitializeComponent() End Sub Public Sub Click_Ouvrir(ByVal sender As Object _ , ByVal e As RoutedEventArgs) Me.mnuFermer.IsEnabled = True Me.mnuOuvrir.IsEnabled = False End Sub Public Sub Click_Fermer(ByVal sender As Object _ , ByVal e As RoutedEventArgs) Me.mnuFermer.IsEnabled = False Me.mnuOuvrir.IsEnabled = True End Sub Public Sub Click_EnLigne(ByVal sender As Object _ , ByVal e As RoutedEventArgs) Me.mnuEnLigne.IsChecked = _ Not Me.mnuEnLigne.IsChecked End Sub End Class

La syntaxe dcriture des mthodes appeles par les vnements est tout fait conforme ce que nous avons vu dans le chapitre rserv ce sujet.

Problme avec lIntelliSense Actuellement, lIntelliSense ne reconnat pas directement les noms que nous avons ajouts. Recompilez votre projet et ceux-ci apparatront.

Pour changer notre menu, nous devons simplement modier les proprits IsChecked et IsEnabled qui correspondent aux attributs du mme nom.

Inverser une valeur Nous ne devons pas connatre ltat de IsChecked pour cocher ou dcocher llment En ligne du menu. Il suffit dinverser la valeur pour obtenir le rsultat souhait, ce qui se fait simplement en rassignant la valeur elle-mme et en la prcdant de Not.

Le guide du codeur 175

Les menus

Rendre le menu dynamique


Plutt quactiver ou dsactiver certaines options du menu, vous souhaiterez certainement rendre ce menu dynamique en fonction des vnements dclenchs. Par exemple, le menu Edition est superu si le chier na pas t ouvert. Pour pouvoir accder toutes les fonctionnalits dun menu depuis le code .NET, il suffit de manipuler lobjet de la classe Menu, qui est forcment instanci. Pour y accder facilement, il doit tre nomm et, oups, nous ne lavons pas fait ! Rparons vite cet oubli.
<Window x:Class="Window1" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Les menus avec XAML" > <DockPanel> <Menu Name="mnuMain" VerticalAlignment="Top" Height="20" DockPanel.Dock="Top"> <MenuItem Name="mnuFichier" Header="Fichier"> <MenuItem Name="mnuOuvrir" Header="Ouvrir" Click="Click_Ouvrir"/> <MenuItem Name="mnuFermer" Header="Fermer" IsEnabled="False" Click="Click_Fermer"/> </MenuItem> <MenuItem Name="mnuEdition" Header="Edition" Visibility="Collapsed"> <MenuItem Name="mnuCopier" Header="Copier"/> <MenuItem Name="mnuColler" Header="Coller"/> <Separator /> <MenuItem Name="mnuLivre" Header="Livre"> <MenuItem Name="mnuPrec" Header="Prcdent"/> <MenuItem Name="mnuSuiv" Header="Suivant"/> </MenuItem> </MenuItem> <MenuItem Header="Aide"> <MenuItem Name="mnuEnLigne" Header="En ligne" IsChecked="True" Click="Click_EnLigne"/> </MenuItem> </Menu> </DockPanel> </Window>

Comme vous pouvez le constater, tous les lments du menu sont maintenant nomms, ce qui nous permettra daccder nimporte lequel des lments. Un autre attribut important a galement t ajout. Lattribut Visibility permet de cacher ou dafficher un lment. Il peut prendre trois valeurs diffrentes.

176 Le guide du codeur

Crer un menu

j j j

visible : llment est affich. hidden : llment nest pas affich mais sa place est rserve. collapsed : llment nest pas affich et sa place nest pas rserve, ce qui provoque un dplacement des autres lments du menu.

Pour des raisons videntes, utilisez Collapsed plutt que Hidden.


Imports Imports Imports Imports Imports Imports Imports Imports System System.Windows System.Windows.Controls System.Windows.Data System.Windows.Documents System.Windows.Media System.Windows.Media.Imaging System.Windows.Shapes

Interaction logic for Window1.xaml Partial Public Class Window1 Inherits Window Public Sub New() InitializeComponent() End Sub Public Sub Click_Ouvrir(ByVal sender As Object _ , ByVal e As RoutedEventArgs) Me.mnuFermer.IsEnabled = True Me.mnuOuvrir.IsEnabled = False Me.mnuEdition.Visibility = Windows.Visibility.Visible End Sub Public Sub Click_Fermer(ByVal sender As Object _ , ByVal e As RoutedEventArgs) Me.mnuFermer.IsEnabled = False Me.mnuOuvrir.IsEnabled = True Me.mnuEdition.Visibility = _ Windows.Visibility.Collapsed End Sub Public Sub Click_EnLigne(ByVal sender As Object _ , ByVal e As RoutedEventArgs) Me.mnuEnLigne.IsChecked = Not Me.mnuEnLigne.IsChecked End Sub End Class

Lcran au dmarrage se prsente comme ceci.

Le guide du codeur 177

Les menus

b Figure 6-5 : Menu dynamique

Mais, aprs avoir cliqu sur Ouvrir, le menu Edition est ajout.

b Figure 6-6 : Menu dynamique

Grce lutilisation de la proprit Visibility, le code .NET est Cela ncessite de penser compltement le menu dans le module vous tes amen ajouter un menu de manire totalement cest--dire sans quil soit prvu initialement, vous devrez le faire au moyen de code .NET.

trs simple. de base. Si dynamique, uniquement

6.2 Crer un menu contextuel


Comme son nom lindique, le menu contextuel est destin offrir un menu spcique llment auquel il est attach. Laccs ce menu se fait grce au clic droit de la souris. Il est de plus en plus couramment utilis dans toutes les applications et plus seulement les applications professionnelles. Dautant que sa programmation est en dnitive relativement aise. Pour illustrer le menu contextuel, nous allons associer lexemple prcdent avec lexemple repris dans le paragraphe sur le Canvas. Le menu contextuel est associ au Canvas.
<Window x:Class="Window1" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
178 Le guide du codeur

Crer un menu contextuel

Title="Les menus avec XAML" > <DockPanel> <Menu Name="mnuMain" VerticalAlignment="Top" Height="20" DockPanel.Dock="Top"> <MenuItem Name="mnuFichier" Header="Fichier"> <MenuItem Name="mnuOuvrir" Header="Ouvrir" Click="Click_Ouvrir"/> <MenuItem Name="mnuFermer" Header="Fermer" IsEnabled="False" Click="Click_Fermer"/> </MenuItem> <MenuItem Name="mnuEdition" Header="Edition" Visibility="Collapsed"> <MenuItem Name="mnuCopier" Header="Copier"/> <MenuItem Name="mnuColler" Header="Coller"/> <Separator /> <MenuItem Name="mnuLivre" Header="Livre"> <MenuItem Name="mnuPrec" Header="Prcdent" Click="Click_Prev"/> <MenuItem Name="mnuSuiv" Header="Suivant" Click="Click_Next"/> </MenuItem> </MenuItem> <MenuItem Header="Aide"> <MenuItem Name="mnuEnLigne" Header="En ligne" IsChecked="True" Click="Click_EnLigne"/> </MenuItem> </Menu> <Canvas Name="frmData" IsEnabled="False" Background="LightBlue" DockPanel.Dock="Bottom"> <Canvas.ContextMenu> <ContextMenu> <MenuItem Header="Prcdent" Click="Click_Prev"/> <MenuItem Header="Suivant" Click="Click_Next"/> </ContextMenu> </Canvas.ContextMenu> <Label Name="lblNom" Canvas.Top="10" Canvas.Left="10"> Nom </Label> <TextBox Name="txtNom" Canvas.Top="10" Canvas.Left="80" Width="150" MaxLength="30" CharacterCasing="Upper" /> <Label Name="lblPrenom" Canvas.Top="10" Canvas.Left="240"> Prnom
Le guide du codeur 179

Les menus

</Label> <TextBox Name="txtPrenom" Canvas.Top="10" Canvas.Left="300" Width="130" MaxLength="30"/> <Label Name="lblAdr" Canvas.Top="40" Canvas.Left="10"> Rue </Label> <TextBox Name="txtAdr" Canvas.Top="40" Canvas.Left="80" Width="350" MaxLength="80"/> <Label Name="lblCP" Canvas.Top="70" Canvas.Left="10"> Code postal </Label> <TextBox Name="txtCP" Canvas.Top="70" Canvas.Left="80" Width="50" MaxLength="5"/> <Label Name="lblLocalite" Canvas.Top="70" Canvas.Left="150"> Localit </Label> <TextBox Name="txtLocalite" Canvas.Top="70" Canvas.Left="200" Width="230" MaxLength="50"/> <Border Width="100" Height="120" BorderThickness="1" Background="White" BorderBrush="Black" Canvas.Top="10" Canvas.Right="10"> <TextBlock Name="blkPhoto" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="20"> Photo </TextBlock> </Border> <Label Name="lblCopyright" Canvas.Bottom="10" Canvas.Right="10" Content="Micro Application 2006" /> </Canvas> </DockPanel> </Window>

Le code VB.NET associ est modi comme ceci.


Interaction logic for Window1.xaml Partial Public Class Window1 Inherits Window Public Sub New() InitializeComponent() End Sub

180 Le guide du codeur

Crer un menu contextuel

Public Sub Click_Ouvrir(ByVal sender As Object _ , ByVal e As RoutedEventArgs) Me.mnuFermer.IsEnabled = True Me.mnuOuvrir.IsEnabled = False Me.mnuEdition.Visibility = Windows.Visibility.Visible Me.frmData.IsEnabled = True End Sub Public Sub Click_Fermer(ByVal sender As Object _ , ByVal e As RoutedEventArgs) Me.mnuFermer.IsEnabled = False Me.mnuOuvrir.IsEnabled = True Me.mnuEdition.Visibility = Windows.Visibility.Collapsed Me.frmData.IsEnabled = False End Sub Public Sub Click_EnLigne(ByVal sender As Object _ , ByVal e As RoutedEventArgs) Me.mnuEnLigne.IsChecked = Not Me.mnuEnLigne.IsChecked End Sub Public Sub Click_Prev(ByVal sender As Object _ , ByVal e As RoutedEventArgs) Code pour prcedent End Sub Public Sub Click_Next(ByVal sender As Object _ , ByVal e As RoutedEventArgs) Code pour suivant End Sub End Class

m Figure 6-7 : Le menu contextuel dans un environnement inactif

Le guide du codeur 181

Les menus

Si vous essayez dactiver le menu contextuel, rien ne se passe. Le menu nest pas accessible car le canevas est dsactiv. Lactivation du canevas est ralise dans la mthode Click_Ouvrir. Aprs avoir effectu Fichier, Ouvrir, le menu contextuel est maintenant actif.

m Figure 6-8 : Le menu contextuel

Toutefois, les botes de texte conservent leur menu contextuel par dfaut.

m Figure 6-9 : Le menu contextuel par dfaut

Si vous dsirez les remplacer, il faudra crer un autre menu contextuel. Remplacez le premier TextBox par celui-ci et il possdera son propre menu contextuel. videmment, dans lexemple, il est trs simpli. Aucune action ne lui est associe mais cela, vous savez dj comment le rsoudre.
<TextBox Name="txtNom" Canvas.Top="10" Canvas.Left="80" Width="150" MaxLength="30" CharacterCasing="Upper"> <TextBox.ContextMenu> <ContextMenu> <MenuItem Header="Copier"/> <MenuItem Header="Coller"/> </ContextMenu> </TextBox.ContextMenu> </TextBox>

182 Le guide du codeur

Crer une barre doutils

b Figure 6-10 : Un menu contextuel dans une bote de texte

Vous trouverez page 132 comment partager un menu contextuel entre


Renvoi plusieurs lments de lcran.

6.3 Crer une barre doutils


Une barre doutils statique
La barre doutils est cre grce un objet de la classe ToolBar. Pour placer les lments dans la barre doutils, il ny a qu ajouter au sein du nud ToolBar les contrles que vous souhaitez voir apparatre. Gnralement, une barre doutils est principalement compose de boutons. En ajoutant le code suivant derrire la balise fermante Menu de notre exemple prcdent, nous obtiendrons directement une barre doutils tout fait fonctionnelle.
<ToolBar DockPanel.Dock="Top" Height="24"> <Button ToolTip="Ouvrir" Click="Click_Ouvrir"> <Image> <Image.Source> <Binding Source="open.bmp"/> </Image.Source> </Image> </Button> <Button ToolTip="Fermer" Click="Click_Fermer"> <Image> <Image.Source> <Binding Source="close.bmp"/> </Image.Source> </Image> </Button> <Button ToolTip="Precedent" Click="Click_Prev"> <Image> <Image.Source> <Binding Source="precedent.bmp"/> </Image.Source> </Image> </Button> <Button ToolTip="Suivant" Click="Click_Next"> <Image> <Image.Source> <Binding Source="suivant.bmp"/>
Le guide du codeur 183

Les menus

</Image.Source> </Image> </Button> </ToolBar>

m Figure 6-11 : Une simple barre doutils

Positionnement de la barre doutils Nous avons ici utilis un DockPanel pour placer la barre doutils et le menu, mais nous aurions tout aussi bien pu utiliser une grille, un StackPanel ou mme un WrapPanel. Le canevas est quant lui moins appropri, mais pourquoi pas !

La barre doutils peut contenir dautres contrles que le bouton. Par exemple une ComboBox.
<ToolBar DockPanel.Dock="Top" Height="24"> <Button ToolTip="Ouvrir" Click="Click_Ouvrir"> <Image> <Image.Source> <Binding Source="open.bmp"/> </Image.Source> </Image> </Button> <Button ToolTip="Fermer" Click="Click_Fermer"> <Image> <Image.Source> <Binding Source="close.bmp"/> </Image.Source> </Image> </Button> <Button ToolTip="Precedent"> <Image> <Image.Source>

184 Le guide du codeur

Crer une barre doutils

<Binding Source="precedent.bmp"/> </Image.Source> </Image> </Button> <Button ToolTip="Suivant"> <Image> <Image.Source> <Binding Source="suivant.bmp"/> </Image.Source> </Image> </Button> <Separator/> <ComboBox Width="80"> <ComboBoxItem IsSelected="True"> Par nom </ComboBoxItem> <ComboBoxItem> Par localit </ComboBoxItem> </ComboBox> </ToolBar>

m Figure 6-12 : Barre doutils avec ComboBox

Sparateur La ComboBox est prcde dun sparateur. Il ne sagit absolument pas dune obligation. Vous pouvez placer des sparateurs o bon vous semble simplement en y plaant la balise Separator comme dans le code ci-dessus.

Un ensemble de barres doutils


Les applications modernes ne se contentent pas dafficher une seule barre doutils mais affichent bien un ensemble dans lequel vous pouvez dplacer ou
Le guide du codeur 185

Les menus

redimensionner votre guise les diffrentes barres doutils. Avec XAML, nous pouvons crer un conteneur dans lequel nous allons placer nos barres doutils. Elles pourront tre alors dplaces ou redimensionnes par lutilisateur dans lespace dtermin par le conteneur. Si lutilisateur rduit trop la taille dune barre doutils, les lments qui ne sont plus affichables sont automatiquement ajouts dans une zone de dpassement et rendus accessibles via la petite che qui marque la n de la barre doutils. Pour crer un conteneur, vous devez utiliser la balise ToolBarTray.
<ToolBarTray DockPanel.Dock="Top" IsLocked="False" Background="LightGray"> <ToolBar Band="0" Height="24"> <Button ToolTip="Ouvrir" Click="Click_Ouvrir"> <Image> <Image.Source> <Binding Source="open.bmp"/> </Image.Source> </Image> </Button> <Button ToolTip="Fermer" Click="Click_Fermer"> <Image> <Image.Source> <Binding Source="close.bmp"/> </Image.Source> </Image> </Button> <Button ToolTip="Precedent"> <Image> <Image.Source> <Binding Source="precedent.bmp"/> </Image.Source> </Image> </Button> <Button ToolTip="Suivant"> <Image> <Image.Source> <Binding Source="suivant.bmp"/> </Image.Source> </Image> </Button> </ToolBar> <ToolBar Band="1" Height="24"> <ComboBox Width="80"> <ComboBoxItem IsSelected="True"> Par nom </ComboBoxItem> <ComboBoxItem> Par localit

186 Le guide du codeur

Crer une barre doutils

</ComboBoxItem> </ComboBox> </ToolBar> </ToolBarTray>

Vous pouvez constater que la barre doutils prcdemment cre a t scinde en deux au niveau du sparateur. Cest maintenant la ToolBarTray qui reoit lattribut DockPanel.Dock. Pour viter un fond blanc, lattribut Background reoit la valeur LightGray. Lattribut Band dans la balise ToolBar permet de xer le numro de ligne dans lequel vous dsirez voir apparatre la barre doutils.

b Figure 6-13 : Des barres doutils mobiles

Lutilisateur peut dplacer les barres doutils, soit pour les rassembler sur une mme ligne, soit pour les inverser. Il ne pourra en revanche pas les dcaler vers la gauche en laissant un espace entre les barres doutils.

b Figure 6-14 : Des barres doutils mobiles

Bloquer les barres doutils La proprit IsLocked permet de spcier si les barres doutils contenues sont mobiles ou non. Il est possible de le spcier individuellement pour chaque barre en introduisant dans la balise de la barre concerne lattribut ToolBarTray.IsLocked.

Si vous souhaitez afficher la barre doutils gauche plutt quen haut de lcran, cest trs simple. Vous changez lattribut Orientation et cest pratiquement tout.
<ToolBarTray DockPanel.Dock="Left" IsLocked="False" Background="LightGray" Orientation="Vertical">
Le guide du codeur 187

Les menus

En effet, il est galement judicieux de changer le docking, sans quoi le rsultat ne sera pas celui espr.
Ordre des lignes Vu le changement dorientation, les lignes dnies par lattribut Band deviennent des colonnes. Cest pourquoi il est prfrable dans notre exemple de xer la valeur 0 pour les deux barres doutils.

<ToolBar Band="0">

Hauteur des lignes Pour les mmes raisons, la hauteur qui tait xe 24 points doit tre adapte pour par exemple devenir automatique. Pour y arriver, retirez lattribut Height de chaque balise ToolBar.

b Figure 6-15 : Des barres doutils gauche

Avec ces barres doutils ottantes, nous devons nous pencher dun peu plus prs sur la zone de dbordement. Si vous rduisez la taille de la premire barre doutils en montant la seconde, la zone de dbordement indique par la che maintenant noire et non plus grise est active. Malheureusement, si vous tentez de lutiliser, licne cache va bel et bien safficher mais en trs grand. Pour viter ce problme, il est prudent dutiliser les attributs MaxWidth et MaxHeigth des images des diffrents boutons. Les autres contrles ventuels doivent subir le mme traitement.
<Image MaxHeight="24" MaxWidth="24">

188 Le guide du codeur

Checklist

b Figure 6-16 : Zone de dbordement de la barre doutils

Si vous souhaitez changer lordre des barres doutils sans dplacer tout le code, vous pouvez simplement utiliser lattribut BandIndex. Dans lexemple, assignez 1 cet attribut pour la premire barre doutils.
ToolBar Band="0" BandIndex="1">

b Figure 6-17 : Ordre des barres doutils

Numrotation Pour rappel, la numrotation commence 0.

6.4 Checklist
Dans ce chapitre, nous avons vu comment crer et manipuler les menus et particulirement comment :
j j j j

crer un menu dapplication complet avec sous-menu et menus imbriqus ; rendre un menu dynamique ; crer un menu contextuel ; crer et manipuler une barre doutils.
Le guide du codeur 189

Ch apit re

7 Lier les donnes son interface utilisateur


Lier les donnes un DataSet .................... Lier les donnes un objet mtier ................ Lier les donnes sans utiliser le code .NET .... Checklist .................................................. 192 203 207 218

Lier les donnes son interface utilisateur

Outre la possibilit dassigner vous-mme les valeurs aux diffrents contrles, vous aurez certainement envie de mettre en place des techniques comme la liaison aux donnes (Data Binding) pour lier vos contrles avec les donnes qui doivent y tre reprises. Cette technique nest pas neuve mais nous allons voir comment la mettre en uvre avec XAML.

7.1 Lier les donnes un DataSet


Tout dabord, nous devons disposer dun DataSet. Pour que vous puissiez raliser vous-mme lexercice sans devoir installer un gestionnaire de bases de donnes quelconque, le choix de raliser un DataSet vers une base de donnes MS-Access dont vous pouvez voir la structure dans lcran ci-dessous semble le plus judicieux.

b Figure 7-1 : Structure de la table

Une fois la base de donnes cre, nous devons lajouter notre projet. Choisissez dans le menu de Visual Studio Donnes - Ajouter une nouvelle
source de donnes

m Figure 7-2 : Ajouter une source de donnes

192 Le guide du codeur

Lier les donnes un DataSet

Si ce nest dj fait, choisissez loption Base de donnes et cliquez sur Suivant. Cliquez sur le bouton Nouvelle connexion et ensuite sur le bouton Modier.

m Figure 7-3 : Modier le type de base de donnes

Cliquez maintenant sur le bouton Parcourir, choisissez la base de donnes que vous venez de crer et cliquez sur OK puis sur Suivant.

m Figure 7-4 : Contenu inclure dans le DataSet

Slectionnez la table inclure dans le DataSet.

b Figure 7-5 : Un DataSet fortement typ

Le guide du codeur 193

Lier les donnes son interface utilisateur

Le DataSet est maintenant cr. Il ne nous reste qu linclure dans notre programme. Modiez le code de Window1.xaml.vb pour reter le code ci-dessous.
Private m_data As New DBXAMLDataSet Private m_i As Integer Public Sub New() InitializeComponent() Dim adapter As New _ DBXAMLDataSetTableAdapters.Carnet_adressesTableAdapter adapter.Fill(m_data.Carnet_adresses) End Sub

Une fois cette tape ralise, nous devons maintenant associer le DataSet notre fentre. Commenons par ajouter la gestion de lvnement Loaded de la fentre.
<Window x:Class="Window1" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Les menus avec XAML" Loaded="Win_loaded" >

La mthode Win_loaded est appele aprs le chargement de la fentre. Dans cette mthode, nous allons initialiser la source de donnes.
Private Sub Win_loaded(ByVal sender As Object _ , ByVal e As RoutedEventArgs) m_i = 0 Me.DataContext = m_data.Carnet_adresses.Rows(m_i) End Sub

La liaison se fait en utilisant la proprit DataContext de la fentre.

Liaison une ligne de la table En ralit, nous ne lions pas le DataSet dans son ensemble notre cran mais lions seulement une ligne dune table. En loccurrence, la premire ligne de la table Carnet adresses.

Il reste maintenant lier les champs avec les zones cran. Commenons par le nom.
194 Le guide du codeur

Lier les donnes un DataSet

<TextBox Name="txtNom" Canvas.Top="10" Canvas.Left="80" Width="150" MaxLength="30" CharacterCasing="Upper" Text ="{Binding Path=Nom}">

Pour raliser la liaison, nous devons utiliser un objet de type Binding. Lobjet doit tre assign la proprit, qui doit tre lie. Pour y arriver, nous avons utilis une syntaxe un peu particulire. Nous pouvons dj excuter lapplication telle quelle.

m Figure 7-6 : Premire liaison

Le nom est correctement affich lcran. Faisons de mme avec les autres champs. Pour vous aider reconstruire lexemple, vous trouverez ci-dessous le code complet que nous avons dj discut prcdemment.
<Window x:Class="Window1" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Les menus avec XAML" Loaded="Win_loaded" > <DockPanel> <Menu Name="mnuMain" VerticalAlignment="Top" Height="20" DockPanel.Dock="Top"> <MenuItem Name="mnuFichier" Header="Fichier"> <MenuItem Name="mnuOuvrir" Header="Ouvrir" Click="Click_Ouvrir"/> <MenuItem Name="mnuFermer" Header="Fermer" IsEnabled="False" Click="Click_Fermer"/> </MenuItem> <MenuItem Name="mnuEdition" Header="Edition" Visibility="Collapsed">
Le guide du codeur 195

Lier les donnes son interface utilisateur

<MenuItem Name="mnuCopier" Header="Copier"/> <MenuItem Name="mnuColler" Header="Coller"/> <Separator /> <MenuItem Name="mnuContact" Header="Contact"> <MenuItem Name="mnuPrec" Header="Prcdent" Click="Click_Prev"/> <MenuItem Name="mnuSuiv" Header="Suivant" Click="Click_Next"/> </MenuItem> </MenuItem> <MenuItem Header="Aide"> <MenuItem Name="mnuEnLigne" Header="En ligne" IsChecked="True" Click="Click_EnLigne"/> </MenuItem> </Menu> <ToolBarTray DockPanel.Dock="Left" IsLocked="False" Background="LightGray" Orientation="Vertical"> <ToolBar Band="0"> <Button ToolTip="Ouvrir" Click="Click_Ouvrir"> <Image MaxHeight="24" MaxWidth="24"> <Image.Source> <Binding Source="open.bmp"/> </Image.Source> </Image> </Button> <Button ToolTip="Fermer" Click="Click_Fermer"> <Image MaxHeight="24" MaxWidth="24"> <Image.Source> <Binding Source="close.bmp"/> </Image.Source> </Image> </Button> <Button ToolTip="Precedent" Click="Click_Prev"> <Image MaxHeight="24" MaxWidth="24"> <Image.Source> <Binding Source="precedent.bmp"/> </Image.Source> </Image> </Button> <Button ToolTip="Suivant" Click="Click_Next"> <Image MaxHeight="24" MaxWidth="24"> <Image.Source> <Binding Source=" suivant.bmp"/> </Image.Source> </Image> </Button> </ToolBar> <ToolBar Band="0">
196 Le guide du codeur

Lier les donnes un DataSet

<ComboBox Width="80"> <ComboBoxItem IsSelected="True"> Par nom </ComboBoxItem> <ComboBoxItem> Par localit </ComboBoxItem> </ComboBox> </ToolBar> </ToolBarTray> <Canvas Name="frmData" IsEnabled="False" Background="LightBlue" DockPanel.Dock="Bottom"> <Canvas.ContextMenu> <ContextMenu> <MenuItem Header="Prcdent" Click="Click_Prev"/> <MenuItem Header="Suivant" Click="Click_Next"/> </ContextMenu> </Canvas.ContextMenu> <Label Name="lblNom" Canvas.Top="10" Canvas.Left="10"> Nom </Label> <TextBox Name="txtNom" Canvas.Top="10" Canvas.Left="80" Width="150" MaxLength="30" CharacterCasing="Upper" Text ="{Binding Path=Nom}"> <TextBox.ContextMenu> <ContextMenu> <MenuItem Header="Copier"/> <MenuItem Header="Coller"/> </ContextMenu> </TextBox.ContextMenu> </TextBox> <Label Name="lblPrenom" Canvas.Top="10" Canvas.Left="240"> Prnom </Label>

Cest partir dici que le code est effectivement modi. Pour chacun des TextBox un objet de type Binding est assign la proprit Text.
<TextBox Name="txtPrenom" Canvas.Top="10" Canvas.Left="300" Width="130" MaxLength="30" Text ="{Binding Path=Prenom}"/> <Label Name="lblAdr" Canvas.Top="40" Canvas.Left="10"> Rue

Le guide du codeur 197

Lier les donnes son interface utilisateur

</Label> <TextBox Name="txtAdr" Canvas.Top="40" Canvas.Left="80" Width="350" MaxLength="80" Text ="{Binding Path=Adresse}"/> <Label Name="lblCP" Canvas.Top="70" Canvas.Left="10"> Code postal </Label> <TextBox Name="txtCP" Canvas.Top="70" Canvas.Left="80" Width="50" MaxLength="5" Text ="{Binding Path=CP}"/> <Label Name="lblLocalite" Canvas.Top="70" Canvas.Left="150"> Localit </Label> <TextBox Name="txtLocalite" Canvas.Top="70" Canvas.Left="200" Width="230" MaxLength="50" Text ="{Binding Path=Localite}"/> <Border Width="100" Height="120" BorderThickness="1" Background="White" BorderBrush="Black" Canvas.Top="10" Canvas.Right="10"> <Image Source="{Binding Path=Photo}"/> </Border> <Label Name="lblCopyright" Canvas.Bottom="10" Canvas.Right="10" Content="Micro Application 2006" /> </Canvas> </DockPanel> </Window>

Autres modications Au passage, la gestion des vnements Click a t ajoute dans la barre doutils pour faire appel aux mthodes Click_Next et Click_Prev.

m Figure 7-7 : Liaison un DataSet

198 Le guide du codeur

Lier les donnes un DataSet

La fentre est affiche avec toutes les informations du premier enregistrement.


Contenu du champ Photo Le champ Photo contient le chemin des images et non limage elle-mme.

En revanche, rien ne se passe si vous cliquez sur Suivant. Nous devons encore ajouter la gestion des changements denregistrement.
Public Sub Click_Prev(ByVal sender As Object _ , ByVal e As RoutedEventArgs) Code pour prcedent If m_i > 0 Then m_i = m_i - 1 Me.DataContext = m_data.Carnet_adresses.Rows(m_i) End If End Sub Public Sub Click_Next(ByVal sender As Object _ , ByVal e As RoutedEventArgs) Code pour suivant If m_i < m_data.Carnet_adresses.Rows.Count - 1 Then m_i = m_i + 1 Me.DataContext = m_data.Carnet_adresses.Rows(m_i) End If End Sub

Le champ m_i permet de conserver en mmoire la position courante dans la DataTable. Ce code intgre les instructions pour viter de dpasser les limites de la table. Comme vous pouvez le constater, il suffit dadapter le DataContext pour quil contienne la ligne voulue. Maintenant, lenregistrement change lorsque vous demandez le suivant ou le prcdent.

m Figure 7-8 : Changer denregistrement

Idalement, il faudrait dsactiver les boutons Prcdent et Suivant des diffrents menus quand ceux-ci ne peuvent tre raliss.
Le guide du codeur 199

Lier les donnes son interface utilisateur

Pour y arriver, reportez-vous au chapitre Rendre un lment du


Renvoi menu inactif page 172.

Vous pouvez modier une valeur dans lcran, changer denregistrement et revenir sur celui que vous avez modi, les modications sont toujours prsentes.

Enregistrement dans la base de donnes Les donnes sont bien sauves dans le DataSet mais le code en ltat nenregistre pas le DataSet dans la base de donnes. Les modications sont ds lors perdues au moment o vous quittez le programme.

Par exemple, nous pouvons enregistrer les donnes dans la base de donnes lors de lopration de fermeture. Modiez le code pour reter le code ci-dessous.
Private m_adapter As _ DBXAMLDataSetTableAdapters.Carnet_adressesTableAdapter Public Sub New() InitializeComponent() m_adapter = New _ DBXAMLDataSetTableAdapters.Carnet_adressesTableAdapter m_adapter.Fill(m_data.Carnet_adresses) End Sub Public Sub Click_Fermer(ByVal sender As Object _ , ByVal e As RoutedEventArgs) Me.mnuFermer.IsEnabled = False Me.mnuOuvrir.IsEnabled = True Me.mnuEdition.Visibility = _ Windows.Visibility.Collapsed Me.frmData.IsEnabled = False m_adapter.Update(m_data) End Sub

Nouveau champ dans la classe Lobjet m_adapter prcdemment dni comme variable locale dans le constructeur devient un champ de la classe. De cette faon, il peut tre utilis dans la mthode Click_Fermer.

La base de donnes sera ds lors correctement enregistre.


200 Le guide du codeur

Lier les donnes un DataSet


Plusieurs sources de donnes Dans lexemple, nous avons travaill avec un seul DataContext dni pour tout lcran. Il est possible de dnir un DataContext diffrent pour chaque lment de la fentre.

Il est galement possible dutiliser une table pour charger un contrle de type liste. Si vous souhaitez reproduire lexemple, modiez votre base de donnes et recrez le schma XSD pour reter le graphique ci-dessous.

b Figure 7-9 : Nouveau schma XSD

Pour crer le schma, reportez-vous la page 192.


Renvoi

Ensuite, nous devons apporter quelques modications au code .NET.


Public Sub New() InitializeComponent() m_adapter = New _ DBXAMLDataSetTableAdapters.Carnet_adressesTableAdapter m_adapter.Fill(m_data.Carnet_adresses) Dim adapter As New _ DBXAMLDataSetTableAdapters.PaysTableAdapter adapter.Fill(m_data.Pays) End Sub

Non seulement nous chargeons le membre m_data avec la DataTable Carnet_adresses mais nous chargeons galement la table Pays. Private Sub Win_loaded(ByVal sender As Object _ , ByVal e As RoutedEventArgs) m_i = 0 Me.DataContext = m_data.Carnet_adresses.Rows(m_i) Me.lstPays.DataContext = m_data End Sub

Le guide du codeur 201

Lier les donnes son interface utilisateur

La table Pays est maintenant charge dans le DataSet et le DataContext de la liste est diffrent de celui du reste de lcran. Ajoutez ces balises dans le code XAML.
<Label Canvas.Top="100" Canvas.Left="150"> Pays </Label> <ListBox Name="lstPays" Canvas.Top="100" Canvas.Left="200" ItemsSource="{Binding Path=Pays}" DisplayMemberPath="Pays"/>

Remarquez que la source est non pas un champ mais une table. Cest lattribut DisplayMemberPath qui prcise le nom du champ afficher. Dans cet exemple, le nom est le mme car il sagit du champ Pays dans la table Pays.

m Figure 7-10 : ListBox lie un DataSet

Cette solution fonctionne parfaitement pour charger la liste mais, du coup, il ne nous est pas possible de lier la valeur notre carnet dadresses. La solution la plus simple est de modier nouveau le code .NET.
Private Sub Win_loaded(ByVal sender As Object _ , ByVal e As RoutedEventArgs) m_i = 0 Me.DataContext = m_data.Carnet_adresses.Rows(m_i) Dim bind As New Binding("Pays") bind.Source = m_data Me.lstPays.SetBinding(ListBox.ItemsSourceProperty _ , bind) End Sub

202 Le guide du codeur

Lier les donnes un objet mtier

Le code XAML devient alors :


<ListBox Name="lstPays" Canvas.Top="100" Canvas.Left="200" DisplayMemberPath="NomPays" SelectedValue="{Binding Path=Pays}" SelectedValuePath="Id" />

De cette faon, une source spcique est dnie pour la liste et la source par dfaut pour la valeur. Cet exemple dmontre non seulement quil est possible de raliser des liaisons vers divers objets mais galement que la liaison peut tre effectue sur diffrents attributs. Vous pourriez par exemple dnir une liaison sur la couleur du fond.

7.2 Lier les donnes un objet mtier


Au lieu de lier les donnes un DataSet, vous pouvez galement les lier un objet quelconque. Gnralement, il sagira dun objet dit mtier. En effet, en programmation professionnelle, les dveloppements sont gnralement diviss en trois couches, la couche de liaison base de donnes, la couche mtier, dite business, et la couche de prsentation. La couche de prsentation lit les donnes non pas directement dans la couche daccs la base de donnes mais uniquement dans la couche mtier, qui prendra en charge une ventuelle transformation des donnes. Nous allons construire un objet mtier capable de recevoir les donnes de notre exemple.
Public Class Business Private Private Private Private Private Private m_nom As String m_prenom As String m_adresse As String m_cp As String m_localite As String m_pays As Integer

Public Property Nom() As String Get Return m_nom End Get Set(ByVal value As String) m_nom = value.ToUpper() End Set

Le guide du codeur 203

Lier les donnes son interface utilisateur

End Property Public Property Prenom() As String Get Return m_prenom End Get Set(ByVal value As String) m_prenom = valueli End Set End Property

Comme vous pouvez le voir, il sagit essentiellement de dnir des membres privs et les proprits qui leur sont associes. Vous pourriez tre tent de dnir directement les membres comme publics et ainsi de vous passer des proprits. Toutefois, il vaut mieux suivre ds le dpart les bonnes pratiques et respecter cette rgle qui apportera dans lvolution de votre classe beaucoup plus de souplesse. Sans compter que le membre dni peut pour des raisons mtier ou techniques tre stock dune certaine manire et prsent aux utilisateurs de la classe dune autre faon.
Public Property Adresse() As String Get Return m_adresse End Get Set(ByVal value As String) m_adresse = value End Set End Property Public Property CP() As String Get Return m_cp End Get Set(ByVal value As String) m_cp = value End Set End Property Public Property Localite() As String Get Return m_localite End Get Set(ByVal value As String) m_localite = value End Set End Property

204 Le guide du codeur

Lier les donnes un objet mtier

Public Property Pays() As Integer Get Return m_pays End Get Set(ByVal value As Integer) m_pays = value End Set End Property

Pour une question de simplicit, la mthode de chargement des donnes est incluse dans lobjet Business. Il existe beaucoup de techniques diffrentes pour raliser les couches, mais nous entrons l dans des problmes darchitecture bien loigns de ce qui nous occupe. Toutefois, mme avec XAML et peut-tre encore plus avec XAML, pensez larchitecture que vous allez implmenter dans votre programme avant de commencer la moindre lige de code.
Public Sub Charger(ByVal val As Short) If val = 1 Then m_nom = "Dupond" m_prenom = "Louis" m_adresse = "Rue des coteaux, 23" m_localite = "Pillion" m_cp = "23456" m_pays = 22 Else m_nom = "Durand" m_prenom = "Albert" m_adresse = "Rue des poteaux, 2" m_localite = "Paille" m_cp = "23765" m_pays = 24 End If End Sub End Class

Le but de cet exemple nest pas de vous apprendre travailler en couche. La classe mtier qui vous est prsente ici est trs simplie et la mthode de chargement des donnes nest l que pour permettre dafficher simplement un rsultat. Typiquement, nous devrions trouver dans la classe des mthodes de manipulation, de contrle, de transformation des donnes. Linteraction entre lobjet mtier et la couche daccs aux donnes nest pas gre par XAML. Il sagit de .NET pur. Le code .NET doit tre adapt pour charger lobjet mtier.
Partial Public Class Window1 Inherits Window
Le guide du codeur 205

Lier les donnes son interface utilisateur

En tout premier, nous devons dclarer notre objet mtier comme membre de la classe. Notez que nous avons galement conserv le DataSet. Il est encore ncessaire pour charger la liste des pays.
Private m_data As New DBXAMLDataSet Private m_business As New Business

Dans le constructeur, nous chargeons les donnes dans le DataSet et dans lobjet mtier.
Public Sub New() InitializeComponent() Dim adapter As New DBXAMLDataSetTableAdapters.PaysTableAdapter adapter.Fill(m_data.Pays) m_business.Charger(1) End Sub

La liaison proprement dite est ralise lors du chargement de la fentre.


Private Sub Win_loaded(ByVal sender As Object , ByVal e As RoutedEventArgs) Dim bind As New Binding("Pays") bind.Source = m_data Me.lstPays.SetBinding(ListBox.ItemsSourceProperty , bind) Me.DataContext = m_business End Sub Public Sub Click_Prev(ByVal sender As Object _ , ByVal e As RoutedEventArgs) Code pour prcedent m_business.Charger(1) Me.DataContext = Nothing Me.DataContext = m_business End Sub Public Sub Click_Next(ByVal sender As Object _ , ByVal e As RoutedEventArgs) Code pour suivant m_business.Charger(2) Me.DataContext = Nothing Me.DataContext = m_business End Sub End Class

Comme ctait le cas pour le DataSet, lobjet mtier est dclar comme champ de la classe. Il est initialis dans le constructeur et plac comme source de
206 Le guide du codeur

Lier les donnes sans utiliser le code .NET

donnes dans la mthode Win_Load. Il manque bien videmment lenregistrement des donnes de lobjet mtier mais, l encore, il sagit de programmation .NET classique.

Rafrachissement An de provoquer le rafrachissement de lcran lorsque les valeurs sont recharges, la valeur Nothing est charge dans lattribut DataContext et est ensuite nouveau charge par m_business.

Selon les circonstances, vous pourriez avoir plusieurs objets mtier et changer le DataContext pour quil pointe sur lun ou lautre. Dans ce cas, typiquement, vous aurez une collection dobjets mtier.

Le chier XAML nest pas modi Les liaisons se font sur les noms des proprits de la classe. Comme nous avons donn les mmes noms nos proprits que les noms des champs dans le schma xsd, le code XAML peut rester tel que.

En dnitive, cet exemple dmontre quil est non seulement possible de lier nimporte quelle proprit une donne externe mais galement que la donne externe peut elle-mme tre conserve dans nimporte quelle classe dobjet.

7.3 Lier les donnes sans utiliser le code .NET


Jusque-l, nous avons vu comment lier les contrles un objet mais UNIQUEMENT via le code .NET. Il est galement possible de raliser cette liaison directement dans le code XAML. Pour cela, vous disposez de deux outils diffrents. Le XmlDataProvider pour rcuprer les donnes dune source XML ou ObjectDataProvider pour rcuprer les donnes dun objet. Nous allons en premier voir comment rcuprer les informations dans la source XML. Tout dabord, nous devons crer un chier de donnes. Recopiez le code XML suivant dans un chier que vous nommez Data.xml.
<Table> <Name>Direction</Name> <Records>

Le guide du codeur 207

Lier les donnes son interface utilisateur

<Record> <Nom>Durant</Nom> <Prenom>Louis</Prenom> <Titre>Directeur general</Titre> </Record> <Record> <Nom>Dupont</Nom> <Prenom>Leon</Prenom> <Titre>Product manager</Titre> </Record> <Record> <Nom>Durand</Nom> <Prenom>Carine</Prenom> <Titre>Directrice generale adjointe</Titre> </Record> </Records> </Table>

Ce chier contient donc une simulation de table dont le nom serait Direction et qui contient trois enregistrements. La structure de ce chier XML nest absolument pas une structure obligatoire et nest reprise qu titre dexemple. Une fois ce chier cr, nous pouvons maintenant raliser notre page XAML qui va lire directement ce chier. Les donnes seront affiches dans une ListView. Ce sera pour nous loccasion de dcouvrir ce contrle, qui se prte particulirement bien laffichage de donnes enregistres dans une source externe.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <Grid> <Grid.Resources> <XmlDataProvider x:Key="data" Source=" Data.XML"/> </Grid.Resources> <Grid.DataContext> <Binding Source="{StaticResource data}" XPath="/Table/Records"/> </Grid.DataContext> <ListView Height="92" Margin="13,18,19,0" Name="MaListView" VerticalAlignment="Top" ItemsSource="{Binding XPath=Record/Nom}" </Grid> </Page>

208 Le guide du codeur

Lier les donnes sans utiliser le code .NET

b Figure 7-11 : Affichage du contenu dun chier XML dans une ListView

Comme vous pouvez le constater, la balise XmlDataProvider est extrmement simple dutilisation puisquil ne sagit que de donner un nom via lattribut x:Key et de dnir le chier en utilisant lattribut Source. Comme pour les techniques prcdentes, nous devons utiliser le DataContext. Cette fois, nous le faisons directement dans le chier XAML puisque la source est dnie en tant que ressource statique. Lattribut XPath va permettre de dterminer dans le chier XML le nud qui contient les donnes qui nous intressent. Il ne reste plus alors qu dnir la ListView. En dehors de lattribut ItemSource, qui permet de dnir les donnes associes, rien de bien neuf. Notez que, pour dnir les donnes, nous utilisons nouveau XPath. Le contenu du nud Nom inscrit dans chaque nud Record de la source de donnes (DataContext) servira dnir un lment de la liste. Si nous dsirons afficher plus dune information par liste, vous pouvez utiliser lattribut ItemTemplate de notre ListView. Pour cela, nous devons au pralable dnir un DataTemplate. Le DataTemplate sert dcrire le contenu et la faon de reprsenter chacun des lments de la liste. Il se place galement dans la zone des ressources.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <Grid> <Grid.Resources> <XmlDataProvider x:Key="data" Source=" Data.XML"/>

Le guide du codeur 209

Lier les donnes son interface utilisateur

<DataTemplate x:Key="DataListView"> <WrapPanel> <Label Content="{Binding XPath=Nom}"/> <Label Content="{Binding XPath=Prenom}"/> <Label Content="{Binding XPath=Titre}"/> </WrapPanel> </DataTemplate> </Grid.Resources> <Grid.DataContext> <Binding Source="{StaticResource data}" XPath="/Table/Records"/> </Grid.DataContext> <ListView Height="92" Margin="13,18,19,0" Name="MaListView" VerticalAlignment="Top" ItemsSource="{Binding XPath=Record}" ItemTemplate="{StaticResource DataListView}"/> </Grid> </Page>

b Figure 7-12 : Affichage dune ListView en utilisant un DataTemplate

Contenu dun DataTemplate Comme vous pouvez le remarquer, un DataTemplate peut contenir nimporte quel code XAML ou presque.

210 Le guide du codeur

Lier les donnes sans utiliser le code .NET

Un autre moyen dafficher plus dinformations est dutiliser un GridView. Le GridView est non pas proprement parler un autre contrle mais plutt une extension qui se place dans la proprit View de ListView. Il permet dafficher les informations dans des colonnes spares et mme de donner un titre ces colonnes. Si nous reprenons le mme exemple, nous devrons le modier comme suit.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <Grid> <Grid.Resources> <XmlDataProvider x:Key="data" Source=" Data.XML"/> </Grid.Resources> <Grid.DataContext> <Binding Source="{StaticResource data}" XPath="/Table/Records"/> </Grid.DataContext> <ListView Height="92" Margin="13,18,19,0" Name="MaListView" VerticalAlignment="Top" ItemsSource="{Binding XPath=Record}"> <ListView.View>

Dans cet exemple, le GridView contient trois colonnes, une pour le nom, une pour le prnom et une pour le titre.
<GridView AllowsColumnReorder="True"> <GridViewColumn Header="Nom" Width="50" DisplayMemberBinding= "{Binding XPath=Nom}"/> <GridViewColumn Header="Prnom" Width="60" DisplayMemberBinding= "{Binding XPath=Prenom}"/> <GridViewColumn Header="Titre" Width="140" DisplayMemberBinding= "{Binding XPath=Titre}"/> </GridView> </ListView.View> </ListView> </Grid> </Page>

Le guide du codeur 211

Lier les donnes son interface utilisateur

b Figure 7-13 : Affichage dun GridView

Dplacer les colonnes Pour permettre lutilisateur de dplacer les colonnes par glisser-dposer, vous devez assigner la valeur True lattribut AllowsColulmnReorder dans la balise GridView.

Si vous prfrez donner un aspect plus structur votre affichage, vous utiliserez probablement un TreeView. Sur la base du mme exemple, nous pouvons construire un petit TreeView mais, an de lui donner un aspect plus hirarchis, il y a lieu de modier au pralable notre source de donnes.
<Table> <Name> Direction </Name> <Records> <Administration> <Record> <Nom>Durant</Nom> <Prenom>Louis</Prenom> <Titre>Directeur general</Titre> </Record> <Record> <Nom>Durand</Nom> <Prenom>Carine</Prenom>
212 Le guide du codeur

Lier les donnes sans utiliser le code .NET

<Titre>Directrice generale adjointe</Titre> </Record> </Administration> <Production> <Record> <Nom>Dupont</Nom> <Prenom>Leon</Prenom> <Titre>Product manager</Titre> </Record> </Production> </Records> </Table>

Avec les nuds Administration et Production, les membres de la direction sont maintenant groups selon leurs tches. Nous pouvons reprsenter cette structure dans le TreeView.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <Grid> <Grid.Resources> <XmlDataProvider x:Key="data" Source="Data2.XML"/> <DataTemplate x:Key="Admin"> <WrapPanel> <Label Foreground="Blue" Content="{Binding XPath=Nom}"/> <Label Content="{Binding XPath=Prenom}"/> <Label Content="{Binding XPath=Titre}"/> </WrapPanel> </DataTemplate>

Nous pouvons dnir un deuxime DataTemplate sur la mme source. Dans lexemple, seule la couleur est modie, mais vous pourriez changer tous les lments.
<DataTemplate x:Key="Prod"> <WrapPanel> <Label Foreground="Green" Content="{Binding XPath=Nom}"/> <Label Content="{Binding XPath=Prenom}"/> <Label Content="{Binding XPath=Titre}"/> </WrapPanel> </DataTemplate> </Grid.Resources> <Grid.DataContext>
Le guide du codeur 213

Lier les donnes son interface utilisateur

<Binding Source="{StaticResource data}" XPath="/Table/Records"/> </Grid.DataContext> <TreeView Margin="13,18,19,0" Name="MaTreeView" Background="Azure"> <TreeViewItem ItemsSource="{Binding XPath=Administration/Record}" Header="Administration" ItemTemplate="{StaticResource Admin}"/> <TreeViewItem ItemsSource="{Binding XPath=Production/Record}" Header="Production" ItemTemplate="{StaticResource Prod}"/> </TreeView> </Grid> </Page>

b Figure 7-14 : Affichage dun TreeView

Comme vous pouvez le constater, chaque lment du TreeView possde sa propre source ou plutt son propre chemin vers les donnes. Il peut aussi avoir sa propre reprsentation mais, gnralement, le modle (DataTemplate) sera le mme pour lensemble des lments. Voyons maintenant comment raliser une liaison avec un objet en utilisant
ObjectDataProvider.

Nous devons tout dabord crer une classe. Prenons comme exemple la classe Auteur, qui contient son nom et une collection de livres quil a crits.

214 Le guide du codeur

Lier les donnes sans utiliser le code .NET

b Figure 7-15 : Le TreeView ouvert

Pour cela, il nous faut une classe Livre.


Public Class Livre Private _name As String Public ReadOnly Property Name() As String Get Return _name End Get End Property

Le nom du livre est initialis dans le constructeur.


Public Sub New(ByVal name As String) _name = name End Sub End Class

Ensuite, nous avons besoin dune collection type pour stocker les objets Livre.
Public Class Livres Inherits ObservableCollection(Of Livre) Public Sub New() End Sub End Class

Le guide du codeur 215

Lier les donnes son interface utilisateur

Nous pouvons maintenant crer la classe Auteur.


Public Class Auteur Private _name As String Private _livres As Livres Public ReadOnly Property Name() As String Get Return _name End Get End Property Public ReadOnly Property Livres() As Livres Get Return _livres End Get End Property

Lauteur et les livres sont initialiss dans le constructeur.


Public Sub New() _name = "Stephen King" _livres = New Livres _livres.Add(New Livre("La tour sombre")) _livres.Add(New Livre("Ca")) _livres.Add(New Livre("La peau sur les os")) End Sub End Class

Maintenant, nous pouvons passer au code XAML et lutilisation dObjectDataProvider. La proprit ObjectType va nous permettre de spcier le type dobjet qui sera cr.

Objet cr dans le code .NET

ObjectDataProvider ne fait pas la liaison avec un objet existant mais instancie


un nouvel objet. Pour raliser la liaison avec un objet dni dans le code .NET, vous devez utiliser la mthode vue prcdemment.

Le paramtre ConstructorParameters, que nous nutiliserons pas ici, permet de transmettre des paramtres au constructeur. Les autres techniques utilises ont dj t vues prcdemment.

216 Le guide du codeur

Lier les donnes sans utiliser le code .NET

<Window xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:src="clr-namespace:ObjectProviderExemple" > <Window.Resources> <ObjectDataProvider x:Key="sk" ObjectType="{x:Type src:Auteur}"/> <DataTemplate x:Key="NomAuteur"> <TextBlock Text="{Binding Path=Name}" /> </DataTemplate> </Window.Resources> <StackPanel DataContext= "{Binding Source={StaticResource sk}}" Margin="10,10,10,0"> <TextBlock Text="{Binding Path=Name}" Background="LightGray" /> <ListView Background="LemonChiffon" ItemsSource="{Binding Path=Livres}" ItemTemplate="{DynamicResource NomAuteur}" /> </StackPanel> </Window>

b Figure 7-16 : Binding avec ObjectDataProvider

ObjectProviderExemple

ObjectProviderExemple est le nom du projet et donc par dfaut celui de


lassembly.

Les paramtres ObjectInstance, MethodName et MethodParameters tendent encore les possibilits de cette classe en permettant entre autres laccs des mthodes de lobjet cr.
Le guide du codeur 217

Lier les donnes son interface utilisateur

7.4 Checklist
Dans ce chapitre sur la connexion aux donnes, nous avons essentiellement vu :
j

j j j

j j

comment lier un objet DataSet ou autre avec un contrle en utilisant les proprits DataContext et Source ; comment lier les donnes en utilisant Binding ; comment lier les donnes un chier XML en utilisant XmlDataProvider ; comment afficher les donnes dans une ListView ou de manire plus labore avec un GridView ; comment afficher les donnes dans une arborescence avec TreeView ; comment lier les donnes un objet en utilisant ObjectDataProvider.

218 Le guide du codeur

Ch apit re

8 Fonctionnalits avances
Appliquer des transformations sur les contrles ....................................... Crer une ressource .................................. Crer un style ........................................... Checklist ..................................................

220 223 227 247

Fonctionnalits avances

8.1 Appliquer des transformations sur les contrles


XAML nous offre quelques possibilits pour manipuler la disposition des contrles. Nous nentrerons pas dans les dtails. Toutefois, au travers des quelques exemples prsents dans ce chapitre et si vous avez un jour besoin dune telle fonctionnalit, vous devriez pouvoir facilement trouver les paramtres qui vous conviennent. Comme premier exemple, nous allons effectuer une rotation sur une tiquette. Pour lexemple, reprenons ltiquette dnie page 28.
Renvoi

<Label Name="lblPremierLabel" HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="Verdana" FontSize="14" FontWeight="Heavy" FontStyle="Italic" FontStretch="UltraExpanded" Foreground="Aquamarine" Background="Blue"> Mon premier label. <Label.RenderTransform> <RotateTransform Angle="270" /> </Label.RenderTransform> </Label>

b Figure 8-1 : Une tiquette verticale

Accder une proprit grce un nud ls Pour la premire fois, nous utilisons une proprit de la classe non pas en la dnissant grce un attribut mais bien comme un nud ls de notre nud Label.

220 Le guide du codeur

Appliquer des transformations sur les contrles

Il est galement possible de raliser une modication dchelle.


<Label Name="lblPremierLabel" HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="Verdana" FontSize="14" FontWeight="Heavy" FontStyle="Italic" FontStretch="UltraExpanded" Foreground="Aquamarine" Background="Blue"> Mon premier label. <Label.RenderTransform> <ScaleTransform CenterY="20" ScaleX="1" ScaleY="7" /> </Label.RenderTransform> </Label>

Notez la prsence de lattribut CenterY, qui comme CenterX permet de modier la position du contrle en mme temps que lui est applique la transformation.

b Figure 8-2 : Une tiquette tire

Nous pouvons aussi adapter loblicit sur deux axes.


<Label Name="lblPremierLabel" HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="Verdana" FontSize="14" FontWeight="Heavy" FontStyle="Italic" FontStretch="UltraExpanded" Foreground="Aquamarine" Background="Blue"> Mon premier label. <Label.RenderTransform> <SkewTransform AngleX="45" AngleY="20" /> </Label.RenderTransform> </Label>

Le guide du codeur 221

Fonctionnalits avances

b Figure 8-3 : Une tiquette en 3D

Si vous ne trouvez pas votre bonheur dans ces transformations, vous pouvez toujours utiliser une transformation grce une matrice.
<Label Name="lblPremierLabel" HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="Verdana" FontSize="14" FontWeight="Heavy" FontStyle="Italic" FontStretch="UltraExpanded" Foreground="Aquamarine" Background="Blue" RenderTransform= "1,-0.5,0,1,0,0"> Mon premier label. </Label>

Nous revenons avec cette commande dans la structure plus traditionnelle dun attribut de notre balise. Chaque chiffre de la matrice applique une transformation notre label.

b Figure 8-4 : Une tiquette oblique

vous de dcouvrir le rsultat obtenu en modiant chacun des paramtres.


222 Le guide du codeur

Crer une ressource

Les transformations appliques prcdemment sur un Label peuvent parfaitement tre utilises avec dautres contrles. Par exemple, leffet sur un texte long est, pour qui a lhabitude des limites de lAPI Win32, toujours trs surprenant.
<TextBlock Name="blckTexte" MaxWidth="200" MaxHeight="70" TextWrapping="Wrap" TextTrimming="WordEllipsis" Margin="5,5,5,5" TextAlignment="Justify" > Nous sommes maintenant arrivs notre deuxime contrle. Comme vous avez dj pu le constater, XAML est la fois simple dutilisation et performant. <TextBlock.RenderTransform> <RotateTransform CenterX="100" CenterY="100" Angle="270"/> </TextBlock.RenderTransform> </TextBlock>

b Figure 8-5 : Un bloc de texte vertical

8.2 Crer une ressource


Une ressource en XAML est un lment que vous codez an quil soit rutilis au sein du conteneur dans lequel elle est dnie. Lutilit de la ressource est de

Le guide du codeur 223

Fonctionnalits avances

pouvoir rutiliser le code sans devoir le rcrire compltement. Ce qui permet un gain de temps mais aussi limite les risques de bug ou doubli en cas de modication. Prenons un exemple simple de ressource.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <Page.Resources> <SolidColorBrush Color="Gold" x:Key="Background1"/> <SolidColorBrush Color="Lavender" x:Key="Background2"/> </Page.Resources> <StackPanel> <TextBox Background="{StaticResource Background1}"/> <TextBox Background="{StaticResource Background2}"/> <TextBox Background="{StaticResource Background1}"/> <TextBox Background="{StaticResource Background1}"/> <TextBox Background="{StaticResource Background2}"/> </StackPanel> </Page>

b Figure 8-6 : Utiliser des ressources

Le nom de la ressource est dni grce lattribut x :key. La ressource est accde en assignat {StaticResource NomDeLaRessource} lattribut cible. Si vous changez la ressource, toute la page est directement affecte. Il nest pas ncessaire de modier chaque contrle.

224 Le guide du codeur

Crer une ressource

<Page.Resources> <SolidColorBrush Color="Red" x:Key="Background1"/> <SolidColorBrush Color="Blue" x:Key="Background2"/> </Page.Resources>

b Figure 8-7 : Ressources modies

Nous avons utilis les ressources de manire statique, il est toutefois possible de les utiliser de manire dynamique en remplaant le mot cl StaticResource par DynamicResource. Cette possibilit nest intressante que quand la ressource peut tre modie. Elle pourra alors tre recharge. Il est possible davoir deux ressources portant le mme nom pour autant quelles ne soient pas dnies dans la mme balise. Pour retrouver une ressource, XAML remonte niveau aprs niveau la recherche de cette ressource. Pour la lisibilit du code, il est malgr tout fortement conseill dutiliser des noms diffrents.
<Page xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <Page.Resources> <SolidColorBrush Color="Red" x:Key="Background1"/> <SolidColorBrush Color="Blue" x:Key="Background2"/> </Page.Resources> <StackPanel> <StackPanel.Resources> <SolidColorBrush Color="Lavender" x:Key="Background1"/> </StackPanel.Resources>

Le guide du codeur 225

Fonctionnalits avances

<TextBox Background="{StaticResource <TextBox Background="{StaticResource <TextBox Background="{StaticResource <TextBox Background="{StaticResource <TextBox Background="{StaticResource </StackPanel> </Page>

Background1}"/> Background2}"/> Background1}"/> Background1}"/> Background2}"/>

b Figure 8-8 : Ressources de mme nom

Les ressources sont aussi un moyen simple pour partager un menu contextuel entre plusieurs lments.
<Window.Resources> <ContextMenu x:Key="CtxtMnu"> <MenuItem Header="Copier"/> <MenuItem Header="Coller"/> </ContextMenu> </Window.Resources> <TextBox Name="txtNom" Canvas.Top="10" Canvas.Left="80" Width="150" MaxLength="30" CharacterCasing="Upper" Text ="{Binding Path=Nom}" ContextMenu="{StaticResource CtxtMnu}" /> <Label Name="lblPrenom" Canvas.Top="10" Canvas.Left="240"> Prnom </Label> <TextBox Name="txtPrenom" Canvas.Top="10" Canvas.Left="300" Width="130" MaxLength="30" Text ="{Binding Path=Prenom}" ContextMenu="{StaticResource CtxtMnu}"/>
226 Le guide du codeur

Crer un style

8.3 Crer un style


Les styles vont permettre de modier lapparence des contrles, et cela sans rpter les modications pour chaque contrle individuellement. Prenons un exemple simple. La couleur du fond des botes de texte ne vous convient pas. Bien sr, vous pouvez changer cette couleur avec lattribut Background sur chaque TextBox mais aussi utiliser un style. Un style est dni comme ressource dun conteneur. Nous choisirons de le placer comme ressource de la fentre.
<Window.Resources> <Style x:Key="MyTextBox"> <Setter Property="TextBox.Background" Value=Gold/> </Style> </Window.Resources>

Si nous analysons ce code, la premire chose faire est de donner un nom ce style avec lattribut x:Key. La balise Setter va nous permettre de dnir la proprit affecte. Il ne nous reste