You are on page 1of 336

Copyright 2009 Micro Application - 20-22, rue des Petits-Htels - 75010 Paris 1re dition - Fvrier 2009 Auteurs

s - Loc BAR, Simon BOIGELOT

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). Avertissement aux utilisateurs 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 pour responsable de toute omission, erreur ou lacune qui aurait pu se glisser dans cet ouvrage 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 n de dsignation des produits en tant que noms de ces derniers. ISBN : 978-2-300-014314 Couverture ralise par Sbastien Wiegant MICRO APPLICATION 20-22, rue des Petits-Htels 75010 PARIS Tl. : 01 53 34 20 20 Fax : 01 53 34 20 00 Support technique : galement disponible sur www.microapp.com http://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 che produit.

1431

Avant-propos
La collection Webmasters sadresse aux personnes inities au dveloppement de sites web qui souhaitent dcouvrir et mettre en pratique les nouvelles technologies Internet. Sans ngliger les aspects thoriques, nous donnons toujours priorit la pratique an que vous puissiez rapidement tre autonome. travers les diffrents titres de cette collection vous dcouvrirez les technologies qui font le web 2.0 et feront ce que certains nomment dj le web 3.0.

Conventions typographiques
An de faciliter la comprhension des 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 scripts, indique un retour la ligne volontaire d aux contraintes de la mise en page.

Il sagit dinformations complmentaires relatives au sujet trait. Propose conseils et trucs pratiques.

Mise en garde sur un point important ne pas ngliger.

Sommaire
1
Le langage XAML 22

1.1 1.2

Introduction .................................................................... 24 Les bases de XAML ........................................................... 24 Hritage de XML ............................................................... 24 Adaptation de XML ........................................................... 25 Les lments de structure ................................................... Grid .............................................................................. StackPanel ...................................................................... Canvas .......................................................................... ScrollViewer .................................................................... Border ........................................................................... Les lments de contenu .................................................... Images ........................................................................... TextBlock ........................................................................ ProgressBar ..................................................................... Les lments dinteractions ................................................. Button ............................................................................ CheckBox ....................................................................... ToggleButton .................................................................... RadioButton ..................................................................... TextBox .......................................................................... PasswordBox ................................................................... ListBox et ListBoxItem .......................................................... ComboBox et ComboBoxItem .............................................. Slider ............................................................................. Autres lments utiles ........................................................ Line ............................................................................... Rectangle ....................................................................... Popup ............................................................................ Premire approche du DataBinding ..................................... DataTemplates ................................................................. ValueConverter ................................................................ Le chier Generic.XAML ..................................................... Rednir la structure dune ListBox .......................................... 26 26 30 31 32 33 35 35 36 37 40 40 42 43 45 46 47 47 49 51 51 51 52 53 55 61 66 72 72

1.3

1.4

1.5 1.6

Les vnements et leur traitement ......................................... 38

1.7

1.8

1.9

Colorez votre application grce aux Brushes et aux Gradients .. 73

Sommaire

1.10 1.11 2

Animez votre application grce aux StoryBoard .................... 79 Crez une bannire Silverlight grce aux animations ................. 82 Check-List ....................................................................... 95
96

Crer vos applications avec Expression Studio

2.1 2.2 2.3 2.4 2.5 2.6 3

Introduction Expression Studio ......................................... 98 Expression Design ............................................................ 99 Expression Encoder 2 ..................................................... 102 Expression Blend 2 ......................................................... 104 Intraction entre Expression Blend et Visual Studio 2008 ....... 109 Check-List ..................................................................... 111
112

Exploiter vos sources de donnes

3.1

Utilisez SQL et votre base de donnes ................................ Silverlight, C# et SQL Serveur : introduction ........................... SQL ............................................................................. Les commandes SQL en C# ...............................................

114 114 115 116

3.2 3.3 3.4

Exploitez vos donnes sur Oracle ...................................... 120 MySQL et Silverlight ....................................................... 124 LINQ ........................................................................... 126 LINQ, un peu dexplication ............................................... 129 LINQ to XML par lexemple ................................................ 129 Les Web services ........................................................... 134 ADO.NET/Silverlight ..................................................... 143 Crez un widget mto ................................................... 153 MapCodesToConditions ................................................... 170 Traitez un ux de donnes RSS ......................................... 174 Check-list ..................................................................... 179
180

3.5 3.6 3.7 3.8 3.9 4

Silverlight et ASP.NET

4.1

Introduction ASP.NET ................................................... 182 ASP.NET ....................................................................... 182 Prrequis ...................................................................... 183

Sommaire

Premier exemple ............................................................. 183 Le Web.cong ............................................................... 190 4.2 Les contrles ASP.NET ..................................................... Les contrles standard ...................................................... Les contrles de validation ................................................. Les contrles riches .......................................................... Les contrles de donnes .................................................. Les contrles de navigation ................................................ Les contrles de login ....................................................... Les contrles HTML .......................................................... Postback et ViewState ...................................................... Les contrles ASP.NET pour Silverlight ................................ Le contrle MediaPlayer ................................................... MediaPlayer et JavaScript ................................................. Le contrle Silverlight ........................................................ 191 191 192 193 193 195 196 197 197 198 201 205 207

4.3

4.4 4.5 5

Interaction de Silverlight avec la page ................................ 210 Check-list ..................................................................... 211


212

Concepts avancs

5.1

Le DataBinding en dtails ................................................ 214 DataContext .................................................................. 216 Interaction avec lutilisateur ................................................ 218 Les Styles et ControlTemplates ........................................... 220 Style ............................................................................ 220 ControlTemplate ............................................................. 222 Crer un UserControl ...................................................... UserControl ClickMe ....................................................... UserControl Ranking ........................................................ Les DependencyProperties ................................................. Cration de lUserControl Ranking ....................................... MediaElement ................................................................ Les contrles de la librairie System.Windows.Controls .......... Calendar ...................................................................... DatePicker .................................................................... GridSplitter .................................................................... TabControl et TabItem ...................................................... 225 226 227 228 229 237 246 247 249 251 252

5.2

5.3

5.4

5.5 5.6 5.7

Le contrle DataGrid ...................................................... 253 DataGrid non auto gnr ................................................ 255 Les contrles Silverlight Toolkit de CodePlex ........................ 269 Check-list ..................................................................... 271

Sommaire

Dcouvrir Deepzoom

272

6.1 6.2 6.3 6.4 6.5 7

Introduction Deepzoom ................................................ 274 Fonctionnement de Deepzoom ......................................... 275 Deepzoom par lexemple ................................................ 279 MouseWheelHelper.cs ..................................................... 285 Deepzoom et Virtual Earth ............................................... 288 Check-list ..................................................................... 289
290

Annexes

7.1

Silverlight et les langages dynamiques ............................... Silverlight et IronPyhton ..................................................... Silverlight et IronRuby ....................................................... Check-list ...................................................................... Introduction au C# ......................................................... Dclaration dune variable de type primitif ............................. Rgles de nommage ........................................................ Dclaration dune variable de type de classe ......................... Fonctionnement par rfrence des types de classe ................... Porte des variables ........................................................ Utilisation des proprits de classe ...................................... Utilisation des mthodes de classe ....................................... Structure dun programme C# (Partie 1) ................................ Dnir un type de classe ................................................... Dnir une nouvelle mthode ............................................. Ajouter une mthode une classe ....................................... Structure dun programme C# (Partie 2) ................................ Exemple dune application de gestion de donnes .................. Conclusion .................................................................... Check-list ...................................................................... Webographie ............................................................... Visual Studio 2008 ......................................................... Silverlight ...................................................................... Le Framework .NET .........................................................

292 292 297 299 299 300 300 301 301 302 303 303 303 304 305 306 306 307 311 311 311 312 312 313
315

7.2

7.3

Index

Remerciements
Nous remercions les personnes qui nous ont aid la ralisation de ce livre et en particulier Stphanie Fanara qui sest propose comme premire relectrice de louvrage. Bargelot (Loc Bar et Simon Boigelot)

Prface
Dnition de Silverlight
Microsoft Silverlight est une plateforme de dveloppement dapplications web de haute qualit (RIA : rich Internet application). Cette plateforme est base sur la plateforme .NET, ce qui en fait la plateforme la plus rapide disponible sur Internet actuellement. Malgr leur dveloppement en .NET, les applications Silverlight sont portables. Autant sur Linux, Solaris, Windows et Mac Os que sur certains mobiles. Pour ce faire, le client web doit installer sur sa machine un sous-ensemble de la plateforme .NET : le plugin Silverlight. Ce sous-ensemble contient tout ce qui est ncessaire au fonctionnement de petites applications.

Les prrequis pour dbuter


Dun point de vue technique, pour programmer des applications Silverlight, le minimum vital est : j la plateforme .NET 3.5 ; j un exemplaire de Visual Studio 2008. (La version gratuite de Visual Studio C# Express suffit amplement.) ; j le Service pack 1 pour Visual Studio 2008 ; j les Silverlight Tools pour Visual Studio 2008. (SDK). Tous ces programmes sont disponibles en tlchargement sur le site http://www.silverlight .net/GetStarted. Il est pourtant conseill dajouter cette liste : j une version de Expression Blend 2 ; j le Silverlight ToolKit de CodePlex. Dun point de vue des connaissances, il est utile davoir de notions relatives : j la programmation oriente objets ; j le langage C# ; j le langage XML.

11

Prface

Pour accder une approche de la programmation .NET grce C#, reportez-vous lannexe 2, Introduction au C#.

Prsentation du Microsoft Framework .NET


Le Framework .Net, ou plateforme .NET en franais, est un ensemble compos des lments suivants :
j j j

une machine virtuelle capable dexcuter un code intermdiaire propre la plateforme ; un ensemble de langages parmi lesquels C#, VB.NET, ASP.NET, PHP.NET, IronPython, IronRuby, etc. ; un ensemble de librairies fournissant un grand nombre dAPI prprogrammes.

La version actuelle de la plateforme est 3.5. Au dbut, prvue pour la cration dapplications de bureautiques et de serveurs, cette plateforme sest peu peu dveloppe pour les sites web et les mobiles. De nombreux paradigmes de programmation accompagnent ce Framework. Le plus connu tant celui de la sparation du code dinterface et du code de la logique applicative. La majorit des langages implments par la plateforme divise le code dune application en deux chiers spars. Ce paradigme permet principalement une meilleure collaboration entre programmeurs, designers et intgrateurs. Parmi les librairies fournies, vous trouverez tout ce qui concerne les accs chier, les protocoles de communication, la gestion des donnes, les connexions aux bases de donnes, etc. Chaque nouvelle version du Framework ajoute une couche dabstraction qui rapproche le langage programm du langage humain. Ainsi la version 3.5 a ajout les requtes LINQ permettant de simplier grandement le maniement des donnes. La version 4, en beta actuellement, simpliera principalement laccs aux langages dynamiques. Entre autres, une librairie nomme DLR (Dynamic Langage Runtime) va permettre aux dveloppeurs de crer de nouveaux langages ou de migrer des langages existant sur la plateforme .NET.

12

Prface

Fonctionnement de Silverlight
Pour faire tourner une application Silverlight dans le navigateur web dun utilisateur, cet utilisateur doit pralablement installer un plugin. Ce plugin contient une machine virtuelle prte interprter le code XAML et certaines librairies de la plateforme .NET. Une fois install, et lors de la visite dune page HTML contenant un contrle Silverlight, le plugin va en tlcharger le contenu. Ce contenu est un chier XAP. Un chier XAP est un chier ZIP contenant tout les documents ncessaires au bon fonctionnement dune application Silverlight. Ces documents sont principalement :
j j j j

les diffrents chiers XAML, dcrivant les interfaces de lapplication ; les diffrents chiers C# (ou autre langage) dcrivant la logique applicative ; les ventuels mdias (images, vidos, musique, polices de caractres) ; des librairies .NET non prsentes dans le plugin Silverlight de base.

Lapplication va ensuite tre excute dans une zone mmoire de lordinateur client. Cette zone est une zone scurise du nom de SandBox (bac sable). Le bac sable empche lapplication Silverlight de nuire la machine hte. Par exemple, en limitant laccs aux chiers. Une application Silverlight garde tout de mme la possibilit dcrire et de lire des chiers sur lordinateur de lutilisateur. Cependant, cette fonctionnalit est limite en taille et demande lapprobation pralable de lutilisateur. Ce mme principe sapplique, par exemple, aux accs aux services web. La version 1.0 de Silverlight permettait lutilisation :
j j j j

des graphique 2D ; danimations ; de mdia ; dun code JavaScript comme code applicatif.

La version 1.1 permis lutilisation de code C# ainsi que de quelques autres langages du Framework.

13

Prface

La version 2.0, dernire en date, prsente dans ce livre, a ajout de nombreuses simplications dans lcriture du code XAML, de nouveaux contrles utilisateur et une version encore plus rapide du runtime.

Prise en main de Visual Studio 2008


Visual Studio est une application vous aidant dvelopper. Elle gre des solutions. Une solution est un ensemble de projets travaillant en parallle pour rsoudre un problme donn. Lors du premier dmarrage de Visual Studio, le programme vous demande quel type de prol vous souhaitez utiliser. Ce livre est conu sous le prol Visual C# Dvelopper. Prenez en compte le fait que les raccourcis clavier ainsi que le formatage du texte peuvent changer en fonction du prol choisi.

c Fig. 1 : cran de dmarrage de Visual Studio

14

Prface

Le premier cran ouvert dans Visual Studio est la page de dmarrage. Cette page vous donne un accs rapide aux dernires solutions ouvertes, aux actions de cration et douverture dautres solutions ainsi quau dernier post intressant du Web. La partie en haut se nomme la barre de menu, la partie place lextrmit droite contient deux outils : lExplorateur de solution et lditeur de proprits. Si ces outils ne sont pas visibles sous votre conguration actuelle de Visual Studio, vous pouvez les activer via le menu Affichage de la Barre de menu.
c Fig. 2 : Menu Affichage

Crer une nouvelle solution Silverlight


Pour crer une nouvelle application Silverlight :
1

Sous le menu Fichier, ouvrez le sous-menu Nouveau et choisissez laction Projet.

c Fig. 3 : Nouveau Projet 2

Dans la bote de dialogue qui saffiche, naviguez vers le type de projet Visual C# Silverlight.

15

Prface

c Fig. 4 : Bote de dialogue Nouveau projet

Slectionnez le modle Application Silverlight. 4 Donnez un nom votre application et cliquez sur OK.
3 c Fig. 5 : Bote de dialogue type de dbogage

Une nouvelle bote de dialogue souvre. Elle vous demande si vous dsirez gnrer un projet contenant un site web pour hberger votre application Silverlight immdiatement ou si vous prfrez que Visual Studio se charge de cette tche chaque dmarrage dune session de dbogage de votre application. 6 Ajoutez un nouveau projet ASP.NET la solution pour hberger Silverlight.
5

Votre solution est cre et contient dj de nombreux chiers.

16

Prface

c Fig. 6 : Arborescence de la solution

Les trois seuls chiers qui nous importent pour le moment sont :
j j j

Page.xaml contenant la dnition de linterface de votre application ; Page.xaml.cs qui dtient la dnition du code application de votre application ; NomDeLApplicationTestPage.aspx, page ASP.NET hte de votre SilverLight.

Ajouter un nouveau chier au projet


Pour ajouter un nouveau chier un projet sous Visual Studio : Cliquez du bouton droit sur le nom du projet dans lExplorateur de la solution. 2 Cliquez sur le menu Ajouter/Nouvel lment.
1 c Fig. 7 : Ajouter un nouvel lment un projet

17

Prface

Compiler un projet
1

Pour dboguer un projet Silverlight, cliquez sur le bouton Play situ dans la barre doutils juste au-dessous de la Barre de menu (ou appuyez sur [F5]).
c Fig. 8 : Bouton Dboguer

Aprs compilation russie, votre projet sera lanc dans une page Internet Explorer. Si une erreur survient, la liste derreurs prsente en bas de Visual Studio vous en informera.

c Fig. 9 : Liste derreurs

18

Prface

Lors de la premire excution de votre application, il est probable que vous trouviez la bote de dialogue Dbogage non activ.
c Fig. 10 : Dbogage non activ

Choisissez loption Modier le chier Web.cong pour activer le debogage et cliquez sur OK sans vous en soucier davantage.

Ma premire application Silverlight : HelloWorld


Quoi de plus beau quun HelloWorld !
1

Aprs avoir cr une solution Visual Studio 2008 contenant un projet Silverlight et un projet ASP.NET destins aux tests, ouvrez le chier Page.xaml.
Page.xaml

<UserControl x:Class="HelloWorld.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="400" Height="300"> <Grid x:Name="LayoutRoot" Background="White"> </Grid> </UserControl>

Du code y est dj prsent, il sagit de code XAML, nous tudierons ce langage en dtails aux chapitres 2 et 5.

19

Prface

En attendant, ajoutez simplement quelques lignes de code :


Page.xaml transforme en HelloWorld

<UserControl x:Class="HelloWorld.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="400" Height="300"> <Grid x:Name="LayoutRoot" Background="White"> <TextBlock Text="HelloWorld" FontFamily="Verena" FontSize="70" HorizontalAlignment="Center" VerticalAlignment="Center"/> </Grid> </UserControl> 3

Lancez lapplication.
c Fig. 11 : HelloWorld

Prsentation du contenu de ce livre


Ce livre traite de Silverlight 2.0 et non des sujets connexes ; nous nous efforcerons de vous fournir le maximum dinformations pour satisfaire votre curiosit et votre comprhension. Cependant, impossible de rsumer dans un seul livre la somme norme des connaissances et des savoirs requis pour devenir un professionnel du dveloppement dapplications Silverlight. Notre voyage commencera par un dgrossissement de la fort impntrable que compose un chier XAML. Une fois ce dgrossissement termin, nous pourrons obtenir un court aperu de la suite Expression. Cette suite est un studio complet destin au design et la cration artistique.

20

Prface

Nous tudierons ensuite diffrentes mthodes daccs aux donnes, quelle quen soit leur provenance. Il sera alors temps de revenir sur nos bases de XAML pour en apprendre davantage. Pour nir, nous verrons comment intgrer au mieux Silverlight au sein dune application ASP.NET.

21

1
1.1 Introduction .............................................. 1.2 Les bases de XAML ..................................... 1.3 Les lments de structure ............................... 1.4 Les lments de contenu ............................... 1.5 Les vnements et leur traitement ...................... 1.6 Les lments dinteractions ............................. 1.7 Autres lments utiles ................................... 1.8 Premire approche du DataBinding .................. 1.9 Colorez votre application grce aux Brushes et aux Gradients ................................................ 1.10 Animez votre application grce aux StoryBoard .... 1.11 Check-List ................................................ 24 24 26 35 38 40 51 55 73 79 95

Le langage XAML
L
ors de la cration du Framework 3.0, Microsoft a mis un point dhonneur simplier linteraction entre les dveloppeurs, les intgrateurs et les designers lors du processus de dveloppement dune application. XAML (Extensible Application Markup Language) est la cl de vote de cette simplication concernant Windows Presentation Foundation.

Le langage XAML

1.1 Introduction
Linterface dune application y est dnie, ou dessine, sous la forme dun arbre XML. On retrouve dans cette mthode de dveloppement une approche trs proche de ce qui se fait depuis longtemps en ASP.NET, avec dun ct le code HTML, agrment de contrle ASP.NET, et de lautre, un code de logique applicative contenant la logique de lapplication. De nombreux outils tels que Expression Blend vous permettent de faire abstraction du XAML en vous proposant une interface interactive de dnition de votre application. Cependant, en tant que dveloppeur, une bonne connaissance du XAML vous aidera souvent. En effet, certaines opportunits offertes par Silverlight sont bien plus dpendantes du XAML que du code applicatif. Le binding en est un bon exemple.

1.2 Les bases de XAML


Hritage de XML
Le langage XAML est bas sur le langage XML. Cela lui donne dj de nombreuses bases :
j j j

Un document contient toujours un unique lment appel lment racine. Un lment est une suite de caractres respectant une nomenclature prcise. Un lment peut contenir des attributs et/ou des lments enfants.

Nomenclatures dun lment XML sans enfants :


j j j j

Le premier caractre dun lment est toujours <. Le nom de llment suit directement. Viennent ensuite les diffrents attributs sous la forme NomDeLattribut= valeur . Les derniers caractres de llment sont />.

On obtient donc : <Nom [Attribut1= valeur [Attribut2= valeur []]]/>. Lorsque llment a des enfants, la suite de caractres fermants /> est remplace par >[enfants]</NomDeLlment>.

24

Les bases de XAML

Adaptation de XML
En XAML, le nom de llment est remplac par le nom de la classe du contrle utilisateur quil reprsente. Ainsi, on peut ajouter un bouton notre interface de la manire suivante :
<Button/>

Ce bouton peut avoir des attributs, tels quune taille et un nom (ce qui permettra de le retrouver plus tard dans le code de la logique applicative).
<Button Width="100" Name="Button1"/>

En XAML, tout attribut peut tre transform en enfant. Cette particularit nous sera trs utile pour dclarer des attributs structurs :
<Button> <Button.Width>100</Button.Width> <Button.Name>Button1</Button.Name> </Button>

Tout contrle utilisateur est capable de contenir dautres contrles utilisateur. Ainsi, lemploi le plus frquent du contenu dun bouton est du texte :
<Button Content="du texte"> <Button.Width>100</Button.Width> <Button.Name>Button1</Button.Name> </Button> c Fig. 1.1 : Bouton contenant du texte

Mais il peut en tre autrement. Par exemple, voici un bouton contenant un autre bouton :
<Button Width="100" Name="Button1"> <Button Width="80" Name="Button2" Content="un autre btt"/> </Button> c Fig. 1.2 : Bouton contenant un autre bouton

Attention, la majorit des contrles utilisateur naccepte quun enfant. Il est donc impossible dcrire directement :

25

Le langage XAML

<Button Width="100" Name="Button1"> <Button Width="80" Name="Button2" Content="un autre btt"/> <Button Width="80" Name="Button3" Content="un autre btt"/> </Button>

Pour obtenir un rsultat de ce genre, il est indispensable dutiliser un des lments de Layout que nous verrons au chapitre 3, Crer vos applications avec Expression Studio. Il existe trois types dattributs diffrents :
j j j

Le premier type se trouve partout ou presque, tels Width et Height qui permettent de dnir la taille dun lment dinterface. Le deuxime type est un attribut qui se retrouve seulement dans un lment. Un attribut du deuxime type ne pourra jamais tre utilis dans un autre lment. Le troisime type dattribut est plus subtil. Un attribut de ce type appartient un lment mais est utilis dans un autre. Un bon exemple est lattribut Top de llment Canvas :
Attribut de troisime type

<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="400" Height="200"> <Canvas x:Name="LayoutRoot" Background="White"> <Button Canvas.Top="50"/> </Canvas> </UserControl>

1.3 Les lments de structure


Grid
Lors de la cration de votre premire application Silverlight, le premier lment que vous rencontrez est une Grid. La Grid, grille en franais, fait partie des lments structurants (Dit de Layout) de votre application. En effet, si en WinForm les diffrents lments de vos applications taient organiss les uns par rapport aux autres majoritairement grce leurs positions relatives, en XAML, des lments dits de Layout se chargent de cette organisation. Le plus commun de ces lments est la grille.

26

Les lments de structure

Une grille peut tre compare un tableau compos de lignes et de colonnes. Chaque lment quelle contient doit lui spcier sa position. Le comportement de base dune grille stipule quelle est compose dune cellule unique. Cette cellule tentera de donner son contenu la taille maximale possible :
Comportement dune Grid sans cellules
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="400" Height="300"> <Grid x:Name="LayoutRoot" Background="White"> <Button Content="Hello World"/> </Grid> </UserControl> c Fig. 1.3 : Comportement dune Grid sans cellules

Il est pourtant possible de stipuler une grille le nombre de colonnes quelle doit afficher. Sans autres informations, chaque colonne aura une taille gale aux autres. Il est maintenant devenu indispensable, pour le bouton contenu dans la grille, de prciser sa position :
Comportement dune Grid avec ColumnDenitions
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="400" Height="300"> <Grid x:Name="LayoutRoot" Background="White"> <Grid.ColumnDefinitions>

27

Le langage XAML

<ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Button Grid.Column="1" Content="Hello World"/> </Grid> </UserControl>

Ajouter des lignes cette grille se fait de la mme manire :


c Fig. 1.4 : Comportement dune Grid avec ColumnDenitions

Comportement dune Grid avec RowDenitions


<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="400" Height="300"> <Grid x:Name="LayoutRoot" Background="White"> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Button Grid.Column="0" Grid.Row="1" Content="Hello World"/> </Grid> </UserControl>

28

Les lments de structure

c Fig. 1.5 : Comportement dune Grid avec RowDenitions

Trois options soffrent nous pour forcer les diffrentes lignes ou colonnes adopter des tailles diffrentes :
j j j

en leur donnant une taille en pixels (Width=100) ; en leur demandant de prendre la taille de leur contenu (Width=Auto) ; en leur allouant une partie de lespace restant (Width=*).
Variation de tailles sur les ColumnDenitions et les RowDenitions

<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="400" Height="300"> <Grid x:Name="LayoutRoot" Background="White"> <Grid.ColumnDefinitions> <ColumnDefinition Width="100"/> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*"/> <ColumnDefinition Width="2*"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="100"/> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> <RowDefinition Height="2*"/> </Grid.RowDefinitions> <Button Grid.Column="0" Grid.Row="0" Content="0,0"/> <Button Grid.Column="1" Grid.Row="0" Content="1,0"/> <Button Grid.Column="2" Grid.Row="0" Content="2,0"/> <Button Grid.Column="3" Grid.Row="0" Content="3,0"/>

29

Le langage XAML

<Button <Button <Button <Button <Button <Button <Button <Button <Button <Button <Button <Button </Grid> </UserControl>

Grid.Column="0" Grid.Column="1" Grid.Column="2" Grid.Column="3" Grid.Column="0" Grid.Column="1" Grid.Column="2" Grid.Column="3" Grid.Column="0" Grid.Column="1" Grid.Column="2" Grid.Column="3"

Grid.Row="1" Grid.Row="1" Grid.Row="1" Grid.Row="1" Grid.Row="2" Grid.Row="2" Grid.Row="2" Grid.Row="2" Grid.Row="3" Grid.Row="3" Grid.Row="3" Grid.Row="3"

Content="0,1"/> Content="1,1"/> Content="2,1"/> Content="3,1"/> Content="0,2"/> Content="1,2"/> Content="2,2"/> Content="3,2"/> Content="0,3"/> Content="1,3"/> Content="2,3"/> Content="3,3"/>

c Fig. 1.6 : Variation de tailles sur les ColumnDenitions et les RowDenitions

StackPanel
Le deuxime lment de la famille des Layout est le StackPanel. Un StackPanel imbrique ses diffrents enfants les uns au-dessous des autres :
StackPanel
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="400" Height="100"> <Grid x:Name="LayoutRoot" Background="White"> <StackPanel> <Button Content="Hello"/> <Button Content="World"/> <Button Content="!!!"/>

30

Les lments de structure

</StackPanel> </Grid> </UserControl> c Fig. 1.7 : StackPanel orientation verticale

Les lments fournis dans la plateforme Silverlight de base ne proposent pas de WrapPanel tel quon en trouve en WPF. Il existe deux solutions pour pallier ce problme :
j

utiliser le Silverlight ToolKit de CodePlex que nous voquerons plus tard ; Pour obtenir plus de renseignements sur le Silverlight Toolkit de CodePlex, reportez-vous au chapitre 5, Silverlight et ASP.NET.

forcer un StackPanel afficher ses enfants les uns ct des autres.


StackPanel orientation horizontale

<StackPanel Orientation="Horizontal"> <Button Content="Hello"/> <Button Content="World"/> <Button Content="!!!"/> </StackPanel> c Fig. 1.8 : StackPanel orientation horizontale

Canvas
Le dernier lment de la famille des Layout prsent dans ce livre est le Canvas. Son utilisation est la mme qu lpoque des WinForm. En effet, le Canvas, contrairement aux autres Layout, dlgue le positionnement de ses enfants eux-mmes. Ce positionnement est relatif leurs distances par rapport au dessus et la gauche du Canvas :

31

Le langage XAML

Canvas
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="200" Height="200"> <Canvas x:Name="LayoutRoot" Background="White" > <Button Canvas.Top="0" Canvas.Left="0" Content="0,0"/> <Button Canvas.Top="100" Canvas.Left="100" Content="Hello"/> <Button Canvas.Top="130" Canvas.Left="130" Content="World"/> <Button Canvas.Top="160" Canvas.Left="160" Content="!!!"/> </Canvas> </UserControl> c Fig. 1.9 : Exemple de Canvas

ScrollViewer
Bien que le ScrollViewer ne soit pas proprement parler un lment de Layout, il permet tout de mme de structurer linterface. Cest lui qui vous offre lopportunit dajouter des ascenseurs votre application, quils soient horizontaux ou verticaux. Sans conguration, seul lascenseur vertical est visible :
ScrollViewer sans conguration
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="200" Height="200"> <ScrollViewer x:Name="LayoutRoot" Background="White" > </ScrollViewer> </UserControl>

32

Les lments de structure

c Fig. 1.10 : ScrollViewer sans conguration

Les attributs HorizontalScrollBarVisibility et VerticalScrollBarVisibility permettent de modier cette conguration. Ils acceptent 4 valeurs diffrentes :
j j j j

Auto : lascenseur est visible uniquement si le contenu du ScrollViewer dpasse la taille du ScrollViewer. Disabled : lascenseur est visible mais inutilisable par lutilisateur. Hidden : lascenseur est cach. Visible : lascenseur est toujours visible. Si la taille du contenu dpasse la taille du ScrollViewer, lascenseur pourra tre employ par lutilisateur.
ScrollViewer avec conguration

<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="200" Height="200"> <ScrollViewer x:Name="LayoutRoot" Background="White" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"> </ScrollViewer> </UserControl>

Border
Au mme titre que le ScrollViewer, llment Border nest pas un lment de Layout. Cependant, son utilisation permet de rendre plus comprhensible la structure dune interface pour lutilisateur. Un Border est seulement une ligne qui entoure llment quil contient. Ses diffrents attributs lui donnent une exibilit incomparable et font de lui un atout majeur :

33

Le langage XAML

Diffrents exemples de Border


<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="200" Height="200"> <StackPanel x:Name="LayoutRoot" Background="White"> <Border Margin="5"> <TextBlock Text="No Param Border" Margin="5"/> </Border> <Border Margin="5" BorderBrush="Black" BorderThickness="2"> <TextBlock Text="Simple Param Border" Margin="5"/> </Border> <Border Margin="5" BorderBrush="Green" BorderThickness="2" CornerRadius="5"> <TextBlock Text="CornerRadius Border" Margin="5"/> </Border> <Border Margin="5" BorderBrush="Blue" BorderThickness="2" CornerRadius="0,0,50,0"> <TextBlock Text="Complex CornerRadius Border" Margin="5"/> </Border> <Border

Margin="5" BorderBrush="Black" Background="Aqua"> <TextBlock Text="Border with Background" Margin="5"/> </Border> </StackPanel> </UserControl> c Fig. 1.11 : Diffrents exemples de Border

34

Les lments de contenu

Les attributs Margin et CornerRadius


Remarquez lutilisation de lattribut Margin. Ce dernier, de type 1, est disponible dans la majorit des lments dinterfaces et permet de les espacer les uns des autres. Comme le CornerRadius dans sa version complexe, le Margin peut tre dnit avec 4 valeurs (Top, Right, Bottom, Left).

1.4 Les lments de contenu


Images
Llment Image est enfantin utiliser. Pour ajouter une image votre application, il suffit den indiquer le chemin relatif par rapport au nud racine de votre application ou den indiquer une URI absolue. Par exemple, pour afficher un chier wipuslogo.jpg faisant partie de votre projet Silverlight :
c Fig. 1.12 : Structure de la solution

Image avec Source relative au projet


<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="400" Height="200"> <Grid x:Name="LayoutRoot" Background="White"> <Image Source="wipuslogo.jpg"/> </Grid> </UserControl>

Ou encore, afficher une image rcupre partir dun site web :


c Fig. 1.13 : Image avec source relative au projet

35

Le langage XAML

Image avec Source absolue (URI)


<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="400" Height="200"> <Grid x:Name="LayoutRoot" Background="White"> <Image Source="http://www.wipus.com/WipusCloud.jpg"/> </Grid> </UserControl> c Fig. 1.14 : Image avec source absolue (URI)

Un des attributs les plus importants de llment Image est lattribut Stretch. Il permet de dnir comment llment va interagir avec limage pour lafficher, sil va la redimensionner, la couper, en conserver les proportions dorigine ou non.

TextBlock
Le TextBlock est la zone de texte la plus communment utilise. Elle permet de choisir toutes les caractristiques habituelles dun texte, de sa famille sa taille, en passant par sa couleur :
TextBlock
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="200" Height="200"> <StackPanel x:Name="LayoutRoot" Background="White"> <TextBlock Text="texte blablabla" TextAlignment="Center" TextWrapping="NoWrap" FontFamily="Arial" FontSize="24" FontStyle="Italic"

36

Les lments de contenu

FontWeight="Bold" Foreground="Blue"/> <TextBlock Text="texte 2" TextAlignment="Left" TextWrapping="NoWrap" FontFamily="Verena" FontSize="13" FontWeight="Bold" Foreground="Red"/> <TextBlock Text="texte 3" TextAlignment="Right" TextWrapping="NoWrap" FontFamily="Verena" FontSize="17" FontWeight="Bold" Foreground="Magenta"/> </StackPanel> </UserControl> c Fig. 1.15 : Exemple de TextBlocks

Remarquez lattribut TextWrapping. Il permet de passer automatiquement la ligne lorsque sa valeur est Wrap. Le cas chant, si la longueur du texte dpasse la taille du TextBlock, le surplus sera coup.

ProgressBar
Comme son nom lindique, la ProgressBar sert indiquer ltat dune progression, il sagit de la mme ProgressBar que celle utilise par Windows lors dune copie. Son attribut Value indique ltat actuel de la progression qui peut varier de Minimum Maximum :
ProgressBar
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="300" Height="30">

37

Le langage XAML

<StackPanel x:Name="LayoutRoot" Background="White"> <ProgressBar Name="ProgressBar1" Height="30" Maximum="100" Value="40" Minimum="0" Foreground="Green" /> </StackPanel> </UserControl> c Fig. 1.16 : ProgressBar

1.5 Les vnements et leur traitement


Avant de continuer, il est important de comprendre comment fonctionne le traitement des vnements en Silverlight, comment interagir entre le code XAML et le code C# de lapplication. Ds quun lment, tel quun bouton, est ajout au code XAML, et pour peu que cet lment contienne un attribut Name, il devient accessible dans le code C#. Ainsi pour atteindre le bouton de Name Button1 dans le code C# dune application, il suffit dcrire son nom. Tout attribut en XAML devient alors une proprit en C# :
Code XAML
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="300" Height="30"> <Grid x:Name="LayoutRoot" Background="White"> <Button Name="Boutton1" Content="un boutton"/> </Grid> </UserControl>

Code C#
using using using using using System; System.Collections.Generic; System.Linq; System.Net; System.Windows;

38

Les vnements et leur traitement

using using using using using using

System.Windows.Controls; System.Windows.Documents; System.Windows.Input; System.Windows.Media; System.Windows.Media.Animation; System.Windows.Shapes;

namespace LearnXAML { public partial class Page : UserControl { public Page() { InitializeComponent(); string temp = "" + Boutton1.Content; } } }

Pour ajouter lvnement Clic sur ce bouton, indiquez-le comme attribut dans le code XAML et ajoutez la fonction relative dans le code C#. Gnralement, cette opration est automatique :
Modication du code XAML
<Button Name="Boutton1" Content="un boutton" Clic="Boutton1_Clic"/>

Modication du code C#
using namespace LearnXAML { public partial class Page : UserControl { public Page() {} private void Boutton1_Clic(object sender, RoutedEventArgs e) { Boutton1.Content = "Merci"; } } }

39

Le langage XAML

c Fig. 1.17 : vnement Clic sur bouton

Les vnements relatifs aux entres utilisateur sont partags par la majorit des lments dinterface. Ainsi MouseEnter, MouseMove, MouseLeftButtonDown, MouseLeftButtonUp, MouseLeave, KeyUp et KeyDown se retrouvent presque partout.
Absence de clic droit en Silverlight
En Silverlight, il ny a pas dvnements lis au clic droit de la souris.

1.6 Les lments dinteractions


Button
Le bouton est llment dinteraction par excellence que nous avons dj largement utilis. Voici, pour rappel, son fonctionnement :
Code XAML dun bouton
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="100" Height="30"> <Grid x:Name="LayoutRoot" Background="White"> <Button Content="Text" Clic="Boutton1_Clic"/> </Grid> </UserControl>

Le texte dun bouton est dni dans son attribut Content. En effet, ce contenu peut tre autre chose que du texte. Par exemple, une image :
Bouton avec une image comme contenu
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML"

40

Les lments dinteractions

Width="100" Height="100"> <Grid x:Name="LayoutRoot" Background="White"> <Button Clic="Boutton1_Clic"> <Image Source="wipuslogo.jpg" Stretch="UniformToFill"/> </Button> </Grid> </UserControl> c Fig. 1.18 : Bouton avec une image comme contenu

Ou quelque chose de plus complexe tel quune grille contenant plusieurs images et un autre bouton :
Bouton contenu htroclite
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="200" Height="200"> <Grid x:Name="LayoutRoot" Background="White"> <Button Clic="Boutton1_Clic"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Image Grid.Row="0" Grid.Column="1" Source="wipuslogo.jpg" Stretch="UniformToFill"/> <Image Grid.Row="0" Grid.Column="0" Source="wipuslogo.jpg" Stretch="UniformToFill"/> <Image Grid.Row="1" Grid.Column="1" Source="wipuslogo.jpg"

41

Le langage XAML

Stretch="UniformToFill"/> <Button Grid.Row="1" Grid.Column="0" Content="Un autre"/> </Grid> </Button> </Grid> </UserControl> c Fig. 1.19 : Bouton contenu htroclite

Gnricit du principe des poupes suisses


Ce principe sapplique tous les lments XAML.

CheckBox
Une CheckBox est une bote deux ou trois tats selon sa conguration. Son tat peut tre coch, non coch ou ventuellement inconnu. Cet tat est stock sous forme dun boolen annulable dans lattribut IsChecked. Lattribut IsThreeState permet de dnir si la CheckBox peut ou non passer par ltat inconnu :
Exemple de CheckBox
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="200" Height="50"> <StackPanel x:Name="LayoutRoot" Background="White"> <CheckBox IsChecked="False" Content="Not Checked CheckBox"/>

42

Les lments dinteractions

<CheckBox IsChecked="True" Content="Checked CheckBox"/> <CheckBox IsThreeState="True" IsChecked="{x:Null}" Content="Null Checked CheckBox"/> </StackPanel> </UserControl> c Fig. 1.20 : Exemple de CheckBox

Lorsquune CheckBox passe dun tat un autre, les vnements Checked et UnChecked sont dclenchs :
Evnements Checked et UnChecked (XAML)
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="200" Height="50"> <StackPanel x:Name="LayoutRoot" Background="White"> <CheckBox IsChecked="False" Content="CheckBox" Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked"/> </StackPanel> </UserControl>

Evnements Checked et UnCheked (C#)


private void CheckBox_Checked(object sender, RoutedEventArgs e) { } private void CheckBox_Unchecked(object sender, RoutedEventArgs e) { }

ToggleButton
Un ToggleButton est une CheckBox sous forme de bouton. Son tat peut tre enfonc, non-enfonc ou ventuellement inconnu. Cet tat est stock sous forme dun boolen annulable dans lattribut IsChecked.

43

Le langage XAML

Lattribut IsThreeState permet de dnir si le ToggleButton peut ou non passer par ltat inconnu :
Exemple de ToggleButton
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="200" Height="90"> <StackPanel x:Name="LayoutRoot" Background="White"> <ToggleButton Height="30" Content="ToggleButton1" IsChecked="False"/> <ToggleButton Height="30" Content="ToggleButton2" IsChecked="True"/> <ToggleButton Height="30" Content="ToggleButton3" IsThreeState="True" IsChecked="{x:Null}"/> </StackPanel> </UserControl> c Fig. 1.21 : Exemple de ToggleButton

Lorsque ltat dun ToggleButton change, les vnements Checked et UnChecked sont dclenchs :
Evnements dtat dun ToggleButton
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="200" Height="90"> <StackPanel x:Name="LayoutRoot" Background="White"> <ToggleButton Height="30" Content="ToggleButton1" IsChecked="False" Checked="ToggleButton_Checked" Unchecked="ToggleButton_Unchecked"/> </StackPanel> </UserControl>

44

Les lments dinteractions

RadioButton
Les RadioButtons fonctionnent de la mme faon que les ToggleButtons. Eux aussi possdent les attributs IsChecked, IsThreeState, Content, etc. Cependant, ils offrent une fonctionnalit supplmentaire les rendant intressants : lattribut GroupName. Parmi un ensemble de plusieurs RadioButtons partageant le mme GroupName, seul un RadioButton pourra avoir son tat IsCheked vrai. Si un autre de ces RadioButtons passe ltat Checked, automatiquement, le prcdent RadioButton Checked deviendra UnChecked :
Exemple de RadioButtons
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="200" Height="130"> <StackPanel x:Name="LayoutRoot" Background="White"> <Border BorderBrush="Black" BorderThickness="1" CornerRadius="5" Margin="5"> <StackPanel> <RadioButton GroupName="Group1" Content="Radio1.1"/> <RadioButton GroupName="Group1" Content="Radio1.2" IsChecked="True"/> <RadioButton GroupName="Group1" Content="Radio1.3"/> </StackPanel> </Border> <Border BorderBrush="Black" BorderThickness="1" CornerRadius="5" Margin="5"> <StackPanel> <RadioButton GroupName="Group2" Content="Radio2.1" IsChecked="True"/> <RadioButton GroupName="Group2" Content="Radio2.2"/> <RadioButton GroupName="Group2" Content="Radio2.3"/> </StackPanel> </Border> </StackPanel> </UserControl>

45

Le langage XAML

c Fig. 1.22 : Exemple de RadioButtons

De mme que pour le ToggleButton, les vnements Checked et UnChecked sont dclenchs lorsquun RadioButton change dtat.

TextBox
lment de saisie de texte, une TextBox offre les mmes attributs quun TextBlock :
Exemple de TextBox
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="200" Height="30"> <StackPanel x:Name="LayoutRoot" Background="White"> <TextBox FontFamily="Arial" Foreground="Black" Text="(Please insert text here)" Margin="5" TextChanged="TextBox_TextChanged"/> </StackPanel> </UserControl> c Fig. 1.23 : Exemple de TextBox

Lvnement TextChanged est dclench lorsque lutilisateur a ni dditer le texte contenu dans la TextBox. Cela tant, hormis pour une validation, le texte entr par lutilisateur sera utilis lors dun autre vnement, tel que le clic sur un bouton adjacent. Pour rcuprer le texte contenu dans ce TextBox partir du code C#, il suffit den utiliser la proprit Text.

46

Les lments dinteractions

PasswordBox
Une PasswordBox est une TextBox naffichant pas les caractres frapps au clavier mais des caractres de remplacements :
Exemple de PasswordBox
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="200" Height="30"> <StackPanel x:Name="LayoutRoot" Background="White"> <PasswordBox FontFamily="Arial" Foreground="Black" Password="(Please insert text here)" Margin="5" PasswordChanged="PasswordBox_PasswordChanged" PasswordChar="*"/> </StackPanel> </UserControl> c Fig. 1.24 : Exemple de PasswordBox

Attention, le texte contenu dans une PasswordBox porte le nom de Password et non de Text. Il en va de mme pour la proprit dans le code C#. Lattribut PasswordChar donne au dveloppeur lopportunit de choisir un caractre de remplacement diffrent de celui de la plateforme dorigine.

ListBox et ListBoxItem
La ListBox est un lment compos dun StackPanel et dun ScrollViewer. Mais ce nest pas tout, elle implmente dorigine une interface lui permettant de grer une collection ditems slectionnables :
ListBox contenant des ListBoxItems
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="200" Height="200"> <Grid x:Name="LayoutRoot" Background="White"> <ListBox>

47

Le langage XAML

<ListBoxItem <ListBoxItem <ListBoxItem <ListBoxItem </ListBox> </Grid> </UserControl>

Content="ListBoxItem1"/> Content="ListBoxItem2"/> Content="ListBoxItem3"/> Content="ListBoxItem4"/>

c Fig. 1.25 : ListBox contenant des ListBoxItems

Les lments utiliss dans cet exemple comme items sont des ListBoxItems. Bien que les ListBoxItems soient prvus spcialement pour servir ditems dans une ListBox, tout autre lment de la plateforme peut les substituer. Ainsi, il est possible davoir une ListBox contenant comme items des boutons, des autres ListBox, des lments de Layout contenant eux-mmes dautres lments enfants, etc. :
ListBox contenant des lments htroclites
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="200" Height="200"> <Grid x:Name="LayoutRoot" Background="White"> <ListBox> <Button Content="ListBoxItem1"/> <ListBox> <ListBoxItem Content="ListBoxItem2.1"/> <ListBoxItem Content="ListBoxItem2.2"/> </ListBox> <StackPanel Orientation="Horizontal"> <ListBoxItem Content="ListBoxItem3.1"/> <Button Content="ListBoxItem3.1"/> </StackPanel> <ListBoxItem Content="ListBoxItem4"/> </ListBox> </Grid> </UserControl>

48

Les lments dinteractions

c Fig. 1.26 : ListBox contenant des lments htroclites

Lorsque la slection passe dun lment un autre, lvnement SelectedItemChanged est dclench.

ComboBox et ComboBoxItem
Une ComboBox est une ListBox prsente sous forme dune liste droulante. Son utilisation est donc semblable celle dune ListBox :
Exemple de ComboBox
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="200" Height="40"> <Grid x:Name="LayoutRoot" Background="White"> <ComboBox Height="30" Margin="5"> <ComboBoxItem Content="ComboBoxItem1"/> <ComboBoxItem Content="ComboBoxItem2"/> <ComboBoxItem Content="ComboBoxItem3" IsSelected="True"/> <ComboBoxItem Content="ComboBoxItem4"/> </ComboBox> </Grid> </UserControl> c Fig. 1.27 : Exemple de ComboBox

Les lments utiliss dans cet exemple sont des ComboBoxItems, mais comme une ListBox, les ComboBox acceptent nimporte quels lments comme items.

49

Le langage XAML

Il est donc possible, par exemple, de construire une ComboBox dimages, de boutons et dinformations diverses runies :
Exemple de ComboBox contenu htroclite
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="200" Height="40"> <Grid x:Name="LayoutRoot" Background="White"> <ComboBox Height="30" Margin="5"> <Image Source="wipuslogo.jpg" Height="100" Width="100" Stretch="UniformToFill"/> <Button Content="ComboBoxItem2"/> <StackPanel Orientation="Vertical"> <TextBlock Text="ComboBoxItem3" /> <Button Content="ComboBoxItem4"/> </StackPanel> <Image Source="http://www.wipus.com/WipusCloud.jpg" Height="100" Width="100" Stretch="UniformToFill"/> </ComboBox> </Grid> </UserControl> c Fig. 1.28 : Exemple de ComboBox contenu htroclite

Lorsque la slection passe dun lment un autre, lvnement SelectedItemChanged est dclench.

50

Autres lments utiles

Slider
Un Slider est un curseur se dplaant le long dune ligne pour permettre lutilisateur dindiquer une valeur numrique de faon visuelle. La valeur (Value) indique par le curseur varie de lattribut Minimum gauche de la ligne lattribut Maximum droite de la ligne :
Exemple de Slider
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="200" Height="40"> <Grid x:Name="LayoutRoot" Background="White"> <Slider Maximum="100" Minimum="0" Value="40" SmallChange="1" LargeChange="10" /> </Grid> </UserControl> c Fig. 1.29 : Exemple de Slider

Les attributs SmallChange et LargeChange reprsentent respectivement la valeur ajoute ou retire la valeur en cours lors dun dplacement par la souris ou le clavier. Lvnement ValueChanged est dclench lorsque la valeur indique par le curseur est modie par lutilisateur.

1.7 Autres lments utiles


Line
La plateforme noffre pas que des lments dinterface mais aussi des lments graphiques tels que les lignes, les polygones, les rectangles, etc. Bien que ces lments soient plus utiles aux designers quaux dveloppeurs, il est intressant de comprendre leurs fonctionnements :

51

Le langage XAML

Exemple de Ligne
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="200" Height="40"> <Grid x:Name="LayoutRoot" Background="White"> <Line X1="5" Y1="10" X2="195" Y2="30" Stroke="Black" StrokeThickness="3"/> <Line X1="5" Y1="30" X2="195" Y2="30" Stroke="Magenta" StrokeThickness="3"/> </Grid> </UserControl> c Fig. 1.30 : Exemple de ligne

Dans cet exemple, deux lignes sont dessines grce aux positions relatives (en pixels) de leurs points dorigine et de destination par rapport llment qui les contient. Ces deux points sont respectivement {X1,Y1} et {X2,Y2}.

Rectangle
Dans le mme ordre dides, un rectangle est dni par ses dimensions. Les attributs RadiusX et RadiusY, quant eux, permettent den arrondir les bords :
Exemple de Rectangle
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="200" Height="60"> <StackPanel x:Name="LayoutRoot" Background="White"> <Rectangle Fill="Magenta" Margin="5" Height="20" Width="100" MouseLeftButtonDown="Rectangle_MouseLeftButtonDown"/> <Rectangle Fill="Blue" Margin="5" Height="20" RadiusX="30" RadiusY="30"/> </StackPanel> </UserControl>

52

Autres lments utiles

c Fig. 1.31 : Exemple de Rectangle

Interaction utilisateur des lments graphiques


Souvenez-vous que tout lment graphique garde une possibilit dinteraction avec la souris et/ou le clavier. Dans cet exemple, nous retrouvons lvnement MouseLeftButtonDown.

Attention, un rectangle est un lment gomtrique et non un lment dinterface ; il naccepte donc pas de contenu. Le code suivant ne fonctionnera pas :
Rectangle avec contenu
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="200" Height="60"> <StackPanel x:Name="LayoutRoot" Background="White"> <Rectangle Fill="Magenta" Margin="5" Height="20" Width="100" MouseLeftButtonDown="Rectangle_MouseLeftButtonDown"> <Button/> </Rectangle> </StackPanel> </UserControl>

Pour obtenir un rsultat semblable qui fonctionne, utilisez un Border avec Background.

Popup
En Silverlight, un lment Popup nest pas un popup proprement parler tel quon lentend dans le monde du Web. En effet, il ne sagit en aucun cas dune fentre supplmentaire qui souvre hors du navigateur dans lequel sexcute lapplication Silverlight. Un popup Silverlight nest rien dautre quun lment dinterface indpendant de la structure solide dnie par les lments de Layout de lapplication. Il saffiche librement au-dessus de tout autre contrle.

53

Le langage XAML

Dans cet exemple, un bouton contrle louverture dun popup. Ce popup contient comme lments enfants un texte et un bouton dclenchant sa fermeture :
Exemple de Popup (XAML)
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="200" Height="60"> <Grid x:Name="LayoutRoot" Background="White"> <Button Height="20" Width="100" Clic="OpenPopup" Content="Open Popup"/> <Popup Name="MyPopup" VerticalAlignment="Center" HorizontalAlignment="Center"> <Border BorderBrush="Black" BorderThickness="2" Background="Beige"> <StackPanel Orientation="Horizontal"> <TextBlock Text="Text Popup" Margin="5"/> <Button Margin="5" Clic="ClosePopup" Content="x"/> </StackPanel> </Border> </Popup> </Grid> </UserControl>

Ce sont sur les vnements Clic des deux boutons que lon assignera une valeur diffrente lattribut IsOpen du popup. Lorsque cet attribut est vrai, le popup est affich :
Exemple de Popup (C#)
using using using using using using using using using System; System.Collections.Generic; System.Linq; System.Net; System.Windows; System.Windows.Controls; System.Windows.Documents; System.Windows.Input; System.Windows.Media;

54

Premire approche du DataBinding

using System.Windows.Media.Animation; using System.Windows.Shapes; namespace LearnXAML { public partial class Page : UserControl { public Page() { InitializeComponent(); } private void OpenPopup(object sender, RoutedEventArgs e) { MyPopup.IsOpen = true; } private void ClosePopup(object sender, RoutedEventArgs e) { MyPopup.IsOpen = false; } } }

c Fig. 1.32 : Exemple de Popup

1.8 Premire approche du DataBinding


Le binding est la mthode de liaison de donnes entre le code applicatif (code C#) et le code XAML. Grce cette mthode, il devient ais dafficher un set de donnes lutilisateur tout en lui proposant une interaction directe avec elles, sans devoir crire de nombreuses lignes de code. Pour lier des donnes une interface, il nous faut dabord crer ces donnes. Si vous ntes pas habitu la programmation oriente objets, reportez-vous lannexe 2 de ce livre, Introduction au C#.

55

Le langage XAML

Lapplication que nous allons raliser ici se doit de grer une liste dtudiants, rpartis dans plusieurs cours. Un tudiant est dni par son Nom, son Prnom et son ge :
Etudiant.cs
using using using using using using using using using using System; System.Net; System.Windows; System.Windows.Controls; System.Windows.Documents; System.Windows.Ink; System.Windows.Input; System.Windows.Media; System.Windows.Media.Animation; System.Windows.Shapes;

namespace LearnXAML { public class Etudiant { private string nom; public string Nom { get { return nom; } set { nom = value; } } private string prenom; public string Prenom { get { return prenom; } set { prenom = value; } } private int age; public int Age { get { return age; } set { age = value; } } public Etudiant() { }

56

Premire approche du DataBinding

} }

Un cours, quant lui, est dni par son Nom et comprend une liste dtudiants :
Cours.cs
using using using using using using using using using using using System; System.Net; System.Windows; System.Windows.Controls; System.Windows.Documents; System.Windows.Ink; System.Windows.Input; System.Windows.Media; System.Windows.Media.Animation; System.Windows.Shapes; System.Collections.Generic;

namespace LearnXAML { public class Cours { private string nom; public string Nom { get { return nom; } set { nom = value; } } private List<Etudiant> etudiants; public List<Etudiant> Etudiants { get { return etudiants; } set { etudiants = value; } } public Cours() { } } }

57

Le langage XAML

Ajoutons au code applicatif de cette application la dclaration en dur dune liste de deux cours comprenant chacun quelques tudiants :
Dclaration en dure dune liste dtudiant
using using using using using using using using using using using System; System.Collections.Generic; System.Linq; System.Net; System.Windows; System.Windows.Controls; System.Windows.Documents; System.Windows.Input; System.Windows.Media; System.Windows.Media.Animation; System.Windows.Shapes;

namespace LearnXAML { public partial class Page : UserControl { private List<Cours> ListeDeCours; public Page() { InitializeComponent(); #region HardCode ListeDeCours ListeDeCours = new List<Cours>() { new Cours() { Nom = "Declamation", Etudiants = new List<Etudiant>() { new Etudiant() {Prenom="Laurane", Nom="D.", Age=19 }, new Etudiant() {Prenom="Ma", Nom="H.", Age=18 }, new Etudiant() {Prenom="Dovy", Nom="F.", Age=21 } } }, new Cours() { Nom = "Sculpture", Etudiants = new List<Etudiant>() { new Etudiant() {Prenom="Adelade", Nom="A.", Age=19 },

58

Premire approche du DataBinding

new Etudiant() {Prenom="Klintes", Nom="T.", Age=20 }, new Etudiant() {Prenom="Kaphilis", Nom="A.", Age=20 }, new Etudiant() {Prenom="Jade", Nom="G.", Age=14 } } } }; #endregion HarCode ListeDeCours } } }

Dans cette dclaration, nous retrouvons la structure suivante :


j j

un cours de dclamation dont les lves sont Laurane, Ma et Dovy ; un cours de sculpture dont les lves sont Adelade, Klintes, Kaphilis et Jade.

Du ct de la dnition de linterface, dclarons une ListBox :


chier XAML
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="400" Height="300"> <Grid x:Name="LayoutRoot" Background="White"> <ListBox Name="CoursListBox"/> </Grid> </UserControl>

Pour lier la liste de cours cette ListBox, il suffit dajouter dans le code applicatif, sous la dclaration en dur :
Ajout au code applicatif
CoursListBox.ItemsSource = ListeDeCours;

Cette ligne de code ordonne la ListeBox CoursListBox dafficher le contenu de la liste ListeDeCours.

59

Le langage XAML

Voici le rsultat :
c Fig. 1.33 : DataBinding direct

Bien que cela ne plante pas et que nous dtections dj 2 items diffrents dans cette ListBox, linterface obtenue est loin dtre satisfaisante pour un utilisateur nal. Pourquoi ? La plateforme .Net, en labsence dinformations lui dictant comment afficher un objet, en appelle la mthode ToString. Cette mthode, prsente intrinsquement dans chaque objet, retourne une chane de caractres comprenant le nom de la classe de cet objet. Le premier contournement de ce problme est donc la surcharge de cette mthode :
Ajout Cours.cs
public override string ToString() { string ret = this.nom; if(etudiants == null) return ret; ret += "\t("; foreach(Etudiant e in etudiants) ret += " "+e.Prenom; ret += " )"; return ret; }

60

Premire approche du DataBinding

Grce cette simple modication, notre affichage de donnes est dj bien plus agrable voir :
c Fig. 1.34 : DataBinding avec surcharge de ToString()

DataTemplates
Voici la faon la plus intressante de rendre lisible toute notre liste de cours ainsi que ses lves respectifs. Un DataTemplate est une structure XAML qui sera applique chacun des items dune ListBox donne. Ici le changement se fait uniquement dans le code XAML, lindpendance avec le code applicatif est parfaite. Ce qui permet de dlguer plus facilement ce travail aux designers et intgrateurs. La ListBox possde un attribut du nom de ItemTemplate qui permet de dnir quel Template utiliser pour afficher les items :
Exemple de DataTemplate 1
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="400" Height="300"> <Grid x:Name="LayoutRoot" Background="White"> <ListBox Name="CoursListBox"> <ListBox.ItemTemplate> <DataTemplate> <Border CornerRadius="2" Margin="3" BorderBrush="Black" BorderThickness="1"> <TextBlock Text="{Binding Path=Nom}" Margin="5"/> </Border>

61

Le langage XAML

</DataTemplate> </ListBox.ItemTemplate> </ListBox> </Grid> </UserControl> c Fig. 1.35 : Exemple de DataTemplate 1

Pour prciser quelles proprits des objets forment la source du binding, il faut afficher. XAML offre une mthode de navigation par chane de caractres travers ces derniers. Ainsi le code {Binding Path=Nom} dans notre exemple, stipule que pour chaque Cours, linterface doit afficher la proprit Nom. En ce qui concerne la liste dlves, il faut ajouter ce DataTemplate une nouvelle liste, dont lItemSource est la proprit Etudiants de chaque cours :
Exemple de DataTemplate2
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="400" Height="300"> <Grid x:Name="LayoutRoot" Background="White"> <ListBox Name="CoursListBox"> <ListBox.ItemTemplate> <DataTemplate> <Border CornerRadius="2" Margin="3" BorderBrush="Black" BorderThickness="1"> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Path=Nom}" Margin="5"/> <ListBox ItemsSource="{Binding Path=Etudiants}"/> </StackPanel> </Border> </DataTemplate> </ListBox.ItemTemplate>

62

Premire approche du DataBinding

</ListBox> </Grid> </UserControl> c Fig. 1.36 : Exemple de DataTemplate2

Un nouveau DataTemplate doit ensuite tre cr, cette fois non pour les cours mais pour les tudiants :
Exemple de DataTemplate 3
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="400" Height="300"> <Grid x:Name="LayoutRoot" Background="White"> <ListBox Name="CoursListBox"> <ListBox.ItemTemplate> <DataTemplate> <Border CornerRadius="2" Margin="3" BorderBrush="Black" BorderThickness="1"> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Path=Nom}" Margin="5"/> <ListBox ItemsSource="{Binding Path=Etudiants}"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Path=Prenom}" Margin="5"/> <TextBlock Text="{Binding Path=Nom}" Margin="5"/> <TextBlock Text="{Binding Path=Age}" Margin="5"/> </StackPanel>

63

Le langage XAML

</DataTemplate> </ListBox.ItemTemplate> </ListBox> </StackPanel> </Border> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Grid> </UserControl> c Fig. 1.37 : Exemple de DataTemplate 3

Cette mthode donne un rsultat surprenant. Cependant, le code, lui, est des plus immondes. Lire un code XAML de ce genre est presque impossible ds quil grandit un peu. Rsoudre ce problme de clart invoque lutilisation des Ressources XAML. Chaque lment XAML a la possibilit dtre lhte dune collection de ressources. Ces ressources seront accessibles tous les lments enfants de llment hte grce leur nom. (En loccurrence, grce leur x:Key.) Le code XAML de lexemple prcdent, agrment de lutilisation des ressources, devient :
Exemple de DataTemplate en Ressources
<UserControl x:Class="LearnXAML.Page" xmlns="http://schemas.microsoft.com/winfx/2006/XAML/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/XAML" Width="400" Height="300">

64

Premire approche du DataBinding

<UserControl.Resources> <DataTemplate x:Key="EtudiantDataTemplate"> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Path=Prenom}" Margin="5"/> <TextBlock Text="{Binding Path=Nom}" Margin="5"/> <TextBlock Text="{Binding Path=Age}" Margin="5"/> </StackPanel> </DataTemplate> <DataTemplate x:Key="CoursDataTemplate"> <Border CornerRadius="2" Margin="3" BorderBrush="Black" BorderThickness="1"> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Path=Nom}" Margin="5"/> <ListBox ItemsSource="{Binding Path=Etudiants}" ItemTemplate="{StaticResource EtudiantDataTemplate}"/> </StackPanel> </Border> </DataTemplate> </UserControl.Resources> <Grid x:Name="LayoutRoot" Background="White"> <ListBox Name="CoursListBox" ItemTemplate="{StaticResource CoursDataTemplate}"/> </Grid> </UserControl>

Non seulement la lisibilit du code sest beaucoup amliore, mais en plus, ces DataTemplates sont maintenant rutilisables dautres endroits de notre interface, sans quon ait besoin de les copier.
Diffrence entre StaticResource et DynamicResource
Remarquez lutilisation du mot StaticResource. Une ressource statique est une ressource dnie dans le mme document et en amont de son utilisation. Ceci explique que EtudiantDatatTemplate soit dni avant CoursDataTemplate. Une alternative cette structure rigoureuse est dutiliser DynamicResource. Une ressource dynamique peut tre dnie nimporte o dans lapplication, mme dans un autre chier.

65

Le langage XAML

ValueConverter
Dans lexemple prcdent, une proprit C# est affiche telle quelle lors de son binding sur linterface. Ainsi, le nom Lauranne est pleinement lisible. Cependant ce nest pas toujours lidal. Si nous ajoutons la proprit EstDou de type booleen aux tudiants, le rsultat de son binding sera soit TRUE, soit FALSE :
Ajout Etudiant.cs
private bool estDou; public bool EstDou { get { return estDou; } set { estDou = value; } }

Une fois de plus, la mthode ToString du type booleen sert la plateforme.


c Fig. 1.38 : Binding sans ValueConverter

Comme il nest pas possible de surcharger cette mthode dans un type primitif, une autre solution soffre nous : un ValueConverter. Un ValueConverter est une classe C# qui, comme son nom lindique, transforme une valeur, quelle quelle soit, en une autre valeur. Ainsi dans le cas prsent, nous allons crire un ValueConverteur transformant la valeur TRUE en est un lve dou, et la valeur FALSE en nest pas un lve dou.

66

Premire approche du DataBinding

Linterface IValueConverter fait dune classe un ValueConverteur. Son implmentation demande deux mthodes :
j j

Convert convertit la valeur source en valeur afficher. ConvertBack convertit la valeur afficher en valeur source.
EstDouValueConverter.cs

using using using using using using using using using using using using

System; System.Net; System.Windows; System.Windows.Controls; System.Windows.Documents; System.Windows.Ink; System.Windows.Input; System.Windows.Media; System.Windows.Media.Animation; System.Windows.Shapes; System.Windows.Data; System.Globalization;

namespace LearnXaml { public class EstDouValueConverter : IValueConverter { private const string Dou = "est un lve dou"; private const string NonDou = "nest pas un lve dou"; #region IValueConverter Membres public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { bool? EstDou = (value as bool?); if (EstDou == null || EstDou.HasValue == false) throw new InvalidCastException( "EstDouValueConverter.Convert value is not bool or is null"); if (EstDou.Value) { return Dou; } else { return NonDou;

67

Le langage XAML

} } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { string EstDou = value.ToString(); switch (EstDou) { case Dou: return true; case NonDou: return false; default: throw new InvalidCastException( "EstDouValueConverter.ConvertBack value incorrecte" + value.ToString()); } } #endregion } }

Pour utiliser le ValueConverter EstDouValueConverter dans un binding, plusieurs tapes doivent tre respectes :
j j

j j

ajouter le code du ValueConverter la solution Silverlight (ou en ajouter la rfrence dune assembly compile pralablement pour Silverlight) ; ajouter au chier XAML un using (xmls) pointant vers lespace de noms du ValueConverter (dans ce cas, lespace de noms est le mme que celui de lapplication mais cela peut varier) ; crer une instance de ce ValueConverter dans les ressources de lapplication ; spcier au binding dutiliser cette instance de ValueConverter.
Modication du chier XAML

<UserControl x:Class="LearnXaml.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:MyApp="clr-namespace:LearnXaml" Width="400" Height="300">

68

Premire approche du DataBinding

<UserControl.Resources> <MyApp:EstDouValueConverter x:Key="estDouValueConverter"/> <DataTemplate x:Key="EtudiantDataTemplate"> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Path=Prenom}" Margin="5"/> <TextBlock Text="{Binding Path=Nom}" Margin="5"/> <TextBlock Text="{Binding Path=Age}" Margin="5"/> <TextBlock Text="{Binding Path=EstDou, Converter={StaticResource estDouValueConverter}}" Margin="5" /> </StackPanel> </DataTemplate> <DataTemplate x:Key="CoursDataTemplate"> <Border CornerRadius="2" Margin="3" BorderBrush="Black" BorderThickness="1"> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Path=Nom}" Margin="5"/> <ListBox ItemsSource="{Binding Path=Etudiants}" ItemTemplate="{StaticResource EtudiantDataTemplate}"/> </StackPanel> </Border> </DataTemplate> </UserControl.Resources> <Grid x:Name="LayoutRoot" Background="White"> <ListBox Name="CoursListBox" ItemTemplate="{StaticResource CoursDataTemplate}"/> </Grid> </UserControl> c Fig. 1.39 : Binding avec ValueConverter

69

Le langage XAML

Attributs dun ValueConverter


Il est parfois utile de laisser au charg dinterface (celui qui crit le XAML) la possibilit de congurer un ValueConverter sans devoir passer par le code C#. Cest le cas dun RatioValueConverter multipliant simplement un nombre entier par un autre. Il serait aberrant de devoir crer un RatioValueConverter par multiplication souhaite. Ajouter un attribut congurable en XAML se fait en ajoutant une proprit publique dans la classe du ValueConverter, ainsi quil est montr dans le code suivant avec la proprit Ratio :
RatioConverter.cs
using using using using using using using using using using using using System; System.Net; System.Windows; System.Windows.Controls; System.Windows.Documents; System.Windows.Ink; System.Windows.Input; System.Windows.Media; System.Windows.Media.Animation; System.Windows.Shapes; System.Windows.Data; System.Globalization;

namespace LearnXaml { public class RatioValueConverter : IValueConverter { private int ratio = 5; public int Ratio { get { return ratio; } set { ratio = value; } }

public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return (int)value * ratio; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)

70

Premire approche du DataBinding

{ return (int)value / ratio; } } }

Il est alors possible dutiliser ce RatioConverter dans le code XAML pour, par exemple, transformer lge (en annes) des tudiants en un nombre de mois :
Modication du code XAML
<MyApp:EstDouValueConverter x:Key="estDouValueConverter"/> <MyApp:RatioValueConverter x:Key="AnneeEnMoisConverter" Ratio="12"/> <DataTemplate x:Key="EtudiantDataTemplate"> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Path=Prenom}" Margin="5"/> <TextBlock Text="{Binding Path=Nom}" Margin="5"/> <TextBlock Text="{Binding Path=Age, Converter={StaticResource AnneeEnMoisConverter}}" Margin="5"/> <TextBlock Text="{Binding Path=EstDou, Converter={StaticResource estDouValueConverter}}" Margin="5" /> </StackPanel> </DataTemplate> c Fig. 1.40 : Binding avec RatioValueConverter

71

Le langage XAML

Le chier Generic.XAML
Comme nous le voyons dans lexemple suivi tout au long ce chapitre, le nombre de ressources de notre page XAML ne cesse de grandir. Pour viter un code trop long et rendre ces ressources accessibles depuis nimporte quel chier XAML de notre application, il suffit de crer un chier XAML du nom de Generic.XAML dans le dossier Themes de larborescence de la solution Silverlight.
c Fig. 1.41 : Arborescence de solution pour le chier Generic.XAML

Attention, dans les proprits du chier Generic.xaml, le mode de compilation doit tre chang de Page Resource.

c Fig. 1.42 : Modication des proprits de Generic.xaml

Rednir la structure dune ListBox


Nous avons vu comment changer laspect des items contenus dans une ListBox lors dun binding. Il est galement possible de forcer lordre dans lequel ces items vont safficher. De base, pour une ListBox, les items sont affichs dans un StackPanel dont lorientation est verticale. Pour changer cela, il suffit de surcharger lattribut ItemPanel de la ListBox :

72

Colorez votre application grce aux Brushes et aux Gradients

Surchage de lattribut ItemPanel


<UserControl x:Class="LearnXaml.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:MyApp="clr-namespace:LearnXaml" Width="400" Height="300"> <UserControl.Resources> ... </UserControl.Resources> <Grid x:Name="LayoutRoot" Background="White"> <ListBox Name="CoursListBox" ItemTemplate="{StaticResource CoursDataTemplate}" > <ListBox.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Horizontal"/> </ItemsPanelTemplate> </ListBox.ItemsPanel> </ListBox> </Grid> </UserControl> c Fig. 1.43 : Surcharge de lattribut ItemPanel

1.9 Colorez votre application grce aux Brushes et aux Gradients


Ajouter de la couleur vos applications Silverlight se fait grce aux Brushes. Un Brush est la reprsentation dune couleur. Nous en avons souvent rencontr dans les exemples prcdents de ce livre.

73

Le langage XAML

En outre, dans le code suivant, White est un Brush :


Exemple dun Brush
<UserControl x:Class="LearnXaml.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:MyApp="clr-namespace:LearnXaml" Width="400" Height="100"> <Grid x:Name="LayoutRoot" Background="White"> </Grid> </UserControl>

De nombreux lments dinterface ont la possibilit dtre congurs pour utiliser dautres couleurs que leurs couleurs dorigines. Il sagit gnralement des attributs Background, Foreground, Stoke, BorderColor, etc. Mais il y a mieux, en plus daccepter des Brushes comme valeurs, ces attributs acceptent aussi des Gradients. Les Gradients sont des collections de couleurs et doffsets permettant de crer un dgrad. La classe Gradient est une classe abstraite dont dcoule quelques types de Gradients diffrents et ne pouvant tre utiliss directement en XAML.

LinearGradientBrush
Le type de Gradient le plus simple est le LinearGradiantBrush :
Exemple de LinearGradientBrush
<UserControl x:Class="LearnXaml.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:MyApp="clr-namespace:LearnXaml" Width="400" Height="100"> <Grid x:Name="LayoutRoot"> <Grid.Background> <LinearGradientBrush> <GradientStop Offset="0" Color="White"/> <GradientStop Offset="1" Color="Black"/> </LinearGradientBrush> </Grid.Background> </Grid> </UserControl>

74

Colorez votre application grce aux Brushes et aux Gradients

c Fig. 1.44 : Exemple de LinearGradientBrush

Le LinearGradientBrush est une fonction linaire dont les couleurs varient proportionnellement un offset. Dans ce cas, le pinceau va varier du blanc x = 0 au noir x = 100. Il est possible dajouter plus de couleurs dans un LinearGradientBrush la fonction est alors divise en un set de segments de taille suffisante pour afficher le dgrad selon les crits du XAML :
Exemple de LinearGradientBrush dcoup
<UserControl x:Class="LearnXaml.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:MyApp="clr-namespace:LearnXaml" Width="400" Height="100"> <Grid x:Name="LayoutRoot"> <Grid.Background> <LinearGradientBrush> <GradientStop Offset="0" Color="White"/> <GradientStop Offset="0.3" Color="Black"/> <GradientStop Offset="0.5" Color="White"/> <GradientStop Offset="0.7" Color="Black"/> <GradientStop Offset="0.9" Color="Black"/> <GradientStop Offset="1" Color="White"/> </LinearGradientBrush> </Grid.Background> </Grid> </UserControl> c Fig. 1.45 : Exemple de LinearGradientBrush dcoup

75

Le langage XAML

Lorientation du dgrad, ici de gauche droite, est elle aussi modiable. Le dgrad commence son attribut StartPoint et nit son attribut EndPoint. Chacun de ces attributs sont des points dnis par deux valeurs : X et Y en pourcentage de llment colorier. En modiant un peu ces attributs, nous pouvons crer un dgrad vertical :
LinearGradientBrush vertical
<UserControl x:Class="LearnXaml.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:MyApp="clr-namespace:LearnXaml" Width="400" Height="100"> <Grid x:Name="LayoutRoot"> <Grid.Background> <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> <GradientStop Offset="0" Color="White"/> <GradientStop Offset="1" Color="Black"/> </LinearGradientBrush> </Grid.Background> </Grid> </UserControl> c Fig. 1.46 : LinearGradientBrush vertical

RadialGradientBrush
Un RadialGradientBrush agit de la mme manire quun LinearGadientBrush mais en dcrivant des cercles :
Exemple de RadialGradientBrush
<UserControl x:Class="LearnXaml.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:MyApp="clr-namespace:LearnXaml" Width="400" Height="100"> <Grid x:Name="LayoutRoot"> <Grid.Background> <RadialGradientBrush>

76

Colorez votre application grce aux Brushes et aux Gradients

<GradientStop Offset="0" Color="White"/> <GradientStop Offset="0.3" Color="Black"/> <GradientStop Offset="0.5" Color="White"/> <GradientStop Offset="0.7" Color="Black"/> <GradientStop Offset="0.9" Color="Black"/> <GradientStop Offset="1" Color="White"/> </RadialGradientBrush> </Grid.Background> </Grid> </UserControl> c Fig. 1.47 : Exemple de RadialGradientBrush

Contrairement au LinearGradientBrush, ce sont les attributs Center et GradientOrigin qui permettent de changer la source et lorientation du dgrad :
RadialGradientBrush dcentr
<UserControl x:Class="LearnXaml.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:MyApp="clr-namespace:LearnXaml" Width="400" Height="100"> <Grid x:Name="LayoutRoot"> <Grid.Background> <RadialGradientBrush Center="0.8,0.8" GradientOrigin="0.8,0.8"> <GradientStop Offset="0" Color="White"/> <GradientStop Offset="1" Color="Black"/> </RadialGradientBrush> </Grid.Background> </Grid> </UserControl> c Fig. 1.48 : RadialGradientBrush dcentr

77

Le langage XAML

ImageBrush
Les ImageBrushes vous permettent dutiliser une image la place dun Brush. On les emploie de la mme faon que llment Image :
Exemple de ImageBrush
<UserControl x:Class="LearnXaml.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:MyApp="clr-namespace:LearnXaml" Width="400" Height="100"> <Grid x:Name="LayoutRoot"> <Grid.Background> <ImageBrush ImageSource="wipuslogo.jpg" Stretch="None"/> </Grid.Background> </Grid> </UserControl> c Fig. 1.49 : Exemple dImageBrush

Lutilit de ce genre de GradientBrush est vidente lorsquon lemploie sur des attributs plus surprenants de la plateforme Silverlight. Dans lexemple qui suit, le mme ImageBrush est utilis sur lattribut Foreground dune TextBox :
Exemple dImageBrush sur lattribut Foreground
<UserControl x:Class="LearnXaml.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:MyApp="clr-namespace:LearnXaml" Width="400" Height="100"> <Grid x:Name="LayoutRoot" Background="Black"> <TextBlock Text="WIPUS" FontSize="100" HorizontalAlignment="Center" VerticalAlignment="Center"> <TextBlock.Foreground> <ImageBrush ImageSource="wipuslogo.jpg" Stretch="UniformToFill"/> </TextBlock.Foreground>

78

Animez votre application grce aux StoryBoard

</TextBlock> </Grid> </UserControl> c Fig. 1.50 : Exemple dImageBrush sur lattribut Foreground

1.10 Animez votre application grce aux StoryBoard


En XAML, il est possible danimer nimporte quoi, nimporte comment. En effet, par animation, le XAML nentend pas seulement mouvement dun objet mais bien variation dune valeur partir dune valeur initiale jusqu une valeur nale sur une priode de temps donne. Ainsi, bien quil soit possible de faire bouger un lment grce une animation, il est galement envisageable den faire varier sa couleur, sa taille, etc. Plusieurs animations peuvent tre runies en un ensemble appel StoryBoard, scnario en franais. Pour commencer en beaut, voici un scnario qui va changer la taille du texte dun TexBlock et dplacer la position dun rectangle :
Les animations Silverlight (XAML)
<UserControl x:Class="LearnXaml.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:MyApp="clr-namespace:LearnXaml" Width="400" Height="100"> <Grid x:Name="LayoutRoot" Background="Black"> <TextBlock Name="HeodeLabel" MouseLeftButtonDown="HeodeLabel_Clic" Text="Heode" FontSize="10" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White"> </TextBlock> <Canvas> <Rectangle Fill="LimeGreen" Name="ProgressRect" Height="20"

79

Le langage XAML

Width="40" Canvas.Top="80" Canvas.Left="0" RadiusX="10" RadiusY="10"/> </Canvas> <Grid.Resources> <Storyboard x:Name="MagnifyStoryBoard" Duration="00:00:10" RepeatBehavior="Forever" AutoReverse="True"> <DoubleAnimationUsingKeyFrames Storyboard.TargetName="HeodeLabel" Storyboard.TargetProperty="FontSize" BeginTime="0" Duration="5"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="10"/> <SplineDoubleKeyFrame KeyTime="00:00:10" Value="100"/> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames Storyboard.TargetName="ProgressRect" Storyboard.TargetProperty="(Canvas.Left)"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/> <SplineDoubleKeyFrame KeyTime="00:00:10" Value="360"/> </DoubleAnimationUsingKeyFrames> </Storyboard> </Grid.Resources> </Grid> </UserControl>

Cette animation est dclenche lors de lvnement MouseLeftButtonClic sur le TextBox HeodeLabel. Le code de la logique applicative de cette application appelle la mthode Begin du scnario MagnifyStoryBoard. Cette mthode va enclencher simultanment chacune des animations contenues dans ce scnario :

80

Animez votre application grce aux StoryBoard

Les animation en Silverlight (C#)


using using using using using using using using using using using System; System.Collections.Generic; System.Linq; System.Net; System.Windows; System.Windows.Controls; System.Windows.Documents; System.Windows.Input; System.Windows.Media; System.Windows.Media.Animation; System.Windows.Shapes;

namespace LearnXaml { public partial class Page : UserControl { public Page() { InitializeComponent(); } private void HeodeLabel_Clic(object sender, MouseButtonEventArgs e) { MagnifyStoryBoard.Begin(); } } } c Fig. 1.51 : Animation non dmarre

c Fig. 1.52 : Animation aprs quelques secondes

81

Le langage XAML

c Fig. 1.53 : Animation aprs 10 secondes

Ce scnario a une dur (Duration), une rgle de rptition (RepeatBehavior) et une rgle de renversement (AutoReverse). La dure est le temps que prend un cycle complet de ce scnario ; il sagit dune valeur temporelle reprsente sous la forme hh:mm:ss. La rgle de rptition est elle aussi une valeur temporelle. Si cette rgle avait eu comme valeur 10:00:00, ce scnario se rpterait pendant une priode de 10 heures suivant lappel de la mthode Begin, et sarrterait ensuite. Dans le cas prsent, la valeur de la rgle de rptition est Forever ; cela signie que le scnario redmarrera ad vitam aeternam. La rgle de renversement, quant elle, est une valeur boolenne. Lorsquelle est vraie, une fois arrive sa n, le scnario sera rembobin. Une DoubleAnimationUsingKeyFrame est une animation modiant la valeur dun double (nombre rel) sur une certaine dure. Ses attributs StoryBoard.TagetName et StoryBoard.TargetProperty indiquent respectivement quel lment XAML contient ce double, et le nom de lattribut reprsentant ce double. Ces animations possdent un attribut BeginTime et une dure (Duration). Inutile de prciser que jouer avec ces StoryBoard est une bonne solution pour faire luire un bouton lorsque la souris passe par-dessus, et ainsi de suite.

Crez une bannire Silverlight grce aux animations


Grce au savoir acquis au cours de ce chapitre, il nous est maintenant possible de crer une bannire Silverlight tel que celle du site de Mircrosoft.

82

Animez votre application grce aux StoryBoard

c Fig. 1.54 : Bannire du site Microsoft

Cette bannire affiche 3 publicits diffrentes ; des boutons sur le ct permettent de changer de publicit. Lorsque la souris passe par-dessus un de ces boutons, les publicits glissent les unes sur les autres jusqu ce que la publicit relative au bouton survol soit visible. Commenons par dnir linterface visuelle de la bannire sous la structure suivante :
j

Canvas

- StackPanel PubCanvas1 .Publicit1 (Image + Lien vers site web) .Bouton vers Publicit1 - StackPanel PubCanvas2 .Publicit2 (Image + Lien vers site web) .Bouton vers Publicit2 - StackPanel PubCanvas3 .Publicit3 (Image + Lien vers site web) .Bouton vers Publicit3

83

Le langage XAML

Interface visuelle de la bannire


<UserControl x:Class="SilverlightBanner.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="500" Height="200"> <Canvas x:Name="LayoutRoot" Background="White"> <StackPanel Name="PubCanvas1" Orientation="Horizontal"> <Border Name="ToPub1" Background="Beige" BorderBrush="Black" BorderThickness="2" CornerRadius="3" Height="200" Width="80" MouseMove="ToPub1_MouseEnter" MouseEnter="ToPub1_MouseEnter"> <Canvas> <TextBlock Text="Wipus" Canvas.Top="80" Canvas.Left="50" FontSize="16"> <TextBlock.RenderTransform> <RotateTransform Angle="90" CenterX="0" CenterY="0"/> </TextBlock.RenderTransform> </TextBlock> </Canvas> </Border> <Border Name="Publicit1" Background="White" Height="200" Width="260" Opacity="1"> <Canvas> <Image Source="wipuslogo.jpg" Stretch="Uniform" Height="200" Width="160"/> <TextBlock Text="Wipus" FontSize="35" Canvas.Top="100" FontFamily="Arial" Canvas.Left="100"/> <HyperlinkButton NavigateUri="http:\\www.wipus.com" Canvas.Left="110" Canvas.Top="130"> <StackPanel Orientation="Horizontal">

84

Animez votre application grce aux StoryBoard

<Image Source="smallbtt.jpg"/> <TextBlock Text="Tell me more..." Foreground="Black" Margin="5" FontSize="14"/> </StackPanel> </HyperlinkButton> </Canvas> </Border> </StackPanel> <StackPanel Name="PubCanvas2" Orientation="Horizontal" Canvas.Left="80"> <Border Name="ToPub2" Background="Beige" BorderBrush="Black" BorderThickness="2" CornerRadius="3" Height="200" Width="80" MouseMove="ToPub2_MouseEnter" MouseEnter="ToPub2_MouseEnter"> <Canvas> <TextBlock Text="Heode" Canvas.Top="80" Canvas.Left="50" FontSize="16"> <TextBlock.RenderTransform> <RotateTransform Angle="90" CenterX="0" CenterY="0"/> </TextBlock.RenderTransform> </TextBlock> </Canvas> </Border> <Border Name="Publicit2" Background="White" Height="200" Width="260" Opacity="1"> <Canvas> <Image Source="heodelogo.jpg" Stretch="Uniform" Height="200" Width="160"/> <TextBlock Text="Heode" FontSize="35" Canvas.Top="100" FontFamily="Arial" Canvas.Left="100"/>

85

Le langage XAML

<HyperlinkButton NavigateUri="http:\\www.heode.com" Canvas.Left="110" Canvas.Top="130"> <StackPanel Orientation="Horizontal"> <Image Source="smallbtt.jpg"/> <TextBlock Text="Tell me more..." Foreground="Black" Margin="5" FontSize="14"/> </StackPanel> </HyperlinkButton> </Canvas> </Border> </StackPanel> <StackPanel Name="PubCanvas3" Orientation="Horizontal" Canvas.Left="160"> <Border Name="ToPub3" Background="Beige" BorderBrush="Black" BorderThickness="2" CornerRadius="3" Height="200" Width="80" MouseMove="ToPub3_MouseEnter" MouseEnter="ToPub3_MouseEnter" Opacity="1"> <Canvas> <TextBlock Text="Jubbeo" Canvas.Top="80" Canvas.Left="50" FontSize="16"> <TextBlock.RenderTransform> <RotateTransform Angle="90" CenterX="0" CenterY="0"/> </TextBlock.RenderTransform> </TextBlock> </Canvas> </Border> <Border Name="Publicit3" Background="White" Height="200" Width="260" Opacity="1"> <Canvas> <Image Source="jubbeologo.jpg" Stretch="Uniform" Height="200" Width="160"/>

86

Animez votre application grce aux StoryBoard

<TextBlock Text="Jubbeo" FontSize="35" Canvas.Top="100" FontFamily="Arial" Canvas.Left="100"/> <HyperlinkButton NavigateUri="http:\\www.jubbeo.com" Canvas.Left="110" Canvas.Top="130"> <StackPanel Orientation="Horizontal"> <Image Source="smallbtt.jpg"/> <TextBlock Text="Tell me more..." Foreground="Black" Margin="5" FontSize="14"/> </StackPanel> </HyperlinkButton> </Canvas> </Border> </StackPanel> </Canvas> </UserControl> c Fig. 1.55 : Interface visuelle de la bannire

Leffet voulu est le suivant : chaque passage sur un des Border ToPub1, ToPub2 ou ToPub3, les publicits vont glisser vers la droite pour afficher la publicit relative au Border survol. Si la publicit relative au Border a dj gliss pralablement vers la droite, elle va glisser vers la gauche. Il y a donc 3 tats notre bannire :
Publicit3Visible (tat actuel de la bannire) ; Publicit2Visible ; j Publicit1Visible.
j j

87

Le langage XAML

Pour des raisons de lisibilit du code, crons une numration reprsentant ces tats :
Etat de la bannire (C#)
using using using using using using using using using using System; System.Net; System.Windows; System.Windows.Controls; System.Windows.Documents; System.Windows.Ink; System.Windows.Input; System.Windows.Media; System.Windows.Media.Animation; System.Windows.Shapes;

namespace SilverlightBanner { public enum EtatBannire { Publicit1Visible, Publicit2Visible, Publicit3Visible } }

Ce sont des animations qui vont nous permettre de passer dun tat lautre. Pour naviguer entre 3 tats, il faut 4 animations (ou scnario en loccurrence, chaque scnario contenant une unique animation). Ces animations sont :
DePub3Pub2 ; j DePub2Pub1 ; j DePub1Pub2 ; j DePub2Pub3.
j

Ajoutons le code XAML de ces scnarios au chier XAML de linterface :


Les animations de la bannire
<UserControl x:Class="SilverlightBanner.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="500" Height="200">

88

Animez votre application grce aux StoryBoard

<Canvas x:Name="LayoutRoot" Background="White"> <!--( dfinition de linterface ...)--> <Canvas.Resources> <Storyboard x:Name="DePub3Pub2"> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="PubCanvas3" Storyboard.TargetProperty="(Canvas.Left)"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="160"/> <SplineDoubleKeyFrame KeyTime="00:00:04" Value="420"/> </DoubleAnimationUsingKeyFrames> </Storyboard> <Storyboard x:Name="DePub2Pub1"> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="PubCanvas2" Storyboard.TargetProperty="(Canvas.Left)"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="80"/> <SplineDoubleKeyFrame KeyTime="00:00:04" Value="340"/> </DoubleAnimationUsingKeyFrames> </Storyboard> <Storyboard x:Name="DePub1Pub2"> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="PubCanvas2" Storyboard.TargetProperty="(Canvas.Left)"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="340"/> <SplineDoubleKeyFrame KeyTime="00:00:04" Value="80"/> </DoubleAnimationUsingKeyFrames> </Storyboard> <Storyboard x:Name="DePub2Pub3"> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="PubCanvas3" Storyboard.TargetProperty="(Canvas.Left)"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="420"/> <SplineDoubleKeyFrame KeyTime="00:00:04" Value="160"/> </DoubleAnimationUsingKeyFrames> </Storyboard> </Canvas.Resources>

89

Le langage XAML

</Canvas> </UserControl>

Cest ensuite sur les vnements MouseMouve et MouseEnter de chaque Border ToPub quil faut ajouter le dclenchement dun de ces scnarios. Une analyse pralable de la logique applicative semble requise :
Analyse de la logique applicative de la bannire
Dclarer un tat assign Publicit1Visible au dmarage de lapplication Dclarer un boolen signalant si une animation est dj en cours ou non pour viter que 2 animations ne dmarrent en mme temps { Ajouter chaque fin danimation un vnement modifiant ce boolen Modifier ce boolen avant chaque appel de la mthode Begin dun animation } Dclarer une destination de type EtatBannire. Cette destination est la dernire publicit survole par la souris de lutilisateur. Crer une mthode StartNextAnimation qui dmare une animation en fonction des valeurs tat et destination. Appeler cette mthode chaque fin danimation au cas o ltat soit actuel diffrent de la destination actuelle Lors du survol des Borders ToPub. { Assigner la publicit courante comme destination Si aucune animation nest en cours, alors appeler la mthode StartNextAnimation }

90

Animez votre application grce aux StoryBoard

Code de la logique applicative :


Code C# de la bannire
using using using using using using using using using using using System; System.Collections.Generic; System.Linq; System.Net; System.Windows; System.Windows.Controls; System.Windows.Documents; System.Windows.Input; System.Windows.Media; System.Windows.Media.Animation; System.Windows.Shapes;

namespace SilverlightBanner { public partial class Page : UserControl { private EtatBannire tat = EtatBannire.Publicit3Visible; private bool AnimationEnCours = false; private EtatBannire destination = EtatBannire.Publicit3Visible; public Page() { InitializeComponent(); DePub1Pub2.Completed DePub2Pub1.Completed DePub2Pub3.Completed DePub3Pub2.Completed } void SetEtatToPub1(object sender, EventArgs e) { tat = EtatBannire.Publicit1Visible; AnimationEnCours = false; StartNextAnimation(); } void SetEtatToPub2(object sender, EventArgs e) { tat = EtatBannire.Publicit2Visible; AnimationEnCours = false; StartNextAnimation(); += += += += new new new new EventHandler(SetEtatToPub2); EventHandler(SetEtatToPub1); EventHandler(SetEtatToPub3); EventHandler(SetEtatToPub2);

91

Le langage XAML

} void SetEtatToPub3(object sender, EventArgs e) { tat = EtatBannire.Publicit3Visible; AnimationEnCours = false; StartNextAnimation(); } private void ToPub3_MouseEnter(object sender, MouseEventArgs e) { destination = EtatBannire.Publicit3Visible; if (AnimationEnCours == true) return; StartNextAnimation(); } private void ToPub2_MouseEnter(object sender, MouseEventArgs e) { destination = EtatBannire.Publicit2Visible; if (AnimationEnCours == true) return; StartNextAnimation(); } private void ToPub1_MouseEnter(object sender, MouseEventArgs e) { destination = EtatBannire.Publicit1Visible; if (AnimationEnCours == true) return; StartNextAnimation(); } private void StartNextAnimation() { if (tat == destination) return; AnimationEnCours = true; switch (tat)

92

Animez votre application grce aux StoryBoard

{ case EtatBannire.Publicit1Visible: DePub1Pub2.Begin(); break; case EtatBannire.Publicit2Visible: if (destination == EtatBannire.Publicit1Visible) DePub2Pub1.Begin(); else DePub2Pub3.Begin(); break; case EtatBannire.Publicit3Visible: DePub3Pub2.Begin(); break; } } } }

La bannire devrait maintenant fonctionner merveille ; cependant, ce nest pas le cas. Lors de lexcution du premier scnario, la publicit 3 sort du contrle Silverlight et empite sur la page ASP.NET (ou HTML) le contenant.

c Fig. 1.56 : Animation sortant du contrle Silverlight

Ce problme nest pas un problme d au code Silverlight mais bien un problme d au code ASP.NET (ou HTML) gnr par VisualStudio. Dans la page ASP.NET hte du projet de dveloppement Silverlight, remplacez la taille du contrle Silverlight par With =500 et Height=200 :

93

Le langage XAML

Page ASP.NET hte dun projet de dveloppement Silverlight


<%@ Page Language="C#" AutoEventWireup="true" %> <%@ Register Assembly="System.Web.Silverlight" Namespace="System.Web.UI.SilverlightControls" TagPrefix="asp" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" style="height:100%;"> <head runat="server"> <title>SilverlightBanner</title> </head> <body style="height:100%;margin:0;"> <form id="form1" runat="server" style="height:100%;"> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> <div style="height:100%"> <asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/SilverlightBanner.xap" MinimumVersion="2.0.31005.0" Width="100%" Height="100%" /> </div> </form> </body> </html>

La bannire fonctionnera parfaitement.

c Fig. 1.57 : Bannire tat 3 2

94

Check-List

c Fig. 1.58 : Bannire tat 2 1

c Fig. 1.59 : Bannire tat 1

1.11 Check-List
Ce chapitre vous a fourni les bases ncessaires la comprhension dun chier XAML. Nous avons tudi ici les diffrents contrles et fonctionnalits de base dune interface Silverlight :

a le langage XAML driv du XML ; a les diffrents contrles de Layout structurants une interface ; a quelques contrles daffichages dinformations ; a quelques contrles de captures dinformations ; a les bases du Binding ; a quelques lments de design.
Enn, nous avons conclu par la cration complte dune bannire Silverlight.

95

2
2.1 Introduction Expression Studio ...................... 2.2 Expression Design ...................................... 2.3 Expression Encoder 2 .................................. 2.4 Expression Blend 2 ..................................... 2.5 Intraction entre Expression Blend et Visual Studio 2008 .................................................... 2.6 Check-List ................................................ 98 99 102 104 109 111

Crer vos applications avec Expression Studio


D
ans ce chapitre, vous dcouvrirez la nouvelle gamme doutils Microsoft destine aux graphistes et cratifs. Microsoft Expression Studio vous simpliera la vie lorsque vous devrez crer des applications pousses, au niveau graphique. Dcouvrez lensemble de la gamme doutils dans ce chapitre : Expression Design pour la partie purement graphique, Expression Web pour tout ce qui concerne lintgration de Silverlight et ASP.NET dans vos pages, Expression Blend pour la partie animation et web application, Expression Media et Media Encoder pour lintgration de vos vidos dans Silverlight.

Crer vos applications avec Expression Studio

2.1 Introduction Expression Studio


Lorsque vous crez une application, que ce soit pour le Web ou pour toute autre plateforme, vous devez veiller ce que tout soit correctement prsent. Le design, cest--dire linterface du produit, inuence beaucoup les consommateurs. Cest ainsi quApple a, depuis un moment, un succs de plus en plus remarqu grce au design raffin de ses ordinateurs. Jusqualors, lunivers des cratifs et des dveloppeurs tait diffrent. Dun ct, les graphistes utilisaient des suites logicielles dAdobe avec le clbre Photoshop ou Illustrator et dun autre ct, les dveloppeurs employaient des logiciels de dveloppement comme Visual Studio que vous avez dcouvert lors du premier chapitre. Ces logiciels navaient aucune cohrence entre eux, ce qui posait normment de problmes de communication entre cratifs et dveloppeurs. Microsoft, soucieux des mthodologies de travail, a donc cr une nouvelle suite de logiciels appele Expression Studio. Cette suite est plutt destine aux cratifs et intgrateurs. Microsoft a russi son pari pour ces nouveaux logiciels ; non seulement linteroprabilit avec Visual Studio est parfaite, mais en plus, les cratifs qui ont dj eu loccasion de lutiliser ne sont pas dus. Seul bmol pour le moment : Expression Studio tourne uniquement sur du Windows. Seul Microsoft Expression Media 2 peut fonctionner dans un environnement Mac OS. Nul doute que tout le monde nabandonnera pas la suite Adobe mais vous trouverez sur Internet une srie doutils vous permettant de faire la liaison entre la gamme de logiciels Adobe et la gamme Expression Studio. La suite Microsoft a pour vocation de faciliter la cration de RIA (Rich Internet Application).
Rich Internet Application
Ce terme est apparu avec la redcouverte dAJAX. Les applications sont dites riches quand elles permettent beaucoup dinteraction avec lutilisateur. Flash et Silverlight sont orients vers ce genre dinteractions. En effet, comme tout est tlcharg du ct du client, on peut avoir des applications web trs rapides lexcution, ce qui permet une trs bonne ractivit et donc une bonne interaction avec lutilisateur de lapplication. Le mot riche peut aussi tre associ des interfaces jolies ou encore user friendly. Nous verrons dans les prochains sous-chapitres que Expression Studio a tout pour crer ce genre dapplication.

98

Expression Design

La gamme Expression Studio comprend 5 outils :


j j j j j

Expression Expression Expression Expression Expression

Web ; Blend ; Design ; Media ; Encoder 2.

Les plus utiles, dans le cas de Silverlight, sont Expression Blend, Expression Media et Encoder (les deux derniers sont fortement lis). Si vous ne comptez pas tirer parti de la puissance de Silverlight pour la vido, Expression Blend vous suffira. Expression Studio est payant mais vous disposez dune version dvaluation vous permettant de tester le produit. Vous pourrez trouver ce produit en magasin, la FNAC par exemple ou chez des partenaires Microsoft.
Un bon exemple dapplication ralis en XAML
Un bon exemple dapplication ralise en XAML est Expression Studio. En effet, lensemble des outils de la gamme Expression a t ralis en XAML.

Partons maintenant la dcouverte de ces 5 outils qui vous serviront tout au long de la cration dune application web Silverlight.

2.2 Expression Design


Expression Design est un peu le Photoshop de Microsoft. Bien que plus jeune et moins complet, il vous permet de raliser bon nombre dlments graphiques. Son grand intrt par rapport dautres logiciels, est sa connaissance par dfaut du XAML. Comme vous lavez vu, XAML est un langage de dnitions dinterfaces vectorielles. Expression Design gre uniquement des images vectorielles par dfaut, ce qui permet de les convertir trs rapidement en XAML. Prenons un exemple, si dans Expression Design, vous crez un dessin ainsi :

99

Crer vos applications avec Expression Studio

c Fig. 2.1 : Expression Design 2

Si vous voulez crer le mme dessin en XAML, voici quoi cela ressemblera :
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Name="Layer_1_0" Width="800" Height="600" Canvas.Left="0" Canvas.Top="0"> <Rectangle Width="345.983" Height="155.492" Canvas.Left="253.257" Canvas.Top="170.506" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000"> <Rectangle.Fill> <LinearGradientBrush StartPoint="-0.00144939,0.5" EndPoint="1.00145,0.5"> <LinearGradientBrush.GradientStops> <GradientStop Color="#FF000000" Offset="0.237443"/>

100

Expression Design

<GradientStop Color="#FFF3F025" Offset="0.502283"/> <GradientStop Color="#FFE9F100" Offset="0.589041"/> <GradientStop Color="#FFED2E16" Offset="0.776256"/> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> <Ellipse Width="77.4962" Height="78.9961" Canvas.Left="554.742" Canvas.Top="122.509" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000"> <Ellipse.Fill> <LinearGradientBrush StartPoint="-0.00653628,0.5" EndPoint="1.00654,0.5"> <LinearGradientBrush.GradientStops> <GradientStop Color="#FF000000" Offset="0.237443"/> <GradientStop Color="#FFF3F025" Offset="0.502283"/> <GradientStop Color="#FFE9F100" Offset="0.589041"/> <GradientStop Color="#FFED2E16" Offset="0.776256"/> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Ellipse.Fill> </Ellipse> </Canvas>

Imaginez alors combien de temps cela vous prendrait de crer des dessins beaucoup plus complexes ? Expression Design est donc un outil indispensable la ralisation dinterfaces riches. Expression Design fait lobjet de livres entiers. Si vous tes habitu Photoshop, vous naurez aucun problme le prendre en main.
XAML vs Images
Si XAML reprsente une image, pourquoi ne pas directement prendre cette image et lajouter comme ressource notre projet en utilisant la balise XAML Image ? Tout dpend du type dapplications que vous voulez raliser. Si limage fait partie intgrante de votre interface et que celle-ci soit extensible, vous devez la prvoir en XAML. Mais si vous devez afficher une srie darticles avec des images, il est inutile de transformer ces images en XAML.

101

Crer vos applications avec Expression Studio

2.3 Expression Encoder 2


Si vous aimez la vido et que vous vouliez utiliser vos vidos dans Silverlight, Expression Encoder 2 est loutil dont vous avez besoin. Un peu complexe prendre en main au dbut, il vous permet deffectuer tout le processus du dbut la n, cest--dire de lencodage de la vido un rendu dans un lecteur Silverlight prt lemploi. Prenons un exemple avec une vido WMV. Vous pouvez limporter dans Expression Encoder laide du bouton import.

c Fig. 2.2 : Expression Encoder

Une fois la vido importe, vous pouvez la visualiser laide du lecteur intgr au programme. Vous avez la possibilit de couper la vido comme vous le dsirez pour y placer des chapitres ou des explications. Lorsque votre dition est termine, vous pouvez regarder toute une srie de paramtres droite. Dans le dernier onglet, output, vous avez la possibilit de choisir un lecteur pour votre vido. Il en existe toute une srie et vous pouvez en crer vous-mme de nouveaux ou diter les existants en les ouvrant dans Expression Blend laide du petit carr situ juste ct de la liste droulante. Lorsque vous avez termin, cliquez sur Encode et attendez le rsultat qui devrait safficher dans une nouvelle fentre Internet explorer.

102

Expression Encoder 2

Si on regarde la page (C:\Users\VOTRE_USER\Documents\Expression\Expression Encoder\Output) qui a t gnre :


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd"> <!-- saved from url=(0014)about:internet --> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <script type=text/javascript src="MicrosoftAjax.js"></script> <script type=text/javascript src="Silverlight.js"></script> <script type=text/javascript src="SilverlightControl.js"></script> <script type=text/javascript src="SilverlightMedia.js"></script> <script type=text/javascript src="ExpressionPlayer.js"></script> <script type=text/javascript src="PlayerStrings.js"></script> <script type=text/javascript src="player.js"></script> <script type=text/javascript src="StartPlayer.js"></script> <title></title> <style type="text/css"> html, body { margin: 0; padding: 0; height:100% } #divPlayer_0 { min-height: 100%; height:100%; } </style> </head> <body style="background-color:black;margin:0,0,0,0;overflow:auto;"> <div id="divPlayer_0"> <script type=text/javascript> var player = new StartPlayer_0(); </script> </div> </body> </html>

Vous pourrez trouver tous les chiers JavaScript en rapport dans le mme dossier que le chier Default.html. Microsoft Expression Encoder permet galement de senregistrer (voix et son) an de crer vos propres vidos lmes par webcam ou camscope. Pour cela, cliquez sur longlet Live Encoding. Une nouvelle fentre apparat en overlay. Vous devez choisir la source de la vido et la source audio et cliquez sur Start. Une fois lenregistrement effectu, vous obtenez un aperu en vous rendant dans longlet output et en cliquant sur Launch Preview.

103

Crer vos applications avec Expression Studio

2.4 Expression Blend 2


Expression Blend 2 est loutil le plus puissant pour la ralisation dapplication Silverlight 2. Pour commencer, il vous faudra tlcharger le SP1 de Microsoft Expression Blend 2 an davoir la possibilit de crer des projets Silverlight 2. Par dfaut, Blend 2 supporte uniquement les projets Silverlight 1, cest--dire les projets Silverlight base de JavaScript. Pour pouvez tlcharger Microsoft Expression Blend 2 SP ladresse suivante : http:// www.microsoft.com/downloads/details.aspx?FamilyId=EB9B5C48-BA2B-4C39-A1C3-135C60BBBE66&displaylang=en.
c Fig. 2.3 : Nouveau projet Expression Blend 2 SP1

Aprs avoir install le SP1, vous pouvez crer un projet Silverlight 2 en lui donnant un nom et en cliquant sur OK. Un projet vide sest cr. Vous pouvez basculer entre laffiche design ou XAML par les onglets verticaux de droite. Mme un projet blanc nest pas tout fait vide puisque Blend vous prpare directement un conteneur de base (Grid) :
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="SilverlightApplication2.Page" Width="640" Height="480"> <Grid x:Name="LayoutRoot" Background="White"/> </UserControl>

104

Expression Blend 2

Si on passe nouveau du ct Design et que lon ajoute un rectangle, on remarquera que le code XAML sest directement mis jour :

c Fig. 2.4 : Expression Blend 2 <UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="SilverlightApplication2.Page" Width="640" Height="480"> <Grid x:Name="LayoutRoot" Background="White"> <Rectangle Height="73" Margin="117,122,280,0" VerticalAlignment="Top" Stroke="#FF000000"> <Rectangle.Fill> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#FF000000"/> <GradientStop Color="#FF0F2B66" Offset="1"/> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> </Grid> </UserControl>

Au niveau des proprits des lments, on retrouve assez facilement des lments dj vus dans Microsoft Expression Design 2. Vous pouvez consulter tout les lments XAML disponibles en cliquant sur la double che gauche. Par dfaut, ils ne sont pas tous affichs. Si vous voulez les afficher tous, vous devrez cocher la case en haut droite Show all.

105

Crer vos applications avec Expression Studio

c Fig. 2.5 : Barre des proprits

Llment le plus important de Blend est la colonne Objects and Timeline. Elle vous permet de visualiser les lments que vous avez ajouts votre projet et surtout de voir leur situation dans le projet. En effet, cette colonne reprsente les lments sous forme darbre de telle manire que vous puissiez voir comment les lments sont imbriqus les uns dans les autres.

Les noms
Il est trs important de donner des noms vos lments. Cest ainsi que vous pouvez les retrouver quand vous en avez beaucoup sur une mme interface. De la mme manire, lorsque vous voudrez interagir avec ceux-ci par code, vous devrez connatre leur nom dans le code. Sils nont pas de noms, on peut considrer les lments comme inaccessibles.

106

Expression Blend 2

c Fig. 2.6 : Objects and Timeline

Cest aussi dans cette colonne que vous allez contrler les diffrentes animations de votre application. Ainsi, pour animer votre rectangle, il faut cliquer sur le petit bouton en forme de plus et donner un nom votre animation. Vous entrez alors en mode denregistrement. Vous avez une ligne du temps gauche et un encadr rouge droite qui montre la zone denregistrement. Effectuer une animation avec Blend et Silverlight savre trs simple, surtout si vous tes habitu jouer avec les mmes concepts pour Flash/Flex. Tout se fait par point darrt. Un point darrt est x ds que vous dplacez un lment. Pour crer une animation, placez-vous sur la ligne du temps et dplacez llment. Pour visualiser lanimation, cliquez sur le bouton Play.

c Fig. 2.7 : Animation dans Expression Blend 2

Ces actions trs basiques gnrent du code XAML larrire :


<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="SilverlightApplication2.Page" Width="640" Height="480"> <UserControl.Resources> <Storyboard x:Name="Storyboard1"> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle"

107

Crer vos applications avec Expression Studio

Storyboard.TargetProperty="(UIElement.RenderTransform). (TransformGroup.Children)[3].(TranslateTransform.Y)"> <SplineDoubleKeyFrame KeyTime="00:00:01" Value="63"/> <SplineDoubleKeyFrame KeyTime="00:00:02" Value="-74"/> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(UIElement.RenderTransform). (TransformGroup.Children)[3].(TranslateTransform.X)"> <SplineDoubleKeyFrame KeyTime="00:00:01" Value="125"/> <SplineDoubleKeyFrame KeyTime="00:00:02" Value="244"/> </DoubleAnimationUsingKeyFrames> <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush. GradientStops)[1].(GradientStop.Color)"> <SplineColorKeyFrame KeyTime="00:00:01" Value="#FF0F2B66"/> <SplineColorKeyFrame KeyTime="00:00:02" Value="#FFA9BCE4"/> </ColorAnimationUsingKeyFrames> </Storyboard> </UserControl.Resources> <Grid x:Name="LayoutRoot" Background="White"> <Rectangle Height="73" Margin="117,122,280,0" VerticalAlignment="Top" Stroke="#FF000000" RenderTransformOrigin="0.5,0.5" x:Name="rectangle"> <Rectangle.RenderTransform> <TransformGroup> <ScaleTransform/> <SkewTransform/> <RotateTransform/> <TranslateTransform/> </TransformGroup> </Rectangle.RenderTransform> <Rectangle.Fill> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#FF000000"/> <GradientStop Color="#FF0F2B66" Offset="1"/> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> </Grid> </UserControl>

108

Intraction entre Expression Blend et Visual Studio 2008

la simple vue de ce code, vous vous rendez compte quel point Expression Blend peut tre utile.
La limite dExpression Blend
Si les outils pouvaient gnrer le code sans faire derreurs, nous naurions plus besoin dexperts. Trs souvent, une intervention humaine est apprcie pour optimiser le code. Tout ceci sera expliqu dans les concepts avancs. Retenez que Blend ne remplace pas un code bien crit la main. Il est l pour vous simplier la vie mais tentez de toujours comprendre ce quil fait.

2.5 Intraction entre Expression Blend et Visual Studio 2008


La plupart du temps, on ne commence pas un projet rel dans Expression Blend ; cela pause de nombreux problmes de portabilit de dorganisation par la suite. Il arrive nanmoins de commencer un projet dans Expression Blend si celui-ci est destin donner un avant-got du logiciel ou de lapplication au client. Cest en effet un trs bon moyen de convaincre un client. Vous pouvez facilement tablir la comparaison avec les graphistes qui dessinent une interface et la montrer au client avant que tout soit implment. Les bonnes pratiques veulent quon cre dabord le projet dans Visual Studio. Si vous travaillez dans un environnement professionnel avec ces outils, vous devez utiliser une solution de gestion de version comme Visual Source Safe ou SVN. Malheureusement, Blend nest pas encore compatible avec ces outils, lutilisation de Visual Studio 2008 est donc recommande. Visual Studio ou Visual Developer ne proposent pas une interface ddition du XAML aussi pousse que Expression Blend. Les prochaines versions du logiciel devraient apporter des amliorations ce niveau. Heureusement, Microsoft a prvu lutilisation de ces deux logiciels en simultan. Lorsque vous crez un projet dans Visual Studio, vous avez la possibilit dditer les chiers XAML directement dans Expression Blend. Pour cela, cliquez du bouton droit sur le chier dont lextension est xaml. Cela a pour effet douvrir directement Blend. La moindre modication dun ct des rpercutions directes de lautre. Vous tes normalement jour dans la gestion de vos chiers.

109

Crer vos applications avec Expression Studio

Considrez toujours Visual Studio comme votre outil principal et Expression Blend comme un outil de retouche plutt quun outil de cration dapplication Silverlight. Expression Blend ne permet pas de modier les chiers contenant la logique mtier. Si vous cliquez sur la petite croix devant le nom du chier, vous verrez un sous-chier ; cest le chier contenant tout ce qui est dynamique dans lapplication. Seul Visual Studio ou votre Bloc-notes vous permet de modier ces chiers :
using using using using using using using using using using using System; System.Collections.Generic; System.Linq; System.Net; System.Windows; System.Windows.Controls; System.Windows.Documents; System.Windows.Input; System.Windows.Media; System.Windows.Media.Animation; System.Windows.Shapes;

namespace SilverlightApplication1 { public partial class Page : UserControl { public Page() { InitializeComponent(); } } }

Si vous travaillez deux sur un mme projet, il arrive frquemment quune personne travaille sur le chier xaml et lautre sur le chier cs. Attention toutefois aux abus ; la plupart du temps, pour avoir un code cohrent, il faut une interface dj bien dnie ; le chier xaml est souvent plus avanc que le chier cs qui lui est ddi. Vous aurez peu loccasion dutiliser Expression Web et Expression Media qui ne seront pas dcrits dans ce livre. Nous pouvons donc terminer ce chapitre parenthse pour partir la conqute des donnes.

110

Check-List

2.6 Check-List
Dans ce chapitre nous avons explor la gamme Expression avec :

a Expression Design ; a Expression Blend ; a Expression Encoder ; a Linteraction entre Visual Studio et Expression Blend.

111

3
3.1 Utilisez SQL et votre base de donnes ............... 3.2 Exploitez vos donnes sur Oracle .................... 3.3 MySQL et Silverlight .................................... 3.4 LINQ ..................................................... 3.5 Les Web services ....................................... 3.6 ADO.NET/Silverlight ................................... 3.7 Crez un widget mto ................................ 3.8 Traitez un ux de donnes RSS ........................ 3.9 Check-list ................................................. 114 120 124 126 134 143 153 174 179

Exploiter vos sources de donnes


accs aux donnes est trs important. Ce chapitre va vous montrer comment accder tout et nimporte quoi, en passant par les bases de donnes : que ce soit Microsoft SQL Serveur ou MySQL, ou en allant voir du ct des Web services qui sont de plus en plus prsents. Nous montrerons par la mme occasion comment exposer vos donnes en Web service. Nous rentrerons enn dans un autre mode daccs aux donnes : lutilisation de LINQ.

Exploiter vos sources de donnes

3.1 Utilisez SQL et votre base de donnes


La majorit des donnes se trouve dans des bases de donnes. Ces dernires font partie dun systme de base de donnes (SGBD) parfois diffrent dune socit lautre. Silverlight fonctionne trs bien avec SQL Serveur, systme de base de donnes de Microsoft et grand concurrent dOracle. Dautres SGBD existent comme MySQL, rachet par SUN il y a peu. La liste est longue. Ce livre couvrira laccs en majorit SQL Serveur, dont vous pouvez trouver une version gratuite et utilisable en production : SQL Serveur Express (cf. http://msdn.microsoft .com/fr-fr/express/aa718378.aspx). Nous aurons galement des exemples dutilisations avec MySQL et Oracle qui sont deux SGBD fort rpondus. Ainsi, vous obtiendrez une vue globale de lexploitation des donnes avec Silverlight.

Silverlight, C# et SQL Serveur : introduction


Ce nest pas Silverlight qui va accder aux donnes mais bien C#, langage utilis larrire de Silverlight. Si vous navez aucune connaissance en C#, nous vous conseillons la lecture de lannexe 2, Introduction au C#. Autrement, vous ne comprendrez pas ce qui va suivre. Nous allons voir comment utiliser SQL Serveur. En C#, il existe plusieurs moyens deffectuer des requtes sur SQL Serveur. Pour ce faire, nous avons besoin des lments suivants :
j j j j

une chane de connexions permettant de vous authentier et de cibler la base de donnes attaquer ; une connexion qui souvre grce aux paramtres placs dans la chane de connexion ; une commande qui est une chane de caractres reprsentant une requte SQL ; un objet pour rcuprer les rsultats an de pouvoir les afficher.

Une fois que nous avons tous ces lments, nous pouvons commencer. Tout dabord, la chane de connexion. Cest un concept qui reviendra pour les autres SGBD galement. Pour SQL Serveur, elle ressemble ceci :
Data Source=PC-MACWIN\SQLEXPRESS;Initial Catalog=WipusBD;Persist Security Info=True;User ID=WipusDBManager; Password=WipusManager

114

Utilisez SQL et votre base de donnes

Cette chane de connexion, nous devons la sauvgarder dans une variable de type string. Ce type de variable est spcialement prvu pour accepter les chanes de caractres :
string connectionString = @"Data Source=PC-MACWIN\SQLEXPRESS;Initial Catalog=WipusBD;Persist Security Info=True;User ID=WipusDBManager; Password=WipusManager";

Une fois cette chane sauvegarde, nous pouvons lutiliser pour initialiser une connexion. Cela se fait laide de lobjet SqlConnection :
SqlConnection myConnection; myConnection = new SqlConnection(connectionString);

Une fois la connexion initialise, nous devons louvrir :


try { myConnection.Open(); } catch(Exception e) { Console.WriteLine(e.ToString()); }

Le try/catch permet de dtecter sil y a eu une erreur lors de la connexion la base de donne. Si cest le cas, vous pourrez la grer dans le catch. Autrement, le code continuera sexcuter sans passer dans le catch. Avant daller plus loin, nous allons procder un rappel concernant SQL.

SQL
Structured Query Language est un langage qui vous permet daccder aux donnes situes dans une base de donnes. Cest un langage uniformis qui doit, normalement, fonctionner sur tous les SGBD. Cependant, vous trouverez quelques nuances quand vous utiliserez SQL Server ou Oracle, ces deux SGBD tant si puissants quils ont ajout un lot de nouvelles fonctionnalits au SQL. Sans rentrer dans les dtails, SQL permet de raliser 4 actions basiques : j slectionner ; j supprimer ; j diter ; j ajouter.

115

Exploiter vos sources de donnes

Chaque action que peut effectuer SQL a son mot-cl. Ainsi, pour la slection, on a le mot-cl SELECT, pour la suppression, le mot-cl est DELETE, pour diter UPDATE et INSERT pour lajout dans une base de donnes. Pour la slection, outre le mot-cl SELECT, nous devons signier ce que nous souhaitons slectionner (la projection) et le critre de slection sur cette slection. Par exemple : Rechercher le nom, le prnom et lge des tudiants de deuxime anne. Nous avons ici une projection : nom, prnom et ge, ainsi quune slection, cest--dire le fait de slectionner uniquement les lves de deuxime anne. Pour la projection, nous avons presque tous les lments pour notre requte :
SELECT nom, prenom, age FROM etudiants

Pour la slection, nous devons introduire un nouveau mot-cl : WHERE :


SELECT nom, prenom, age FROM etudiants WHERE annee = 2

Dans cet exemple, nous ne prenons en compte une seule table. Il arrive frquemment de devoir aller rechercher une information situe dans plusieurs tables. Imaginez que notre base de donnes stocke le cours auquel ltudiant participe actuellement. Pour cela, il y aurait une autre table cours avec une rfrence vers la table des tudiants. Si vous voulez la liste des tudiants se trouvant au cours de maths, nous allons obtenir :
SELECT etudiants.nom, etudiants.prenom, etudiants.age FROM etudiants, cours WHERE etudiants.Id = cours.Id AND cours.Nom = Math

Cette faon ne reprsente quune manire de chercher le rsultat. Nous pourrions utiliser dautres mthodes avec les mots-cls INNER JOIN ou JOIN. Pour ce qui est de linsertion de nouveaux lments ainsi que de la suppression et modication, vous dcouvrirez, au long du chapitre, la syntaxe fort proche de la slection.

Les commandes SQL en C#


Aprs cette petite parenthse sur SQL, nous pouvons continuer avec deux des quatre lments de base dont nous avions besoin pour effectuer sur requte sur SQL Serveur. Cela se fait laide de lobjet SqlCommand :

116

Utilisez SQL et votre base de donnes

SqlCommand cmd = new SqlCommand("SELECT nom, prenom, age " + "FROM etudiants " + "WHERE annee = 2 " + "AND age < 22 ", con);

Lobjet SqlCommand prend en paramtre une chane de caractres reprsentant la requte SQL ainsi que lobjet connexion que nous avons initialis auparavant (SqlConnection). Il peut arriver que la requte ait des donnes dites dynamiques. Imaginez par exemple que dans votre Silverlight, vous ayez un moment donn demander lge maximal des lves que vous voudriez afficher. Cette donne aura t sauve dans une variable de type int ou short vu que lge dune personne dpasse rarement les 100 ans. Vous pouvez exploiter ces donnes au sein de votre requte :
SqlCommand cmd = new SqlCommand("SELECT nom, prenom, age " + "FROM etudiants " + "WHERE annee = " + "AND age < " + VOTRE VARIABLE ICI, myConnection);

Attention aux hackers


En utilisant cette mthode, vous ne vous mettez pas labri des hackers qui pourraient effectuer une injection SQL. Une injection SQL est une injection de code via un formulaire qui a pour objectif de dtourner votre requte de son but premier dans lespoir de corrompre votre systme de base de donnes. Pour viter cela, vous ne devez jamais placer de paramtre directement dans la chane de caractres mais prfrer lutilisation de lobjet SqlParameter.

SqlParameter est un objet qui dnit un paramtre de votre requte. Le paramtre est

dsign par un identiant qui mappe les paramtres de la requte SQL :


SqlCommand cmd = new SqlCommand("SELECT count(*) " + "FROM video " + "WHERE Status = " + "1 AND UserId = @userId " + "AND IdVideo = @IdVideo ", con); SqlParameter pVideoId = new SqlParameter("IdVideo", SqlDbType.BigInt); pVideoId.Value = VideoId; cmd.Parameters.Add(pVideoId); MembershipUser user = Membership.GetUser(); SqlParameter pUserId = new SqlParameter("UserId", SqlDbType.UniqueIdentifier);

117

Exploiter vos sources de donnes

pUserId.Value = UserId; cmd.Parameters.Add(pUserId);

Ainsi, les attaques SQL ne sont pas possibles. Comme on connat le type quon doit obtenir, on rduit dj le champ de lattaque. De plus, il traite automatiquement les caractres tels que "". Pour excuter notre requte, nous devons crer un reader. Cet objet va nous permettre de lire les rsultats de la requte pour les afficher ensuite :
private static void ReadOrderData(string connectionString) { string queryString = "SELECT OrderID, CustomerID FROM dbo.Orders;"; using (SqlConnection connection = new SqlConnection( connectionString)) { SqlCommand command = new SqlCommand( queryString, connection); connection.Open(); SqlDataReader reader = command.ExecuteReader(); try { while (reader.Read()) { Console.WriteLine(String.Format("{0}, {1}", reader[0], reader[1])); } } finally { // Always call Close when done reading. reader.Close(); } } }

Exemple
Cet exemple provient dune application console. tant donn que vous navez pas encore les notions suffisantes pour ASP.NET, nous avons volontairement limit lexemple. Rendez-vous au chapitre 5, Silverlight et ASP.NET, pour voir comment traiter les donnes correctement. Plus loin dans ce chapitre, nous dcouvrirons galement comment fonctionne laccs direct une base de donnes via Silverlight.

118

Utilisez SQL et votre base de donnes

Les mthodes montres jusquici ne sont applicables quau travers dun Web service. Nous verrons les Web services plus loin dans ce chapitre. Nanmoins, il est rare quun Web service expose une mthode qui renvoie un DataReader. Vous pouvez utiliser la fonction suivante :
/// <summary> /// Converts a SqlDataReader to a DataSet /// <param name=reader> /// SqlDataReader to convert.</param> /// <returns> /// DataSet filled with the contents of the reader.</returns> /// </summary> public static DataSet convertDataReaderToDataSet(SqlDataReader reader) { DataSet dataSet = new DataSet(); do { // Create new data table DataTable schemaTable = reader.GetSchemaTable(); DataTable dataTable = new DataTable(); if (schemaTable != null) { // A query returning records was executed for (int i = 0; i < schemaTable.Rows.Count; i++) { DataRow dataRow = schemaTable.Rows[i]; // Create a column name that is unique // in the data table string columnName = (string)dataRow["ColumnName"]; //+ "<C" + i + "/>"; // Add the column definition to the data table DataColumn column = new DataColumn(columnName, (Type)dataRow["DataType"]); dataTable.Columns.Add(column); } dataSet.Tables.Add(dataTable); // Fill the data table we just created while (reader.Read()) { DataRow dataRow = dataTable.NewRow();

119

Exploiter vos sources de donnes

for (int i = 0; i < reader.FieldCount; i++) dataRow[i] = reader.GetValue(i); dataTable.Rows.Add(dataRow); } } else { // No records were returned DataColumn column = new DataColumn("RowsAffected"); dataTable.Columns.Add(column); dataSet.Tables.Add(dataTable); DataRow dataRow = dataTable.NewRow(); dataRow[0] = reader.RecordsAffected; dataTable.Rows.Add(dataRow); } } while (reader.NextResult()); return dataSet; }

3.2 Exploitez vos donnes sur Oracle


Oracle est une base de donnes reconnue au niveau mondiale. Elle est utilise par les plus grandes socits. Cest un concurrent de SQL Serveur. Elle permet dtre congure pour supporter de grosse consommation de donnes. Le but de cette section nest pas dapprendre utiliser Oracle mais de russir exploiter les donnes dOracle directement en C#. Il vous faudra par la suite crer un Web service et attaquer votre Web service dans votre application Silverlight pour pouvoir rcolter les donnes. Avant de commencer, vous devez installer les outils Oracle pour Visual Studio 2008 disponibles cette adresse : http://www.oracle.com/technology/software/tech/windows/odpnet/. Vous pouvez galement tlcharger ODP.NET (Oracle Data provider) qui sera utilis dans cette section. Vous le trouverez ladresse suivante : http://www.oracle.com/technology/ software/tech/windows/odpnet/index.html. Dans votre projet .NET, noubliez pas dajouter la rfrence la DLL dOracle :
using Oracle.DataAccess.Client; // C#

120

Exploitez vos donnes sur Oracle

Vous pouvez ensuite vous connecter la base de donnes Oracle via sa chane de connexion qui doit ressembler ceci :
OraDb= (DESCRIPTION= (ADDRESS_LIST= (ADDRESS=(PROTOCOL=TCP)(HOST=OTNSRVR)(PORT=1521)) ) (CONNECT_DATA= (SERVER=DEDICATED) (SERVICE_NAME=ORCL) ) )

Il faut donc placer cette chane de connexion dans une variable an de pouvoir lutiliser plus tard dans le programme :
string oradb = "Data Source=(DESCRIPTION=" + "(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=ORASRVR)(PORT=1521)))" + "(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCL)));" + "User Id=scott;Password=tiger;";

Une fois la chane sauve, vous pouvez crer une connexion partir de cette chane de la manire suivante :
OracleConnection conn = new OracleConnection(oradb);

Ou si vous prfrez :
OracleConnection conn = new OracleConnection(); conn.ConnectionString = oradb;

Et comme vous le feriez pour SQL Serveur, ouvrir la connexion :


conn.Open();

La suite est pratiquement la mme que ce que vous connaissez avec SQL Serveur. Vous devez crer une commande :
string sql = "select dname from dept where deptno = 10"; // C# OracleCommand cmd = new OracleCommand(sql, conn); cmd.CommandType = CommandType.Text;

121

Exploiter vos sources de donnes

Et utiliser un Reader pour aller rechercher les rsultats :


OracleDataReader dr = cmd.ExecuteReader(); dr.Read(); label1.Text = dr["dname"].ToString(); // C# retrieve by column name label1.Text = dr.GetString(0).ToString(); // return a .NET data type label1.Text = dr.GetOracleString(0).ToString(); // return an Oracle data type

On peut alors prendre les valeurs du Reader :


label1.Text = dr.GetInt16("deptno").ToString();

Et terminer la connexion proprement, comme nous laurions fait avec SQL Serveur :
conn.Close(); conn.Dispose();

Voici une meilleure faon de faire lorsquon voit le code dans son ensemble :
using (OracleConnection conn = new OracleConnection(oradb)) { conn.Open(); OracleCommand cmd = new OracleCommand(); cmd.Connection = conn; cmd.CommandText = "select dname from dept where deptno = 10"; cmd.CommandType = CommandType.Text; OracleDataReader dr = cmd.ExecuteReader(); dr.Read(); label1.Text = dr.GetString(0); }

Gestion derreur
Lorsque vous programmez, noubliez jamais de traiter correctement les erreurs, notamment louverture dune connexion.

122

Exploitez vos donnes sur Oracle

Pour grer efficacement les erreurs, utilisez try catch :


try { conn.Open(); OracleCommand cmd = new OracleCommand(); cmd.Connection = conn; cmd.CommandText = "select dname from dept where deptno = " + textBox1.Text; cmd.CommandType = CommandType.Text; if (dr.Read()) // C# { label1.Text = dr["dname"].ToString(); // or use dr.GetOracleString(0).ToString() } } catch (Exception ex) // catches any error { MessageBox.Show(ex.Message.ToString()); } finally { // In a real application, put cleanup code here. }

Le provider Oracle fournit une srie derreurs que vous pouvez interprter laide de lobjet OracleException :
catch (OracleException ex) // catches only Oracle errors { switch (ex.Number) { case 1: MessageBox.Show("Corruption clef primaire"); break; case 12545: MessageBox.Show("La base de donnes ne rpond pas."); break; default: MessageBox.Show("Autre erreur: " + ex.Message.ToString()); break; } } catch (Exception ex) // catches any error

123

Exploiter vos sources de donnes

{ MessageBox.Show(ex.Message.ToString()); }

Si vous effectuez une requte qui rapatrie plusieurs lments, utilisez la mthode Read du DataReader :
while (dr.Read()) // C# { listBox1.Items.Add("The " + dr["dname"].ToString() + " department is in " + dr["loc"].ToString()); }

Voil notre introduction laccs aux donnes via Oracle termine. Il y a bien entendu beaucoup plus de choses faire avec cette DLL mais ce nest pas lobjectif de notre livre. Reportez-vous lannexe 3, Webographie, pour obtenir les liens qui vous guideront vers de linformation sur le sujet.

3.3 MySQL et Silverlight


MySQL est une base de donnes trs rpandue. Elle est souvent combine des projets PHP. Si vous tes habitu PHP et MySQL, nous vous conseillons la lecture du tutorial suivant : http://nico-pyright.developpez.com/tutoriel/vs2008/csharp/silverlightandmysql/. Sur le site de MySQL, vous trouverez assez facilement un provider pour .NET. MySQL nest pas fort diffrent dOracle et SQL Serveur dans la manire de rechercher les donnes. Le nom des objets va vite vous donner une ide de son fonctionnement :
private private private private private MySqlConnection conn; DataTable data; MySqlDataAdapter da; System.Windows.Forms.DataGrid dataGrid; MySqlCommandBuilder cb;

Nous avons galement besoin dune chane de connexion :


string connStr = String.Format("server={0};user " + "id={1}; password={2}; database=mysql; pooling=false", server.Text, userid.Text, password.Text );

124

MySQL et Silverlight

La chane de connexion est plus petite que pour Oracle et SQL Serveur. Cest quasiment la seule chose qui changera dans notre code. Aprs avoir enregistr cette chane de connexion, nous pouvons louvrir :
try { conn = new MySqlConnection( connStr ); conn.Open(); GetDatabases(); } catch (MySqlException ex) { MessageBox.Show( "Error connecting to the server: " + ex.Message ); }

Nous pouvons ensuite dclarer une commande et lexcuter :


MySqlDataReader reader = null; conn.ChangeDatabase( databaseList.SelectedItem.ToString() ); MySqlCommand cmd = new MySqlCommand("SHOW TABLES", conn); try { reader = cmd.ExecuteReader(); tables.Items.Clear(); while (reader.Read()) { // traitement } } catch (MySqlException ex) { MessageBox.Show("Failed to populate table list: " + ex.Message ); } finally { if (reader != null) reader.Close(); }

Nous avons vu ici comment changer la base de donnes concerne par la requte, ce qui ne peut pas se faire dans les autres providers. Vous devrez, chaque fois, utiliser une chane de connexion diffrente pour chaque base de donnes.

125

Exploiter vos sources de donnes

Vous avez aussi la possibilit dutiliser des DataTable :


data = new DataTable(); da = new MySqlDataAdapter("SELECT * FROM " + tables.SelectedItem.ToString(), conn ); cb = new MySqlCommandBuilder( da ); da.Fill( data ); dataGrid.DataSource = data;

Cest peu prs tout ce que vous devez connatre sur les connexions un serveur MySQL.

3.4 LINQ
LINQ est apparu avec le Framework 3.0 de la plateforme .NET. Il a vite t apprci par les dveloppeurs pour la facilit quil apporte et sa merveilleuse intgration dans Visual Studio 2008. LINQ a su plaire aux dveloppeurs qui avaient lhabitude daller rechercher leurs donnes dans des bases de donnes : SQL Serveur dans un premier temps. Il existe maintenant profusion de providers qui permettent de connecter dautres SGBD. En effet, mme si le SQL est un langage de choix, il nexiste pas de compilateur qui sache reprer une erreur dans notre syntaxe SQL. Il nexiste pas non plus dIntelliSense pour SQL. Ce nest videmment pas la seule raison de ce succs. LINQ est trs facile prendre en main. En effet, sa syntaxe est simple et ressemble beaucoup au SQL. Voyez par vous-mme lexemple dun projet LINQ to Object :
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace LINQ { class Program { static void Main(string[] args) { string[] names = { "Burke", "Connor", "Frank", "Everett", "Albert", "George", "Harris", "David" };

126

LINQ

IEnumerable<string> query = from s in names where s.Length == 5 orderby s select s.ToUpper(); foreach (string item in query) Console.WriteLine(item); Console.ReadLine(); } } }

Nous retrouvons les diffrents lments qui constituent une requte SQL :
j j j

From ; Where ; Order by, etc.

Il existe de nombreux projets LINQ. La communaut .NET sest empare du projet pour ltendre dautres sources de donnes. Voici un tableau rcapitulatif et non exhaustif des diffrents projets LINQ :
Tableau 3.1 : Liste des providers LINQ Provider LINQ to Object LINQ to SQL LINQ to XML LINQ to DataSet LINQ to Entities LINQ to Amazon LINQ to Active Directory LINQ to Bindable Sources LINQ over C# LINQ to CRM Description Permet dutiliser LINQ sur des collections dobjets. Permet dutiliser LINQ avec une source de donnes relationnelles (SQL Serveur pour le moment). Utilis pour manipuler des sources XML Un provider pour utiliser LINQ avec des DataSets LINQ sappuyant sur un modle dentit Providers pour attaquer les donnes dAmazon Providers pour contacter Active Directory Permet de facilement la gestion des tats dune application. Permet de passer du C# laide de LINQ. Providers pour CRM

127

Exploiter vos sources de donnes

Tableau 3.1 : Liste des providers LINQ LINQ to Geo LINQ to Excel LINQ to Expressions LINQ to FlickR LINQ to Google LINQ to Indexes LINQ to JSON LINQ to NHibernate LINQ to JavaScript LINQ to LDAP LINQ to LLBLGen Pro LINQ to Lucene LINQ to Metaweb LINQ to MySQL, Oracle et PostGreSql LINQ to NCover LINQ to Opf3 LINQ to Parallel LINQ to RDF File LINQ to SharePoint LINQ to SimpleDB LINQ to Streams LINQ to WebQueries LINQ to WMI LINQ to XtraGrid LINQ pour manipuler des donnes go spatiales LINQ pour manipuler des tableaux Excel Permet de manipuler des arbres en utilisant LINQ. Permet daller rechercher des informations sur un compte FlickR. LINQ pour requter Google Permet dajouter la notion dindex LINQ. Pour manipuler JSON laide de LINQ Permet de faire le pont entre LINQ et NHibernate. Permet dutiliser LINQ dans du JavaScript. Permet de manipuler un annuaire LDAP avec LINQ. Permet dtendre LINQ to SQL (prise en charge de plus de fonctionnalits venant de SQL). LINQ pour la manipulation de chanes de caractres LINQ pour Freebase LINQ pour Oracle, MySQL et PostGreSql (implmentation de LINQ to SQL 2) LINQ pour NCover LINQ pour le Framework Opf3 Aussi appel PLINQ, permet de programmer en multi core avec LINQ. Comme son nom lindique, permet de manipuler des chiers RDF laide de LINQ. Permet de manipuler les listes SharePoint avec LINQ. LINQ to SQL pour Amazon SimpleDB Manipulation de donnes de streaming avec LINQ Permet de traiter le Web comme une base de donnes. LINQ pour WMI LINQ pour manipuler les grids

128

LINQ

Le tableau parle de lui-mme, il existe ce jour normment de providers pour LINQ. Nous nallons pas les dtailler tous dans ce livre.

LINQ, un peu dexplication


Pour comprendre comment fonctionne LINQ, nous devons reprendre notre exemple et le dcomposer :
IEnumerable<string> query = from s in names where s.Length == 5 orderby s select s.ToUpper();

La premire chose qui choque, lorsque nous rencontrons une requte LINQ, ce sont les nouveaux mot-cls :
from ; where ; j orderby ; j select, etc.
j j

Ces mots-cls ont t introduits dans le Framework 3.0. Lorsque le compilateur tombe sur ces mots-cls, il transforme tout en succession de mthodes :
IEnumerable<string> query = names .Where(s => s.Length == 5) .OrderBy(s => s) .Select(s => s.ToUpper());

Nous nallons pas nous terniser sur le sujet tant il est vaste. Nous verrons juste un exemple dutilisation de LINQ to XML qui nous permettra de manipuler du XAML.

LINQ to XML par lexemple


Notre exemple est assez basique. Rcuprer du XAML dun Web service et lutiliser avec LINQ to XML pour linjecter dynamiquement dans notre code. Cest un exemple assez courant lorsquon apprend ASP.NET ; nous allons ici ladapter Silverlight. Nous crerons donc une application Silverlight munie uniquement dun StackPanel. Dans cet lment, nous viendrons charger dynamiquement du contenu :
<UserControl x:Class="HDI_Silverlight_LinqandXaml_sl_cs.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

129

Exploiter vos sources de donnes

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="400" Height="300" Loaded="UserControl_Loaded"> <Grid x:Name="LayoutRoot" Background="White"> <StackPanel VerticalAlignment="Top" x:Name="stkMenu" Orientation="Horizontal"></StackPanel> </Grid> </UserControl>

Dans le code attach notre chier XAML, nous allons instancier un objet qui se connectera au Web service que nous verrons plus tard :
using using using using System; System.Windows; System.Windows.Controls; System.Xml.Linq;

namespace HDI_Silverlight_LinqandXaml_sl_cs { public partial class Page : UserControl { public Page() { InitializeComponent(); } private void UserControl_Loaded(object sender, RoutedEventArgs e) { MenuServiceReference.MenuServiceClient msc = new MenuServiceReference.MenuServiceClient(); msc.GetMenuItemsCompleted += new EventHandler<MenuServiceReference.GetMenuItems CompletedEventArgs> (msc_GetMenuItemsCompleted); msc.GetMenuItemsAsync(); } void msc_GetMenuItemsCompleted(object sender, MenuServiceReference.GetMenuItemsCompletedEventArgs e) { foreach (XElement xe in e.Result) { stkMenu.Children.Add(System.Windows.Markup.XamlReader.Load (xe.ToString()) as UIElement); } }

130

LINQ

} }

Toujours le mme fonctionnement. On va rechercher le contenu et on appelle une mthode une fois le contenu tlcharg. Si on regarde au niveau de notre Web service, nous avons une interface :
using System.Collections.Generic; using System.ServiceModel; using System.Xml.Linq; namespace HDI_Silverlight_LinqandXaml_web_cs { [ServiceContract] public interface IMenuService { [OperationContract] List<XElement> GetMenuItems(); } }

Cette interface ne dnit quune mthode. Cette mthode est complte dans la classe qui implmente linterface :
using System.Collections.Generic; using System.Linq; using System.Xml.Linq; namespace HDI_Silverlight_LinqandXaml_web_cs { public class MenuService : IMenuService { public List<XElement> GetMenuItems() { List<XElement> menuelementlist = new List<XElement>(); XNamespace xmlns = "http://schemas.microsoft.com/client/2007"; var elements = from x in DataBaseClass.GetDataElements() select new XElement(xmlns + x.ElementType, new XAttribute("Width", x.Width), new XAttribute("Height", x.Height), new XAttribute("Content", x.Content));

131

Exploiter vos sources de donnes

menuelementlist = elements.ToList<XElement>(); return menuelementlist; } } }

Cest dans ce chier que lon voit lutilisation de LINQ to XML. LINQ va rechercher les donnes dans une classe DataBaseClass :
using using using using System; System.Collections.Generic; System.Linq; System.Web;

namespace HDI_Silverlight_LinqandXaml_web_cs { public static class DataBaseClass { public static List<DataElement> GetDataElements() { List<DataElement> lst = new List<DataElement>(); lst.Add(new DataElement { ElementType = "Button", Width = "100", Height = "50", Content = "Menu Item 1" }); lst.Add(new DataElement { ElementType = "Button", Width = "150", Height = "50", Content = "Menu Item 2" }); lst.Add(new DataElement { ElementType = "Button", Width = "100", Height = "50", Content = "Menu Item 3" }); return lst; } } public class DataElement { public string ElementType { get; set; } public string Width { get; set; } public string Height { get; set; } public string Content { get; set; } } }

132

LINQ

Cette classe fait office de base de donnes. On aurait pu imaginer aller rechercher lobjet dans une base de donnes. Une fois le Web service termin, nous devons ajouter une rfrence dans notre projet Silverlight, ce qui cre un chier ServiceReference.cong :
<configuration> <system.serviceModel> <bindings> <basicHttpBinding> <binding name="BasicHttpBinding_IMenuService" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647"> <security mode="None" /> </binding> </basicHttpBinding> </bindings> <client> <endpoint address="http://localhost:7107/MenuService.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IMenuService" contract="MenuServiceReference.IMenuService" name="BasicHttpBinding_IMenuService" /> </client> </system.serviceModel> </configuration>

Lexemple est termin. Il vous reste dclarer un tag Silverlight dans une page pour tester votre code :
<%@ Page Language="C#" AutoEventWireup="true" %> <%@ Register Assembly="System.Web.Silverlight" Namespace="System.Web.UI.SilverlightControls" TagPrefix="asp" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" style="height:100%;"> <head runat="server"> <title>HDI-Silverlight-LinqandXaml-sl-cs</title> </head> <body style="height:100%;margin:0;"> <form id="form1" runat="server" style="height:100%;"> <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>

133

Exploiter vos sources de donnes

<div style="height:100%;"> <asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/HDI-Silverlight-LinqandXaml-sl-cs.xap" MinimumVersion="2.0.31005.0" Width="100%" Height="100%" /> </div> </form> </body> </html>

Nous pouvons maintenant passer la partie Web service qui vous permettra de mieux comprendre comment les exemples prcdents fonctionnent. LINQ est trs complexe et le Framework a du connatre beaucoup de modication et dajout pour permettre lutilisation de LINQ. Reportez-vous lannexe 3, Webographie, si vous souhaitez plus dinformation sur lutilisation de LINQ. Aujourdhui, le provider LINQ le plus utilis est LINQ to Entities. Il vous permet de vous connecter votre base de donnes et traiter les donnes de celle-ci comme si sagissait dobjets que vous avez lhabitude de manipuler dans vos programmes.

3.5 Les Web services


Les Web services sont apparus avec le Web 2.0. Cest lune des meilleures choses qui soit arriv au Web. Ils permettent dexposer des donnes dans un format standard an que tout le monde puisse les utiliser. Cest loptique du Web 2.0 ; celle du partage dans tous les sens du terme. On voit pourtant encore trop de sites web se fermer sur eux-mmes alors quune bonne API permet de crer un systme dapplications qui gravite autour. Cest le cas de Twitter ou encore Flickr qui grce leur API se voient utiliser par de nombreuses autres applications qui ajoutent des fonctionnalits un service dj existant. Vient le problme de rentabilit. Exposer des donnes pour que dautres les consommes cote normment dargent. Microsoft propose donc certain de ces Web services payants, comme Live Earth, pour des utilisations grande chelle. Ce qui est certain, cest que le modle conomique du Web 2.0 nest pas encore trs clair. Peu importe, ces Web services sont l et il faut que vous sachiez les exploiter dans vos applications Silverlight. Voire mme crer vous-mme vos Web services pour consommer vos donnes plus facilement.

134

Les Web services

Le Framework .NET propose plusieurs types de Web services. Pour comprendre, il faut un petit historique. En fait, avant larrive de Silverlight et du Framework 3.0, les Web services se craient avec ASP.NET sous forme de chier asmx. Depuis, Microsoft a introduit WCF (Windows Communication Foundation). Cette nouvelle brique du Framework permet de crer des Web services respectant des normes qui ne sont plus seulement les normes de Microsoft mais des normes appliques un peu partout sur le Web. Ce qui a pour but de crer un Web interoprable, cest--dire o la technologie utilise ninuence plus les donnes quelle peut manipuler. Ainsi, si WCF expose des donnes, du code PHP sera capable daller rechercher linformation, etc. De la mme manire, du code .NET pourra rcuprer de linformation en provenance de PHP ou Ruby. Cest ce qui se passe lorsque vous contactez lAPI Twitter puisque Twitter et son API sont dvelopps en Ruby et pourtant, .NET sait facilement lire les donnes exposes sur lAPI. Dans lexemple qui va nous servir dapprentissage, nous allons crer deux Web services diffrents. Un en ASP.NET, mme si vous navez pas encore eu le temps de lire le chapitre dintroduction. Un autre, en WCF, qui exposera des donnes simples et complexes, que nous devrons exploiter dans notre application Silverlight. Vous devez donc crer une application Silverlight dans Visual Studio. Visual Studio vous demande ensuite si vous souhaitez attacher un projet ASP.NET votre projet Silverlight. Cest le cas ici. Dans ce projet ASP.NET, nous devons ajouter un chier ASMX (chier de Web service) :

c Fig. 3.1 : Cration dun Web service

135

Exploiter vos sources de donnes

Web service WCF


Sur la mme image, on remarque la prsence dun chier WCF. Lorsque vous crerez un chier SVC (Web service WCF), vous devrez revenir sur le mme cran et slectionner Web service WCF.

Vous avez donc un nouveau chier dans votre projet :


<%@ WebService Language="C#" CodeBehind="~/App_Code/SimpleAsmx.cs" Class="SimpleAsmx" %>

Ce chier fait rfrence un autre chier situ dans App_Code. Si ce chier nexiste pas, crez-le. Ce chier dnira les diffrentes mthodes que notre Web service expose :
using using using using using using using System; System.Collections; System.Linq; System.Web; System.Web.Services; System.Web.Services.Protocols; System.Xml.Linq;

/// <summary> /// Summary description for SimpleAsmx /// </summary> [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding (ConformsTo = WsiProfiles.BasicProfile1_1)] // To allow this Web service to be called from script, // using ASP.NET AJAX, uncomment the following line. // [System.Web.Script.Services.ScriptService] public class SimpleAsmx : System.Web.Services.WebService { public SimpleAsmx() { //Uncomment the following line if using //designed components //InitializeComponent(); } [WebMethod] public string HelloWorld() {

136

Les Web services

return "Hello World"; } [WebMethod] public string SayHelloToMe(string name) { return string.Format("Hello {0}, how are you?", name); } }

Nous avons ici deux mthodes exposes. Pour exposer une mthode, il suffit de lui appliquer un attribut WebMethod. La premire fonction fait un clbre Hello World et la deuxime prend un paramtre et demande lutilisateur comment il va. Notre Web service ASP.NET est termin. Nous pouvons faire la mme chose pour WCF. De la mme manire, vous allez voir apparatre dans votre projet un nouveau chier dont lextension est svc :
<%@ ServiceHost Language="C#" Debug="true" Service="SimpleWCF" CodeBehind="~/App_Code/SimpleWCF.cs" %>

Ce chier fait rfrence un chier code dans App_Code comme pour le Web service ASP.NET :
using using using using using using System; System.Collections.Generic; System.Linq; System.Runtime.Serialization; System.ServiceModel; System.Text;

// NOTE: If you change the class name "SimpleWCF" // here, you must also update the reference to // "SimpleWCF" in Web.config. public class SimpleWCF : ISimpleWCF { #region ISimpleWCF Members public string SayHelloToMe(string name) { return string.Format("Hello {0}, how are you today?", name); }

137

Exploiter vos sources de donnes

#endregion #region ISimpleWCF Members

public List<Person> GetPeople() { List<Person> ppl = new List<Person>(); ppl.Add(new }); ppl.Add(new }); ppl.Add(new "Ballmer" return ppl; } #endregion } Person() { FirstName = "Tim", LastName = "Heuer" Person() { FirstName = "Zane", LastName = "Heuer" Person() { FirstName = "Steve", LastName = });

Nous avons ici deux mthodes. Lune renvoie un texte et lautre, une srie de personnes. Ici, pas dattributs. Tout se trouve dans linterface implmente par notre classe SimpleWCF :
using using using using using using System; System.Collections.Generic; System.Linq; System.Runtime.Serialization; System.ServiceModel; System.Text;

[ServiceContract] public interface ISimpleWCF { [OperationContract] string SayHelloToMe(string name); [OperationContract] List<Person> GetPeople(); } [DataContract] public class Person { [DataMember]

138

Les Web services

public string FirstName; [DataMember] public string LastName; }

Du ct de notre Silverlight, nous navons pas normment de chose. Juste un textbox pour donner son nom et un textblock pour afficher les rsultats. Un bouton se trouve galement dans notre XAML pour demander laccs au Web service :
<UserControl x:Class="WebServicesApp.Page" xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="400" Height="300"> <Grid x:Name="LayoutRoot" Background="White"> <StackPanel x:Name="OurStack" Orientation="Vertical"> <TextBox x:Name="InputText"></TextBox> <TextBlock x:Name="OutputText"></TextBlock> <ItemsControl x:Name="PeopleList"> <ItemsControl.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding FirstName}" /> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> <Button x:Name="CallServiceButton" Content="Call WCF Simple" Click="CallServiceButton_Click"></Button> </StackPanel> </Grid> </UserControl>

Au niveau de la gestion de lvnement, dans le code attach au chier, nous avons ceci lorsque nous voulons contacter le Web service ASP.NET :
private void CallServiceButton_Click(object sender, RoutedEventArgs e) { // using ASMX Web service SimpleASMX.SimpleAsmxSoapClient proxy = new WebServicesApp.SimpleASMX.SimpleAsmxSoapClient(); proxy.SayHelloToMeCompleted += new EventHandler<WebServicesApp.SimpleASMX .SayHelloToMeCompletedEventArgs>(proxy_SayHelloToMeCompleted); proxy.SayHelloToMeAsync(InputText.Text); }

139

Exploiter vos sources de donnes

Avec comme mthode pour afficher le rsultat :


void proxy_SayHelloToMeCompleted(object sender, WebServicesApp.SimpleASMX.SayHelloToMeCompletedEventArgs e) { OutputText.Text = e.Result; }

Si nous souhaitons contacter le service WCF avec la mthode simple, nous aurons :
private void CallServiceButton_Click(object sender, RoutedEventArgs e) { // using WCF Web service with simple type SimpleSVC.SimpleWCFClient proxy = new WebServicesApp.SimpleSVC.SimpleWCFClient(); proxy.SayHelloToMeCompleted += new EventHandler<WebServicesApp.SimpleSVC. SayHelloToMeCompletedEventArgs>(proxy_SayHelloToMeCompleted); proxy.SayHelloToMeAsync(InputText.Text); }

Avec exactement la mme mthode indique au-dessus (proxy_SayHelloToMeCompleted) mais utilisant la dnition de WCF :
void proxy_SayHelloToMeCompleted (object sender, WebServicesApp.SimpleSVC.SayHelloToMeCompletedEventArgs e) { OutputText.Text = e.Result; }

Pour contacter la mthode qui renvoie des donnes complexes, nous aurons :
private void CallServiceButton_Click(object sender, RoutedEventArgs e) { // using WCF Web service with complex type SimpleSVC.SimpleWCFClient proxy = new WebServicesApp.SimpleSVC.SimpleWCFClient(); proxy.GetPeopleCompleted += new EventHandler<WebServicesApp. SimpleSVC.GetPeopleCompletedEventArgs>(proxy_GetPeopleCompleted); proxy.GetPeopleAsync(); }

140

Les Web services

Avec comme mthode de traitement :


void proxy_GetPeopleCompleted(object sender, WebServicesApp.SimpleSVC.GetPeopleCompletedEventArgs e) { // result is Person[] SimpleSVC.Person[] people = e.Result; PeopleList.Items.Clear(); PeopleList.ItemsSource = people; }

Ou, si vous voulez utiliser LINQ pour ltrer les donnes, par exemple rechercher toutes les personnes dont le nom commence par B :
void proxy_GetPeopleCompleted(object sender, WebServicesApp.SimpleSVC.GetPeopleCompletedEventArgs e) { // result is Person[] SimpleSVC.Person[] people = e.Result; var filtered = from ppl in people where ppl.LastName.StartsWith("B") select ppl; PeopleList.Items.Clear(); PeopleList.ItemsSource = people; }

Au niveau du chier de conguration de Silverlight, nous avons ceci (obtenu lorsque nous avons ajout la rfrence au Web service de notre projet ASP.NET :
<configuration> <system.serviceModel> <bindings> <basicHttpBinding> <binding name="BasicHttpBinding_ISimpleWCF" maxBufferSize="65536" maxReceivedMessageSize="65536"> <security mode="None" /> </binding> <binding name="SimpleAsmxSoap" maxBufferSize="65536" maxReceivedMessageSize="65536"> <security mode="None" /> </binding> </basicHttpBinding> </bindings>

141

Exploiter vos sources de donnes

<client> <endpoint address="http://localhost:1597/WebServicesApp_Web/ SimpleWCF.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ISimpleWCF" contract="WebServicesApp.SimpleSVC.ISimpleWCF" name="BasicHttpBinding_ISimpleWCF" /> <endpoint address="http://localhost:1597/WebServicesApp_Web/ SimpleAsmx.asmx" binding="basicHttpBinding" bindingConfiguration="SimpleAsmxSoap" contract="WebServicesApp.SimpleASMX.SimpleAsmxSoap" name="SimpleAsmxSoap" /> </client> </system.serviceModel> </configuration>

Au niveau de notre page de test dans le projet ASP.NET, nous avons le code suivant :
<%@ Page Language="C#" AutoEventWireup="true" %> <%@ Register Assembly="System.Web.Silverlight" Namespace="System.Web.UI.SilverlightControls" TagPrefix="asp" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" style="height:100%;"> <head runat="server"> <title>Test Page For WebServicesApp</title> </head> <body style="height:100%;margin:0;"> <form id="form1" runat="server" style="height:100%;"> <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager> <div style="height:100%;"> <asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/WebServicesApp.xap" Version="2.0" Width="100%" Height="100%" /> </div> </form> </body> </html>

142

ADO.NET/Silverlight

Rendez-vous au chapitre 4, Silverlight et ASP.NET, pour comprendre comment fonctionne ce contrle ASP.NET Silverlight. Lapplication est termine. WCF est une technologie trs vaste. Il existe plusieurs livres sur ce sujet. Si vous souhaitez plus dinformations, nhsitez pas utiliser Google ou Live pour trouver tout ce que vous voulez savoir sur cette brique du Framework .NET.

3.6 ADO.NET/Silverlight
Silverlight peut exploiter directement les donnes sans passer par un Web service. Pour cela, nous utiliserons les mthodes prsentes dans System.Data.Services.Client. Les exemples de cette section explorent lassociation entre des lments Order et Order_Detail de la base de donnes Northwind disponible partir du Centre de tlchargement de Microsoft cette adresse : http://go.microsoft.com/fwlink/?linkid=24758.
Code de lapplication
Ce chapitre ne montrera pas de code complet mais uniquement des parties de code. Si vous voulez voir la totalit du code, rendez-vous la n de cette section. Vous devez garder en tte ce qui a t vu aux chapitres prcdents. Veillez aussi connatre llment XAML Grid qui nous permettra dafficher les donnes.

Notre application contiendra 5 zones. La premire zone est le Grid en question. Il permettra dafficher les donnes que nous allons rcolter :
<Grid.RowDefinitions> <RowDefinition Height="40"/> <RowDefinition Height="25"/> <RowDefinition Height="250"/> <RowDefinition Height="25"/> <RowDefinition Height="250"/> </Grid.RowDefinitions>

Le deuxime lment constituant notre interface est un StackPanel contenant deux boutons :
<StackPanel Orientation="Horizontal" Grid.Row="0"> <Button Content="Get Data" Width="75" Height="20" Margin="10"

143

Exploiter vos sources de donnes

Click="OnGetCustomers"/> <Button Content="Get Orders" Width="75" Height="20" Margin="10" Click="OnGetOrders"/> </StackPanel>

Ensuite, nous avons besoin de deux TextBlock : un pour afficher le client concern et lautre pour afficher dventuelles erreurs :
<TextBlock x:Name="CustomerBlock" Grid.Row="1" Text="Customers:" Grid.Column="0" FontFamily="Calibri"/> <TextBlock x:Name="textBlock" Grid.Row="3" Grid.Column="0" FontFamily="Calibri"/>

Il nous faudra ensuite deux DataGrid pour afficher les clients et les commandes associes aux clients :
<data:DataGrid Name="dataGridCustomers" Grid.Row="2" Margin="20" AutoGenerateColumns="True" ItemsSource="{Binding}" > </data:DataGrid> <data:DataGrid Name="dataGridOrders" Grid.Row="4" Margin="20" AutoGenerateColumns="True" ItemsSource="{Binding}" > </data:DataGrid>

Linterface utilisateur Silverlight complte est dnie dans lexemple XAML suivant :
<UserControl x:Class="SilverlightClientApp4.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:data="clr-namespace:System.Windows.Controls;assembly=System .Windows.Controls.Data" Width="800" Height="600">

144

ADO.NET/Silverlight

<Grid x:Name="LayoutRoot" Background="White"> <Grid.RowDefinitions> <RowDefinition Height="40"/> <RowDefinition Height="25"/> <RowDefinition Height="250"/> <RowDefinition Height="25"/> <RowDefinition Height="250"/> </Grid.RowDefinitions> <StackPanel Orientation="Horizontal" Grid.Row="0"> <Button Content="Get Data" Width="75" Height="20" Margin="10" Click="OnGetCustomers"/> <Button Content="Get Orders" Width="75" Height="20" Margin="10" Click="OnGetOrders"/> </StackPanel> <TextBlock x:Name="CustomerBlock" Grid.Row="1" Text="Customers:" Grid.Column="0" FontFamily="Calibri"/> <data:DataGrid Name="dataGridCustomers" Grid.Row="2" Margin="20" AutoGenerateColumns="True" ItemsSource="{Binding}" > </data:DataGrid> <TextBlock x:Name="textBlock" Grid.Row="3" Grid.Column="0" FontFamily="Calibri"/> <data:DataGrid Name="dataGridOrders" Grid.Row="4" Margin="20" AutoGenerateColumns="True" ItemsSource="{Binding}" > </data:DataGrid> </Grid> </UserControl>

145

Exploiter vos sources de donnes

Du ct du code, nous avons 6 actions effectuer. Dabord il faut crer linstance de la classe DataServiceContext de type NorthwindEntities :
NorthwindEntities svcContext; void OnLoaded(object sender, EventArgs args) { svcContext = new NorthwindEntities( new Uri("Northwind.svc", UriKind.Relative)); dataGridCustomers.AutoGeneratingColumn += dataGridCustomers_AutoGeneratingColumn; obsvCollCustomers = new ObservableCollection<Customer>(); OnGetCustomers(null, null); }

Dans la mthode OnGetCustomers, nous allons rechercher tous les clients dont le pays est USA :
void OnGetCustomers(object sender, EventArgs args) { DataServiceQuery<Customer> query = (DataServiceQuery<Customer>) (from customer in svcContext.Customers where customer.Country == "USA" select customer); try { query.BeginExecute(GetCustomersCallback, query); } catch (DataServiceRequestException ex) { textBlock.Text = "OnGetCustomers Error: " + ex.Response.ToString(); } dataGridOrders.DataContext = null; }

Nous avons utilis ici une mthode de CallBack. Cette mthode sexcute lorsque le traitement quon a dni au mme moment est termin. On obtient le rsultat en paramtre de cette fonction CallBack :
void GetCustomersCallback(IAsyncResult result) {

146

ADO.NET/Silverlight

try { DataServiceQuery<Customer> queryResult = (DataServiceQuery<Customer>)result.AsyncState; IEnumerable<Customer> ienumResults = queryResult.EndExecute(result); obsvCollCustomers = new ObservableCollection<Customer>(); foreach (var item in ienumResults) { obsvCollCustomers.Add(item); } Dispatcher.BeginInvoke(() => { dataGridCustomers.DataContext = obsvCollCustomers; }); } catch (DataServiceRequestException ex) { textBlock.Text = "GetCustomersCallback Error: " + ex.Response.ToString(); } }

Nous avons dni un vnement sur la gestion des colonnes. Nous supprimerons deux colonnes qui nont pas lieu dtre dans ce Grid-l. Pour ce faire, nous devons annuler la gnration si nous rencontrons ces deux colonnes :
void dataGridCustomers_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) { if (e.PropertyName == "CustomerDemographics" || e.PropertyName == "Orders") { e.Cancel = true; } }

Il faut ensuite grer la liste des commandes dun client. Pour cela, nous avions cr un bouton. Sur le clic du bouton Get Order, nous allons appeler la mthode OnGetOrders :
ObservableCollection<Order> obsvCollCustomerOrders;

147

Exploiter vos sources de donnes

void OnGetOrders(object sender, EventArgs args) { Customer selectedCustomer = (Customer)dataGridCustomers.SelectedItem; try { svcContext.BeginLoadProperty(selectedCustomer, "Orders", OnPropertyLoading, selectedCustomer); } catch (DataServiceRequestException ex) { textBlock.Text = "OnGetOrders Error: " + ex.Response.ToString(); } }

Nous demandons ici notre DataContext les commandes du client actuellement slectionn :
svcContext.BeginLoadProperty(selectedCustomer, "Orders", OnPropertyLoading, selectedCustomer);

De la mme manire, lorsque le rsultat aura t rapatri, la mthode OnPropertyLoading sera appele et cette fonction traitera les diffrentes informations, comme lajout dans le DataGrid :
void OnPropertyLoading(IAsyncResult result) { void OnPropertyLoading(IAsyncResult result) { Customer resultCustomer = result.AsyncState as Customer; try { svcContext.EndLoadProperty(result); if (resultCustomer.Orders.Count == 0) { textBlock.Text = "Customer has no orders"; dataGridOrders.DataContext = null; return; } else textBlock.Text = "Customer orders:";

148

ADO.NET/Silverlight

obsvCollCustomerOrders = new ObservableCollection<Order>(); foreach (Order order in resultCustomer.Orders) { obsvCollCustomerOrders.Add(order); } Dispatcher.BeginInvoke(() => { dataGridOrders.DataContext = obsvCollCustomerOrders; }); } catch (DataServiceRequestException ex) { textBlock.Text = "OnPropertyLoading Error: " + ex.Response.ToString(); } }

Voici le code de notre Page.xaml.cs :


using using using using using using using using using using using System; System.Collections.Generic; System.Linq; System.Net; System.Windows; System.Windows.Controls; System.Windows.Documents; System.Windows.Input; System.Windows.Media; System.Windows.Media.Animation; System.Windows.Shapes;

using SilverlightClientApp4.NorthwindSvc; using System.Data.Services.Client; using System.Collections.ObjectModel; namespace SilverlightClientApp4 { public partial class Page : UserControl { NorthwindEntities svcContext; ObservableCollection<Customer> obsvCollCustomers; ObservableCollection<Order> obsvCollCustomerOrders; public Page() {

149

Exploiter vos sources de donnes

InitializeComponent(); this.Loaded += OnLoaded; } void OnLoaded(object sender, EventArgs args) { svcContext = new NorthwindEntities( new Uri("Northwind.svc", UriKind.Relative)); dataGridCustomers.AutoGeneratingColumn += dataGridCustomers_AutoGeneratingColumn; obsvCollCustomers = new ObservableCollection<Customer>(); OnGetCustomers(null, null); } void OnGetOrders(object sender, EventArgs args) { Customer selectedCustomer = (Customer)dataGridCustomers.SelectedItem; try { svcContext.BeginLoadProperty(selectedCustomer, "Orders", OnPropertyLoading, selectedCustomer); } catch (DataServiceRequestException ex) { textBlock.Text = "OnGetOrders Error: " + ex.Response.ToString(); } } void OnPropertyLoading(IAsyncResult result) { Customer resultCustomer = result.AsyncState as Customer; try { svcContext.EndLoadProperty(result); if (resultCustomer.Orders.Count == 0) { textBlock.Text = "Customer has no orders";

150

ADO.NET/Silverlight

dataGridOrders.DataContext = null; return; } else textBlock.Text = "Customer orders:"; obsvCollCustomerOrders = new ObservableCollection<Order>(); foreach (Order order in resultCustomer.Orders) { obsvCollCustomerOrders.Add(order); } Dispatcher.BeginInvoke(() => { dataGridOrders.DataContext = obsvCollCustomerOrders; }); } catch (DataServiceRequestException ex) { textBlock.Text = "OnPropertyLoading Error: " + ex.Response.ToString(); } } void OnGetCustomers(object sender, EventArgs args) { DataServiceQuery<Customer> query = (DataServiceQuery<Customer>) (from customer in svcContext.Customers where customer.Country == "USA" select customer); try { query.BeginExecute(GetCustomersCallback, query); } catch (DataServiceRequestException ex) { textBlock.Text = "OnGetCustomers Error: " + ex.Response.ToString(); } dataGridOrders.DataContext = null; } void GetCustomersCallback(IAsyncResult result) {

151

Exploiter vos sources de donnes

try { DataServiceQuery<Customer> queryResult = (DataServiceQuery<Customer>)result.AsyncState; IEnumerable<Customer> ienumResults = queryResult.EndExecute(result); obsvCollCustomers = new ObservableCollection<Customer>(); foreach (var item in ienumResults) { obsvCollCustomers.Add(item); } Dispatcher.BeginInvoke(() => { dataGridCustomers.DataContext = obsvCollCustomers; }); } catch (DataServiceRequestException ex) { textBlock.Text = "GetCustomersCallback Error: " + ex.Response.ToString(); } } void dataGridCustomers_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) { if (e.PropertyName == "CustomerDemographics" || e.PropertyName == "Orders") { e.Cancel = true; } } } }

152

Crez un widget mto

3.7 Crez un widget mto


Avec tout ce que nous avons vu, vous tes maintenant capable de comprendre comment crer un Widget indiquant la mto.
c Fig. 3.2 : Widget mto

De nombreux sites Internet diffusent des informations de mto via Web services. Si vous avez un iPhone et que vous ayez dj manipul lapplication mto, vous avez alors dj utilis le Web service mto de Yahoo. En effet, lapplication a besoin dune connexion data pour aller rechercher linformation sur Yahoo et vous lafficher ensuite. Nous utiliserons un autre Web service. Vous pourrez trouver un grand nombre de services sur le site suivant : http://a4472706772.api.wxbug.net/. La premire chose faire est dajouter la rfrence au Web service dans votre projet Silverlight. Ceci cre un chier ServiceReferences.ClientCong :
<configuration> <system.serviceModel> <bindings> <basicHttpBinding> <binding name="WeatherBugWebServicesSoap" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647"> <security mode="None" /> </binding> </basicHttpBinding> </bindings> <client> <endpoint address="http://a4472706772.api.wxbug.net/ weatherservice.asmx" binding="basicHttpBinding" bindingConfiguration="WeatherBugWebServicesSoap" contract="WeatherService.WeatherBugWebServicesSoap" name="WeatherBugWebServicesSoap" /> </client> </system.serviceModel> </configuration>

153

Exploiter vos sources de donnes

Changement au niveau Web service


Le code prsent ici ne lest qu titre dexemples. Il se peut que le Web service change de point dentre avant que ce livre sorte. Veuillez donc vous rendre sur lURL indique prcdemment pour avoir accs au point daccs correct.

Pour notre interface, nous allons utiliser un grand nombre dimages. Vous pourrez retrouver tout ce code et les images sur le site de Micro Application :
<UserControl.Resources> <ImageBrush ImageSource="Resources/BLUE-base.png" x:Key="blueBase" /> <ImageBrush ImageSource="Resources/GRAY-base.png" x:Key="grayBase" /> <ImageBrush ImageSource="Resources/divider-vertical.png" x:Key="dividerVertical" Opacity="0.6" /> <ImageBrush ImageSource="Resources/divider-horizontal.png" x:Key="dividerHorizontal" Opacity="0.6" /> <BitmapImage UriSource="Resources/BLACK-highlight-01.png" x:Key="blackHighlight" /> <BitmapImage UriSource="Resources/undocked_cloudy.png" x:Key="CloudyBig" /> <BitmapImage UriSource="Resources/26.png" x:Key="Cloudy" /> <BitmapImage UriSource="Resources/undocked_few-showers.png" x:Key="FewShowersBig" /> <BitmapImage UriSource="Resources/5.png" x:Key="FewShowers" /> <BitmapImage UriSource="Resources/undocked_foggy.png" x:Key="FoggyBig" /> <BitmapImage UriSource="Resources/19.png" x:Key="Foggy" /> <BitmapImage UriSource="Resources/undocked_hail.png" x:Key="HailBig" /> <BitmapImage UriSource="Resources/17.png" x:Key="Hail" /> <BitmapImage UriSource="Resources/undocked_partly-cloudy.png" x:Key="PartlyCloudyBig" /> <BitmapImage UriSource="Resources/29.png" x:Key="PartlyCloudy" /> <BitmapImage UriSource="Resources/undocked_rainy.png" x:Key="RainyBig" /> <BitmapImage UriSource="Resources/8.png" x:Key="Rainy" /> <BitmapImage UriSource="Resources/undocked_snow.png" x:Key="SnowBig" /> <BitmapImage UriSource="Resources/13.png" x:Key="Snow" /> <BitmapImage UriSource="Resources/undocked_sun.png" x:Key="SunBig" /> <BitmapImage UriSource="Resources/undocked_moon-full.png" x:Key="MoonBig" /> <BitmapImage UriSource="Resources/31.png" x:Key="Sun" /> <BitmapImage UriSource="Resources/undocked_thunderstorm.png" x:Key="ThunderstormBig" /> <BitmapImage UriSource="Resources/1.png" x:Key="Thunderstorm" /> <BitmapImage UriSource="Resources/undocked_windy.png" x:Key="WindyBig" /> <BitmapImage UriSource="Resources/23.png" x:Key="Windy" />

154

Crez un widget mto

<SolidColorBrush Color="White" Opacity="0.5" x:Key="zipCodeBackground" /> </UserControl.Resources>

Nous utiliserons ces ressources de la manire suivante :


<Canvas Width="71" Background="{StaticResource dividerVertical}" Margin="5, 0, 0, 0">

Pour plus dinformations sur le binding, rendez-vous au chapitre Le langage XAML, o lon explique son fonctionnement exact. Voici le XAML complet de lapplication qui utilise les ressources :
<UserControl x:Class="WeatherWidget.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="320" Height="240" > <UserControl.Resources> <ImageBrush ImageSource="Resources/BLUE-base.png" x:Key="blueBase" /> <ImageBrush ImageSource="Resources/GRAY-base.png" x:Key="grayBase" /> <ImageBrush ImageSource="Resources/divider-vertical.png" x:Key="dividerVertical" Opacity="0.6" /> <ImageBrush ImageSource="Resources/divider-horizontal.png" x:Key="dividerHorizontal" Opacity="0.6" /> <BitmapImage UriSource="Resources/BLACK-highlight-01.png" x:Key="blackHighlight" /> <BitmapImage UriSource="Resources/undocked_cloudy.png" x:Key="CloudyBig" /> <BitmapImage UriSource="Resources/26.png" x:Key="Cloudy" /> <BitmapImage UriSource="Resources/undocked_few-showers.png" x:Key="FewShowersBig" /> <BitmapImage UriSource="Resources/5.png" x:Key="FewShowers" /> <BitmapImage UriSource="Resources/undocked_foggy.png" x:Key="FoggyBig" /> <BitmapImage UriSource="Resources/19.png" x:Key="Foggy" /> <BitmapImage UriSource="Resources/undocked_hail.png" x:Key="HailBig" /> <BitmapImage UriSource="Resources/17.png" x:Key="Hail" /> <BitmapImage UriSource="Resources/undocked_partly-cloudy.png" x:Key="PartlyCloudyBig" /> <BitmapImage UriSource="Resources/29.png" x:Key="PartlyCloudy" /> <BitmapImage UriSource="Resources/undocked_rainy.png"

155

Exploiter vos sources de donnes

x:Key="RainyBig" /> <BitmapImage UriSource="Resources/8.png" x:Key="Rainy" /> <BitmapImage UriSource="Resources/undocked_snow.png" x:Key="SnowBig" /> <BitmapImage UriSource="Resources/13.png" x:Key="Snow" /> <BitmapImage UriSource="Resources/undocked_sun.png" x:Key="SunBig" /> <BitmapImage UriSource="Resources/undocked_moon-full.png" x:Key="MoonBig" /> <BitmapImage UriSource="Resources/31.png" x:Key="Sun" /> <BitmapImage UriSource="Resources/undocked_thunderstorm.png" x:Key="ThunderstormBig" /> <BitmapImage UriSource="Resources/1.png" x:Key="Thunderstorm" /> <BitmapImage UriSource="Resources/undocked_windy.png" x:Key="WindyBig" /> <BitmapImage UriSource="Resources/23.png" x:Key="Windy" /> <SolidColorBrush Color="White" Opacity="0.5" x:Key="zipCodeBackground" /> </UserControl.Resources> <Canvas x:Name="LayoutRoot" Width="264" Height="194" Background="{StaticResource blueBase}"> <Canvas Canvas.Top="13" Canvas.Left="13" Width="230" Height="160"> <StackPanel x:Name="ConditionsScreen" > <Canvas Height="90"> <Image x:Name="ConditionsOverlay" Margin="-13,-13,0,0" Source="{StaticResource SunBig}"/> <StackPanel> <TextBlock Width="225" Height="37" TextAlignment="Right" FontSize="34" x:Name="TodayTemp" /> <TextBlock Width="225" Height="14" TextAlignment="Right" x:Name="TodayDescription" /> <TextBlock Width="225" Height="14" TextAlignment="Right" x:Name="TodayRange" /> <TextBlock Width="225" Height="14" TextAlignment="Right" x:Name="City" Text="Fetching data..." /> </StackPanel> </Canvas> <StackPanel Orientation="Horizontal" Height="53"> <Canvas Width="71" Background="{StaticResource dividerVertical}"

156

Crez un widget mto

Margin="5, 0, 0, 0"> <TextBlock FontSize="11" x:Name="TomorrowName" Foreground="White" Opacity="0.5" /> <Image x:Name="TomorrowImage" Canvas.Top="17" Canvas.Left="23" /> <TextBlock Canvas.Top="20" x:Name="TomorrowHi" Foreground="White" /> <TextBlock Canvas.Top="35" x:Name="TomorrowLo" Foreground="White" Opacity="0.5" /> </Canvas> <Canvas Width="71" Background="{StaticResource dividerVertical}" Margin="5, 0, 0, 0"> <TextBlock FontSize="11" x:Name="DayAfterName" Foreground="White" Opacity="0.5" /> <Image x:Name="DayAfterImage" Canvas.Top="17" Canvas.Left="23" /> <TextBlock Canvas.Top="20" x:Name="DayAfterHi" Foreground="White" /> <TextBlock Canvas.Top="35" x:Name="DayAfterLo" Foreground="White" Opacity="0.5" /> </Canvas> <Canvas Width="71" Margin="5, 0, 0, 0"> <TextBlock FontSize="11" x:Name="TwoDaysAwayName" Foreground="White" Opacity="0.5" /> <Image x:Name="TwoDaysAwayImage" Canvas.Top="17" Canvas.Left="23" /> <TextBlock Canvas.Top="20" x:Name="TwoDaysAwayHi" Foreground="White" /> <TextBlock Canvas.Top="35" x:Name="TwoDaysAwayLo" Foreground="White" Opacity="0.5" /> </Canvas> </StackPanel> <StackPanel Height="17" Background="{StaticResource dividerHorizontal}" Orientation="Horizontal" > <TextBlock Text="Refresh data" Margin="5, 0, 5, 0" Width="105" Foreground="White" Opacity="0.5" MouseLeftButtonUp="TextBlock_MouseLeft ButtonUp_Refresh" /> <TextBlock Text="Change ZIP" Margin="5, 0, 5, 0" Width="105" TextAlignment="Right" Foreground="White" Opacity="0.5" MouseLeftButtonUp="TextBlock_MouseLeft ButtonUp_Zip" /> </StackPanel>

157

Exploiter vos sources de donnes

</StackPanel> <StackPanel x:Name="ZipCodeScreen" HorizontalAlignment="Center" Visibility="Collapsed" Width="230"> <TextBlock Margin="0, 50, 0, 0" Text="Please enter ZIP code:" Width="130" /> <StackPanel Orientation="Horizontal" Width="120" > <TextBox x:Name="ZipCode" Width="55" MaxLength="5" FontSize="14" Background="{StaticResource zipCodeBackground}" /> <Button Content="Change" Click="Button_Click" Margin="10, 0, 0, 0" /> </StackPanel> <TextBlock Margin="0, 20, 0, 0" Width="220" Text="Weather data courtesy of WeatherBug." /> </StackPanel> <Image IsHitTestVisible="False" Source="{StaticResource blackHighlight}" /> </Canvas> </Canvas> </UserControl>

Dans le code C# attach ce chier XAML, nous avons tout ce qui est connexion au Web service. Cest l que nous irons rechercher les donnes concernant la mto. Nous avons une classe Page qui drive de UserControl, comme dans chaque projet Silverlight :
using using using using using using using using using System; System.ServiceModel; System.Windows; System.Windows.Controls; System.Windows.Input; System.Windows.Media; System.Windows.Media.Imaging; WeatherWidget.WeatherService; System.Windows.Browser;

namespace WeatherWidget { public enum WeatherConditions { Cloudy,

158

Crez un widget mto

FewShowers, Foggy, Hail, PartlyCloudy, Rainy, Snow, Sun, Moon, Thunderstorm, Windy } public partial class Page : UserControl { public Page() { } } }

Nous avons une numration qui permet de choisir limage qui sera affiche. Dans les ressources, nous avons dclar deux arrire-plans. Un pour les bonnes journes et lautre pour les mauvaises journes. Par dfaut, le soleil est affich :
<Canvas x:Name="LayoutRoot" Width="264" Height="194" Background="{StaticResource blueBase}">

Au niveau des ressources, nous avions bien :


<ImageBrush ImageSource="Resources/BLUE-base.png" x:Key="blueBase" /> <ImageBrush ImageSource="Resources/GRAY-base.png" x:Key="grayBase" />

Grce lajout de la rfrence vers le Web service, nous pouvons crer un projet de type :
WeatherBugWebServicesSoapClient
private WeatherBugWebServicesSoapClient proxy;

En plus de cet objet, nous avons besoin de deux variables :


// Veuillez obtenir une clef pour lapi cette adresse : // http://www.weatherbug.com/api/default.asp private const string apiCode = ""; private int zipCode = 98101;

159

Exploiter vos sources de donnes

Le code postal en dur


Nous avons ici impos un code postal lapplication. Nous aurions pu dcider que ce code serait donn par lutilisateur. Il sagit seulement dun code de base. Lutilisateur est apte changer ce code via une textbox. On pourra alors faire une nouvelle fois appel au Web service avec une nouvelle valeur pour le code postal.

Dans le constructeur de notre application, nous allons crer et initialiser ce qui concerne notre Web service :
public Page() { // Required to initialize variables InitializeComponent(); // Check that user provided an API key if (!String.IsNullOrEmpty(apiCode)) { // Initialize Web service proxy = new WeatherBugWebServicesSoapClient(); // Create event handlers for service methods proxy.GetForecastByUSZipCodeCompleted += new EventHandler<GetForecastByUSZipCodeCompletedEventArgs> (proxy_GetForecastByUSZipCodeCompleted); proxy.GetLiveWeatherByUSZipCodeCompleted += new EventHandler<GetLiveWeatherByUSZipCodeCompletedEventArgs> (proxy_GetLiveWeatherByUSZipCodeCompleted); // Update display UpdateDisplay(); } else { // If no API key was provided, alert the user and disable the UI City.Text = "No API key provided"; ConditionsScreen.IsHitTestVisible = false; ZipCodeScreen.IsHitTestVisible = false; } }

La premire fonction utilise est InitializeComponent. Elle est prsente dans toutes les applications. Elle permet dinitialiser les diffrents composants XAML de lapplication.

160

Crez un widget mto

Par exemple, dans notre cas :


[System.Diagnostics.DebuggerNonUserCodeAttribute()] public void InitializeComponent() { if (_contentLoaded) { return; } _contentLoaded = true; System.Windows.Application.LoadComponent(this, new System.Uri ("/WeatherWidget;component/Page.xaml", System.UriKind.Relative)); this.LayoutRoot = ((System.Windows.Controls.Canvas)(this.FindName ("LayoutRoot"))); this.ConditionsScreen = ((System.Windows.Controls.StackPanel) (this.FindName("ConditionsScreen"))); this.ConditionsOverlay = ((System.Windows.Controls.Image) (this.FindName("ConditionsOverlay"))); this.TodayTemp = ((System.Windows.Controls.TextBlock)(this.FindName ("TodayTemp"))); this.TodayDescription = ((System.Windows.Controls.TextBlock)(this.FindName ("TodayDescription"))); this.TodayRange = ((System.Windows.Controls.TextBlock)(this.FindName ("TodayRange"))); this.City = ((System.Windows.Controls.TextBlock) (this.FindName("City"))); this.TomorrowName = ((System.Windows.Controls.TextBlock)(this.FindName ("TomorrowName"))); this.TomorrowImage = ((System.Windows.Controls.Image)(this.FindName ("TomorrowImage"))); this.TomorrowHi = ((System.Windows.Controls.TextBlock)(this.FindName ("TomorrowHi"))); this.TomorrowLo = ((System.Windows.Controls.TextBlock)(this.FindName ("TomorrowLo"))); this.DayAfterName = ((System.Windows.Controls.TextBlock)(this.FindName ("DayAfterName"))); this.DayAfterImage = ((System.Windows.Controls.Image)(this.FindName ("DayAfterImage"))); this.DayAfterHi = ((System.Windows.Controls.TextBlock)(this.FindName ("DayAfterHi"))); this.DayAfterLo = ((System.Windows.Controls.TextBlock)(this.FindName ("DayAfterLo"))); this.TwoDaysAwayName = ((System.Windows.Controls.TextBlock)(this.FindName ("TwoDaysAwayName"))); this.TwoDaysAwayImage = ((System.Windows.Controls.Image)(this.FindName ("TwoDaysAwayImage"))); this.TwoDaysAwayHi = ((System.Windows.Controls.TextBlock) (this.FindName("TwoDaysAwayHi"))); this.TwoDaysAwayLo = ((System.Windows.Controls.TextBlock)(this.FindName ("TwoDaysAwayLo")));

161

Exploiter vos sources de donnes

this.ZipCodeScreen = ((System.Windows.Controls.StackPanel) (this.FindName("ZipCodeScreen"))); this.ZipCode = ((System.Windows.Controls.TextBox) (this.FindName("ZipCode"))); }

Ensuite, nous crons notre instance du type objet WeatherBugWebServiceSoapClient :


proxy = new WeatherBugWebServicesSoapClient();

Nous avons dclar ce proxy prcdemment dans le code an davoir accs cette variable partout dans le reste des fonctions. Cest donc un variable globale. Nous ajoutons aprs deux vnements qui seront intercepts par les deux fonctions suivantes :
j j

proxy_GetForecastByUSZipCodeCompleted ; proxy_GetLiveWeatherByUSZipCodeCompleted.

Le type des arguments est dni dans la rfrence. Nous avons par exemple GetLiveWeatherByUSZipCodeCompletedEventArgs :
[System.Diagnostics.DebuggerStepThroughAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")] public partial class GetLiveWeatherByUSZipCodeCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs { private object[] results; public GetLiveWeatherByUSZipCodeCompletedEventArgs (object[] results, System.Exception exception, bool cancelled, object userState) : base(exception, cancelled, userState) { this.results = results; } public WeatherWidget.WeatherService.LiveWeatherData Result { get { base.RaiseExceptionIfNecessary(); return ((WeatherWidget.WeatherService.LiveWeatherData) (this.results[0])); } } }

162

Crez un widget mto

Ce code est automatiquement gnr par lajout de la rfrence au Web service. Il est toutefois important de savoir comment cela fonctionne. Vous serez parfois dans lobligation de dclarer vous-mme ces objets. Quoi quil en soit, Visual Studio gre pour vous une grande partie du projet. Les deux fonctions vnements doivent tre dclares. La premire permet de connatre les prvisions mto et la deuxime le temps actuel :
void proxy_GetForecastByUSZipCodeCompleted(object sender, GetForecastByUSZipCodeCompletedEventArgs e) { ArrayOfAnyType forecast = e.Result; // Set the remaining three days, except for today for (int i = 1; i < 4; i++) { ApiForecastData today = (ApiForecastData)forecast[i]; setDay(i, today.Title, parseTemp(today.TempHigh), parseTemp(today.TempLow), int.Parse(today.ConditionID)); } // Then call for todays live data, and pass the conditions well need later proxy.GetLiveWeatherByUSZipCodeAsync(zipCode.ToString(), UnitType.English, apiCode, forecast[0]); } void proxy_GetLiveWeatherByUSZipCodeCompleted(object sender, GetLiveWeatherByUSZipCodeCompletedEventArgs e) { LiveWeatherData today = e.Result; ApiForecastData todayForecast = (ApiForecastData)e.UserState; // Set todays conditions setToday(today.City, todayForecast.ShortPrediction, float.Parse(today.Temperature), parseTemp(today.TemperatureHigh), parseTemp(today.TemperatureLow), int.Parse(todayForecast.ConditionID), !todayForecast.IsNight); }

163

Exploiter vos sources de donnes

Dans la premire fonction, nous avons besoin de setDay. Cette fonction va rechercher les lments XAML pour y afficher les bonnes valeurs, au bon endroit. Elle emploie une fonction "utilitaire" pour convertir le temps :
static int parseTemp(string input) { int temp; // Remove trailing unrecognized characters input = input.TrimEnd(\xFFFD); // If the hi/lo is unavailable, set it to 0 if (String.IsNullOrEmpty(input) || input == "--") { temp = 0; } else { temp = int.Parse(input); } return temp; }

SetDay permet de mettre jour les diffrents lments de notre XAML :


private void setDay(int offset, string name, int hi, int lo, int weatherConditions) { TextBlock todayName; TextBlock todayHi; TextBlock todayLo; Image todayImage; switch (offset) { case 1: todayName = TomorrowName; todayHi = TomorrowHi; todayLo = TomorrowLo; todayImage = TomorrowImage; break; case 2: todayName = DayAfterName; todayHi = DayAfterHi; todayLo = DayAfterLo; todayImage = DayAfterImage;

164

Crez un widget mto

break; case 3: default: todayName = TwoDaysAwayName; todayHi = TwoDaysAwayHi; todayLo = TwoDaysAwayLo; todayImage = TwoDaysAwayImage; break; } todayName.Text = name.ToString(); todayHi.Text = hi.ToString() + ""; todayLo.Text = lo.ToString() + ""; todayImage.Source = mapConditionsToImage(mapCodesToConditions (weatherConditions, true), false); }

On voit que dans le switch, on recherche les bons lments XAML au bon endroit. Cela se fera en fonction du choix de laffichage des prvisions pour le jour un, deux ou trois et de loffset qui est pass en paramtre. Ensuite, on indique les bonnes valeurs, valeurs passes en paramtre de notre fonction. On mappe aprs limage qui correspond aux valeurs :
private BitmapImage mapConditionsToImage(WeatherConditions weatherConditions, bool isBig) { // Build the resource name - something like RainyBig string resourceName = Enum.GetName(typeof(WeatherConditions), weatherConditions) + (isBig ? "Big" : ""); return (BitmapImage)Resources[resourceName]; }

La

valeur

passe

en

paramtre

est

obtenue

laide

dune

fonction

MapCodesToConditions. Cette fonction tant peu complexe mais excessivement longue,

nous lavons place la n de cet exemple, dans une partie portant le nom de la fonction. Lautre fonction dont nous avons besoin est celle qui va afficher le temps quil fait actuellement dehors. Cette fonction se nomme SetToday et nous lavons utilise dans proxy_GetLiveWeatherByUSZipCodeCompleted. Elle suit plus ou moins le mme principe :
private void setToday(string cityName, string description, float temp, int hi, int lo, int weatherConditions, bool isDay)

165

Exploiter vos sources de donnes

{ // Set the weather parameters City.Text = cityName; TodayTemp.Text = temp.ToString() + ""; TodayDescription.Text = description; TodayRange.Text = hi + " - " + lo + ""; // Set the correct background according to the conditions WeatherConditions currentConditions = mapCodesToConditions(weatherConditions, isDay); // Set correct main image according to the conditions ConditionsOverlay.Source = mapConditionsToImage (currentConditions, true); if (!isDay || (currentConditions == WeatherConditions.Moon) || (currentConditions == WeatherConditions.Cloudy) || (currentConditions == WeatherConditions.Foggy) || (currentConditions == WeatherConditions.Hail) || (currentConditions == WeatherConditions.Rainy) || (currentConditions == WeatherConditions.Snow) || (currentConditions == WeatherConditions.Thunderstorm)) { LayoutRoot.Background = (ImageBrush)Resources["grayBase"]; } else { LayoutRoot.Background = (ImageBrush)Resources["blueBase"]; } }

On met une valeur quelques champs et on fait appel aux mmes mthodes que dans la premire fonction : mapConditionsToImage et mapCodesToConditions. Le constructeur fait ensuite appel une fonction UpdateDisplay pour mettre jour toutes les donnes :
private void UpdateDisplay() { // Call for the 4 day forecast first proxy.GetForecastByUSZipCodeAsync (zipCode.ToString(), UnitType.English, apiCode); }

166

Crez un widget mto

Cette mthode dclenche les deux autres vnements qui mettent jour les donnes de notre application Silverlight. Nous lutiliserons un peu partout dans notre code. Comme indiqu dans la remarque prcdemment, nous disposons dun bouton qui permet de mettre jour le code postal. Nous avons donc ajout un vnement sur le clic du bouton :
private void Button_Click(object sender, RoutedEventArgs e) { bool error = false; if (ZipCode.Text.Length == ZipCode.MaxLength) { try { zipCode = int.Parse(ZipCode.Text); UpdateDisplay(); // Switch to conditions screen ConditionsScreen.Visibility = Visibility.Visible; ZipCodeScreen.Visibility = Visibility.Collapsed; } catch (FormatException) { error = true; } } else { error = true; } if(error) ZipCode.Foreground = new SolidColorBrush(Colors.Red); }

Ce bouton va rechercher le code postal dans une textbox, le transforme en chiffre et met jour le contenu de notre application. Nous vnements grer du ct de notre code. TextBlock_MouseLeftButtonUp_Zip est lun de ces vnements. Il permet en fait dafficher la textbox pour modier le code postal :
private void TextBlock_MouseLeftButtonUp_Zip (object sender, MouseButtonEventArgs e) { ZipCode.Text = "";

avons

encore

deux

167

Exploiter vos sources de donnes

ZipCode.Foreground = new SolidColorBrush (Colors.Black); // Switch to ZIP code selection screen ConditionsScreen.Visibility = Visibility.Collapsed; ZipCodeScreen.Visibility = Visibility.Visible; }

Enn, nous disposons dun bouton permettant de rafrachir le contenu. Pour cela, il suffit dappeler la mthode dj dclare prcdemment :
private void TextBlock_MouseLeftButtonUp_Refresh (object sender, MouseButtonEventArgs e) { UpdateDisplay(); }

Lapplication du ct Silverlight est termine. Reste crer une page HTML de test pour afficher notre application dans un navigateur. Au niveau de notre page HTML, rien de trs difficile :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <!-- saved from url=(0014)about:internet --> <head> <title>Silverlight Project Test Page </title> <style type="text/css"> html, body { height: 100%; overflow: auto; } body { padding: 0; margin: 0; } #silverlightControlHost { height: 100%; } </style> <script type="text/javascript"> function onSilverlightError(sender, args) {

168

Crez un widget mto

var appSource = ""; if (sender != null && sender != 0) { appSource = sender.getHost().Source; } var errorType = args.ErrorType; var iErrorCode = args.ErrorCode; var errMsg = "Unhandled Error in Silverlight 2 Application " + appSource + "\n" ; errMsg += "Code: "+ iErrorCode + " \n"; errMsg += "Category: " + errorType + " \n"; errMsg += "Message: " + args.ErrorMessage + " \n"; if (errorType == "ParserError") { errMsg += "File: " + args.xamlFile + " \n"; errMsg += "Line: " + args.lineNumber + " \n"; errMsg += "Position: " + args.charPosition + " \n"; } else if (errorType == "RuntimeError") { if (args.lineNumber != 0) { errMsg += "Line: " + args.lineNumber + " \n"; errMsg += "Position: " + args.charPosition + " \n"; } errMsg += "MethodName: " + args.methodName + " \n"; } throw new Error(errMsg); } </script> </head> <body> <!-- Runtime errors from Silverlight will be displayed here. This will contain debugging information and should be removed or hidden when debugging is completed --> <div id=errorLocation style="font-size: small;color: Gray;"> </div> <div id="silverlightControlHost"> <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%"> <param name="source"

169

Exploiter vos sources de donnes

value="ClientBin/WeatherWidget.xap"/> <param name="onerror" value="onSilverlightError" /> <param name="background" value="white" /> <param name="minRuntimeVersion" value="2.0.30923.0" /> <param name="autoUpgrade" value="true" /> <a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;"> <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/> </a> </object> <iframe visibility=hidden height=0 width=0 border=0px></iframe> </div> </body> </html>

Notre premier exemple est termin. Nous avons vu ici comment contacter un Web service. Dans le prochain exemple, nous apprendrons manipuler les donnes RSS.

MapCodesToConditions
static WeatherConditions mapCodesToConditions(int weatherConditions, bool isDay) { WeatherConditions conditions; switch (weatherConditions) { case 1: case 13: case 24: case 34: case 66: case 68: case 73: conditions = WeatherConditions.Cloudy; break; case 9: case 19: case 21: case 25:

170

Crez un widget mto

case case case case case case case case case case case case case case case case case case case case case case case case case case case case case case case case case case case case case case case case case case case case

27: 28: 32: 36: 46: 47: 48: 49: 56: 57: 60: 61: 84: 85: 86: 90: 91: 92: 96: 97: 98: 99: 100: 101: 120: 121: 122: 123: 124: 125: 129: 130: 131: 135: 136: 137: 140: 142: 144: 145: 152: 153: 155: 157: conditions = WeatherConditions.FewShowers; break; case 23:

171

Exploiter vos sources de donnes

case 33: case 51: conditions = WeatherConditions.Foggy; break; case 2: case 3: case 16: case 67: case 71: case 72: conditions = WeatherConditions.PartlyCloudy; break; case 5: case 14: case 15: case 20: case 38: case 41: case 42: case 45: case 52: case 58: case 59: case 63: case 81: case 82: case 83: case 87: case 88: case 89: case 108: case 109: case 110: case 114: case 115: case 116: case 132: case 133: case 134: case 139: case 141: case 148: case 150: case 156: conditions = WeatherConditions.Rainy; break; case 8:

172

Crez un widget mto

case case case case case case case case case case case case case case case case case case case case case case case case case case case case case case case case

11: 12: 29: 39: 40: 43: 44: 54: 55: 62: 69: 74: 78: 79: 80: 102: 103: 104: 111: 112: 113: 117: 118: 119: 126: 127: 128: 138: 146: 149: 151: 154: conditions = WeatherConditions.Snow; break; case 0: case 7: case 10: case 17: case 26: case 31: case 35: case 37: case 64: case 65: case 70: case 75: case 76:

173

Exploiter vos sources de donnes

case 77: default: conditions = (isDay) ? WeatherConditions.Sun : WeatherConditions.Moon; break; case 6: case 18: case 22: case 30: case 53: case 93: case 94: case 95: case 105: case 106: case 107: case 143: case 147: conditions = WeatherConditions.Thunderstorm; break; case 50: conditions = WeatherConditions.Windy; break; } return conditions; }

3.8 Traitez un ux de donnes RSS


RSS est un format de donnes bas sur XML. Il permet la plupart du temps de stocker des actualits (titre, description, date etc.). Le format RSS est utilis partout : sur des blogs, des forums, des sites dactualit, etc. Il tait donc trs important de pouvoir lexploiter correctement dans Silverlight. Encore une fois, ce nest pas dans Silverlight que nous allons trouver la solution mais dans C#. En effet, le Framework 3.0 nous offre une nouveaut des plus utiles et souvent sous-exploite : la classe SyndicationFeed. partir de ce moment-l, il devient simple de crer une application Silverlight parvenant lire du RSS. Notre application est compose dun header (haut de lapplication) et de deux colonnes : lune pour afficher les diffrents titres du RSS et lautre pour afficher une vue plus dtaille du contenu du RSS (de llment slectionn pour tre plus exact).

174

Traitez un ux de donnes RSS

Pour le header, rien de trs compliqu : une textbox et un bouton, peu de choses prs :
<StackPanel Orientation="Vertical" Width="845" > <TextBlock Text="Enter feed address below. If this control and the feed are not hosted on the same domain, add a clientaccesspolicy.xml or crossdomain.xml file to domain where the feed is hosted to enable cross-domain access." TextWrapping="Wrap" FontSize="14" /> <StackPanel Orientation="Horizontal" Margin="0, 10, 0, 10"> <TextBox Width="400" x:Name="feedAddress" FontSize="14"/> <Button Content="Fetch feed" Margin="20, 0, 0, 0" FontSize="14" Click="Button_Click" /> </StackPanel>

Ensuite, pour les deux colonnes du bas qui affichent le contenu, nous avons une ListBox et un StackPanel avec un ScrollViewer pour afficher le texte :
<StackPanel Orientation="Horizontal" Margin="0, 10, 0, 10"> <TextBox Width="400" x:Name="feedAddress" FontSize="14"/> <Button Content="Fetch feed" Margin="20, 0, 0, 0" FontSize="14" Click="Button_Click" /> </StackPanel> <StackPanel Orientation="Horizontal"> <ListBox x:Name="itemsList" ItemsSource="{Binding}" Width="325" Height="500" SelectionChanged="itemsList_SelectionChanged" Visibility="Collapsed"> <ListBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding Title.Text, Converter={StaticResource htmlSanitizer}}" TextWrapping="Wrap" Width="300" FontSize="14"/> </DataTemplate> </ListBox.ItemTemplate> </ListBox> <StackPanel x:Name="itemContent" Orientation="Vertical" Width="500" Height="500" Margin="20, 0, 0, 0" Visibility="Collapsed"> <HyperlinkButton Content="{Binding Title.Text, Converter={StaticResource htmlSanitizer}}"

175

Exploiter vos sources de donnes

NavigateUri="{Binding Links, Converter={StaticResource linkFormatter}}" FontSize="16" TargetName="_blank" /> <TextBlock Text="{Binding PublishDate}" TextWrapping="Wrap" FontSize="14" /> <ScrollViewer Height="445" Margin="0, 10, 0, 0"> <TextBlock Text="{Binding Summary.Text, Converter={StaticResource htmlSanitizer}}" TextWrapping="Wrap" FontSize="14"/> </ScrollViewer> </StackPanel> </StackPanel>

Sans oublier que nous avons besoin de deux ressources stockes au tout dbut de notre code dans les ressources de lusercontrol :
<UserControl.Resources> <local:HtmlSanitizer x:Key="htmlSanitizer"/> <local:LinkFormatter x:Key="linkFormatter"/> </UserControl.Resources>

Au niveau du code, rien dextraordinaire non plus. Dans le constructeur, nous mettrons une valeur par dfaut dans la textbox :
public Page() { InitializeComponent(); // Start with a default feed feedAddress.Text = "http://feeds.wired.com/wired/index?format=xml"; }

Sur le clic du bouton, nous allons instancier un objet WebClient. Cet objet ira tlcharger le contenu. Nous pourrons ensuite traiter le contenu avec notre objet SyndicationFeed, laide dun vnement.
Le code asynchrone
On voit souvent le mot async utilis dans le code. En fait, il sagit de traiter plusieurs choses en parallle pour augmenter la vitesse dexcution. Ce que nous faisons ici, cest dire : "Va rechercher le contenu et notie-nous dun vnement quand tu as ni". Cest pour cela que lvnement sappelle client_OpenReadCompleted, completed signiant complet.

176

Traitez un ux de donnes RSS

private void Button_Click(object sender, RoutedEventArgs e) { itemsList.Visibility = Visibility.Collapsed; itemContent.Visibility = Visibility.Collapsed; // Make HTTP request to get feed WebClient client = new WebClient(); client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted); client.OpenReadAsync(new Uri(feedAddress.Text)); }

Le rsultat sera transmis en paramtre de lvnement. Nous pouvons donc le rcuprer dans la fonction client_OpenReadCompleted qui sera appele lorsque le tlchargement du contenu sera ni :
void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e) { if (e.Error == null) { // Load feed into SyndicationFeed XmlReader reader = XmlReader.Create(e.Result); SyndicationFeed feed = SyndicationFeed.Load(reader); // Set up databinding itemsList.DataContext = (feed as SyndicationFeed).Items; itemsList.Visibility = Visibility.Visible; } }

Nous avions dans les ressources deux objets qui sont des converters. On utilise ces objets pour convertir une valeur. Par exemple, nous allons recevoir un texte mais il faut quil soit bien format. Pour cette raison, nous avons une classe HtmlSanitizer :
public class HtmlSanitizer : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { // Remove HTML tags and empty newlines and spaces string returnString = Regex.Replace(value as string, "<.*?>", "");

177

Exploiter vos sources de donnes

returnString = Regex.Replace(returnString, @"\n+\s+", "\n\n"); // Decode HTML entities returnString = HttpUtility.HtmlDecode(returnString); return returnString; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } }

Lobjet implmente une interface IValueConverter. Cest de cette manire que le programme sait que cest un converter. Nous avons la mme chose pour LinkFormatter :
public class LinkFormatter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { // Get the first link - thats the link to the post return ((Collection<SyndicationLink>)value).FirstOrDefault().Uri; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } }

Au niveau de notre page de test HTML, nous avons la mme chose que dhabitude :
<div id="Div1"> <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%"> <param name="source" value="ClientBin/SyndicationFeedReader.xap"/>

178

Check-list

<param name="onerror" value="onSilverlightError" /> <param name="background" value="white" /> <param name="minRuntimeVersion" value="2.0.30923.0" /> <param name="autoUpgrade" value="true" /> <a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;"> <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/> </a> </object> <iframe visibility=hidden height=0 width=0 border=0px></iframe> </div>

Cet exemple court mais utile est maintenant termin.

c Fig. 3.3 : Notre application termine

Nous allons tudier dans le prochain chapitre les concepts avancs de Silverlight. Vous verrez aussi par la suite comment amliorer linsertion de Silverlight lorsque vous utilisez ASP.NET comme technologie serveur.

3.9 Check-list
Dans ce chapitre nous avons tudi :

a lexploitation des sources de donnes SQL ; a lutilisation des Web services ; a LINQ ; a la manipulation XML au travers dun exemple ; a la manipulation de donnes RSS au travers dun exemple.

179

4
4.1 Introduction ASP.NET ................................. 4.2 Les contrles ASP.NET .................................. 4.3 Les contrles ASP.NET pour Silverlight ................ 4.4 Interaction de Silverlight avec la page ............... 4.5 Check-list ................................................. 182 191 198 210 211

Silverlight et ASP.NET
A
SP.NET est une technologie base sur la plateforme .NET de Microsoft qui vous permet de crer des sites web simplement. Plongez-vous dans ce chapitre si vous souhaitez connatre tout ce quil faut savoir sur la conception et le dveloppement dapplications web avec ASP.NET et Silverlight.

Silverlight et ASP.NET

4.1 Introduction ASP.NET


ASP.NET a accs toutes les classes du Framework .NET qui est un ensemble de composants pouvant tre utiliss dans diffrents langages de programmation (grce la CLR, Common Language Runtime) ; les plus connus sont :
j j j

VB.NET successeur de VB ; C#, nouveau langage spcialement conu pour la plateforme .NET ; J# qui a t introduit spcialement pour permettre la rutilisation des blocs crits en J++ et attirer les dveloppeurs Java, etc.

Il en existe bien dautres (Cobol, PHP, ). On notera larrive de deux nouveaux, rcemment :
j j

IronRuby qui, comme son nom lindique, est un driv de Ruby ; IronPython qui, de la mme manire, est un driv de Python.

En rsum, peu importe le langage utilis, Microsoft met votre disposition un ensemble doutils qui vous faciliteront lcriture dune application ou/et dun site Internet. Lensemble de ces outils constitue le Framework .NET. Nous sommes aujourdhui la version 3.5 du Framework .NET. La version 3.0 a t introduite avec Vista. Vous pouvez trouver la version 3.5 sur Internet (voir Les prrequis dans ce chapitre).

ASP.NET
ASP.NET dsigne un ensemble de technologies qui vont vous simplier lcriture dapplications web dynamiques. ASP.NET succde ASP mais ne vous y trompez pas, ce nest pas du tout la mme chose. Le concept a t compltement repens. Dans cet ensemble de technologies on trouvera, par exemple, des outils qui nous permettront de faciliter la gestion de la scurit. En effet, scuriser des pages et crer des espaces membres est un jeu denfants en ASP.NET. De la mme manire, la gestion des donnes est trs simple de prime abord. Si les composants ASP.NET ne suffisent pas, vous avez accs tout ce que le Framework .NET vous propose. Le but ici nest pas de dcrire lensemble des fonctionnalits de ASP.NET mais de vous donner tous les outils et connaissances de base pour crer et comprendre votre premier site ASP.NET.

182

Introduction ASP.NET

Prrequis
Les sceptiques se disent certainement quavec Microsoft, il va falloir payer. Mais ce nest pas le cas. On peut bien programmer avec ASP.NET gratuitement. Il existe en effet une gamme express des produits Microsoft qui vous permet dobtenir des outils suffisants pour la cration de vos premiers projets. Vous pouvez ds lors employer Visual Web Developer Express pour dvelopper vos sites Internet et SQL Server 2005 Express comme base de donnes. Vous trouverez ces deux outils ici : http://msdn.microsoft.com/fr-fr/express/aa975050.aspx.
Les outils en anglais
Si vous matrisez langlais, prenez soin de choisir les versions anglaises qui sont plus compltes au niveau du support et de la compatibilit. Il est beaucoup plus dlicat dinstaller Silverlight pour Visual Studio dans sa version franaise que dans sa version anglaise.

Si vous dsirez directement utiliser les outils professionnels, tlchargez Visual Studio 2008. Vous pouvez galement tlcharger le Framework 3.5 cette adresse : http://www.microsoft .com/downloads/details.aspx?FamilyId=333325FD-AE52-4E35-B531-508D977D32A6&displaylang=en. Cependant, ce nest pas obligatoire, le Framework 2.0 install par dfaut sur tout les Windows (XP, Vista, Windows Server) est largement suffisant pour crer des applications web. Le 3.5 apportent de nombreuses nouveauts quil nest pas intressant de connatre quand on dbute la programmation web avec ASP.NET.

Premier exemple
Que vous possdiez Visual Web Developer ou Visual Studio, la procdure est la mme. La premire chose faire est de crer un site web. Pour cela, rendez-vous dans le menu File/New/Web Site.

183

Silverlight et ASP.NET

c Fig. 4.1 : Fentre dapplication

Slectionnez ASP.NET Web Site, donnez-lui un nom et cliquez sur OK. Visual Studio/Web Developer cre pour vous un ensemble de chiers et de dossiers pour vous aider dmarrer. Vous pouvez voir ces chiers dans lExplorateur de solution.
c Fig. 4.2 : Explorateur de solution

Default.aspx est souvent la page par dfaut dun site ASP.NET. Ceci est congurable dans IIS, le programme traitant les demandes sur des pages Internet (qui coute sur le port 80 par exemple). Cest ce que fait Apache si vous tes habitu travailler avec PHP, Ruby, etc. Default.aspx a un chier qui lui est attach. Il est nomm Default.aspx.cs.

184

Introduction ASP.NET

c Fig. 4.3 : Fichier Default.aspx

Cest dans ce chier que se trouvera toute la logique mtier de notre page. Microsoft a voulu sparer le design et le code. Vous aurez donc tout laspect graphique au niveau de Default.aspx et tout laspect code au niveau de Default.aspx.cs (on appelle le code contenu dans ce chier le code behind). Ceci nest pas obligatoire, vous pouvez dclarer le design et le code dans un mme chier. Le code se trouvera alors entre des balises script mais cela nuit la lisibilit du code et la comprhension de celui-ci. Default.aspx ressemble ceci lorsque vous louvrez :
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Untitled Page</title> </head> <body> <form id="form1" runat="server"> <div> </div> </form> </body> </html>

Cette page ne fait rien du tout. Si vous voulez obtenir un aperu dans le navigateur, cliquez du bouton droit sur le nom de la page dans lExplorateur de solution et cliquez sur View in browser. Par dfaut, votre navigateur se lance et affiche une page blanche. En fait, le contenu de votre page doit tre situ entre les balises form. Nous reviendrons plus tard sur ces balises. La premire ligne de notre page indique un certain nombre dinformations :
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

185

Silverlight et ASP.NET

Cette ligne est appele une directive. Toutes les directives dune page commencent par <%@ et nissent par %>. Ces directives permettent de dclarer des informations ncessaires au compilateur pour compiler la page. Par exemple, nous avons besoin de savoir quel langage est utilis (Language="C#") pour connatre le compilateur qui traitera la page ou le chier contenant le code (CodeFile="Default.aspx.cs"). Le reste de la page devrait vous tre familier si vous avez lhabitude de programmer des sites Internet. On retrouve une ligne pour le dtd :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

Visual Studio et les DTD


Visual Studio gre bien ce dtd et indique une erreur lorsque vous ne le respectez pas dans votre HTML.

Le reste de la page ne devrait pas vous poser de gros problme de comprhension, mis part le form.
<html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Untitled Page</title> </head> <body> <form id="form1" runat="server"> <div> </div> </form> </body> </html>

Au niveau du code attach notre page, nous obtenons ceci :


using using using using using using using System; System.Configuration; System.Data; System.Linq; System.Web; System.Web.Security; System.Web.UI;

186

Introduction ASP.NET

using using using using

System.Web.UI.HtmlControls; System.Web.UI.WebControls; System.Web.UI.WebControls.WebParts; System.Xml.Linq;

public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } }

Code attach
Nous avons chaque fois ce principe de deux chiers. Un pour le code, lautre pour la reprsentation. En effet, en Silverlight on trouve un chier XAML et un chier de code. En ASP.NET, nous avons un chier HTML et un autre chier pour le code. Ce principe est appliqu partout dans les technologies Microsoft.

On remarque directement des usings qui permettent de faciliter lutilisation des composants du Framework .NET. Par exemple, sans using System.IO, vous devriez crire dans votre code :
System.IO.File.Exists("file.txt");

Avec le using, vous simpliez votre code :


File.Exists("file.txt");

Les usings qui sont par dfaut affichs dpendent du Framework que vous utilisez. Ici, nous avons employ la dernire version de celui-ci (3.5). Ne vous inquitiez pas si vous avez des usings diffrents des miens. Ce qui suit est plus intressant. On voit la dclaration dune classe qui hrite de Page et dclare une mthode Page_Load. Cette mthode est un exemple devent handler. Celle-ci dclenche lvnement Load de notre page ; elle sera excute chaque fois que nous rechargerons la page, Load en anglais signiant Chargement. Il existe de nombreux vnements dclenchs au chargement de la page que nous verrons un peu plus loin.

187

Silverlight et ASP.NET

Outre toutes les balises HTML que vous connaissez, ASP.NET propose de nombreux contrles qui vous simplieront lcriture de vos applications web. Ces derniers commencent tous par <asp :. On trouvera, parmi les plus utiliss :
j j j j

le le le le

Label ; GridView ; Repeater ; Literal, etc.

Vous trouvez la liste entire de ces contrles dans la toolbox de votre Visual Studio/Web Developer.
c Fig. 4.4 : Barre doutils

Pour insrer lun de ces contrles dans votre page, slectionnez-le dans votre toolbox et dplacez-le sur votre page :
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs"

188

Introduction ASP.NET

Inherits="_Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Untitled Page</title> </head> <body> <form id="form1" runat="server"> <div> <asp:Label ID="Label1" runat="server" Text=" Mon premier label"></asp:Label> </div> </form> </body> </html>

Nous avons par exemple ajout un label notre page. Remarquez la proprit runat="server" qui permet dindiquer que ce contrle devra tre valu au niveau du serveur. Si vous lancez la page de votre Explorateur, vous verrez que notre asp :label a t transform en une balise span :
<span id="Label1">Mon premier label</span>

Que sest-il pass ? Le compilateur a vu un contrle qui devait tre interprt par le serveur, celui-ci la trait pour le remplacer par du HTML, comprhensible par le navigateur. Dans ce cas, lutilisation dun contrle ne savre pas utile. Lutilit vient lorsque vous traitez ce contrle dans le code behind. Vous avez en effet la possibilit dditer les proprits du label en code behind (Text, etc.) :
protected void Page_Load(object sender, EventArgs e) { Label1.Text = "Ce label a t trait dans le code behind"; }

Cela donnera le rsultat suivant :


<span id="Label1">Ce label a t trait dans le code behind</span>

189

Silverlight et ASP.NET

Code attach
Ce que vous crivez dans le code behind pour la proprit Text prend le dessus sur ce que vous avez crit dans le design de la page car lvnement Load de la page passe aprs la traitement du render de la page. La proprit de votre label est dans un premier temps gale Mon premier label mais elle est ensuite rcrite au moment du Load.

Le Web.cong
Le Web.cong est un chier que vous retrouvez la racine de votre application et qui contient toutes les informations sur la conguration de celle-ci. Si vous ouvrez le Web.cong de votre application web, vous trouverez une srie dinformations. Parmi les informations importantes :

La dclaration des lments qui se trouveront dans le Web.cong


<configSections> <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"> <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"> <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/> ... </sectionGroup> </sectionGroup> </sectionGroup> </configSections>

Les diffrentes libraires dont besoin notre application


<assemblies> <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/> <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> <add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/> </assemblies>

190

Les contrles ASP.NET

La dclaration des contrles ASP.NET


<pages> <controls> <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> <add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> </controls>

</pages>

La dclaration de nos chanes de connexion vers une base de donnes


<connectionStrings> <add name="LimbourgBDConnectionString" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\ProgrammezBD.mdf; Integrated Security=True;User Instance=True" providerName="System.Data.SqlClient"/> </connectionStrings>

4.2 Les contrles ASP.NET


Microsoft vous fournit des contrles que vous pouvez utiliser pour enrichir vos applications web. On peut rpertorier ces contrles en plusieurs catgories.

Les contrles standard


Ces contrles vous permettent dafficher des lments standard : boutons, labels, champs de texte, etc. On pourra par exemple facilement crer un formulaire simple laide de ces contrles :
<asp:Label ID="lbNom" runat="server" Text="Nom"></asp:Label> : <asp:TextBox ID="tbNom" runat="server"></asp:TextBox> <br /> <asp:Label ID="lbPrenom" runat="server" Text="Prenom"></asp:Label> : <asp:TextBox ID="tbPrenom" runat="server"></asp:TextBox> <br /> <asp:Label ID="lbEmail" runat="server" Text="Email"></asp:Label> : <asp:TextBox ID="tbEmail" runat="server"></asp:TextBox> <br /> <asp:Label ID="lb" runat="server" Text="Jai plus de 18 ans"> </asp:Label> : <asp:CheckBox ID="cbPLusDe18ans" Text="" runat="server" /><br /> <asp:Button ID="btGo" runat="server" Text="Envoyer" />

191

Silverlight et ASP.NET

Ceci sera affich sur votre navigateur Internet :


c Fig. 4.5 : Contrles de base dASP.NET

On peut regarder ce que cela gnre au niveau du code source :


<span id="lbNom">Nom</span> : <input name="tbNom" type="text" id="tbNom" /> <br /> <span id="lbPrenom">Prenom</span> : <input name="tbPrenom" type="text" id="tbPrenom" /> <br /> <span id="lbEmail">Email</span> : <input name="tbEmail" type="text" id="tbEmail" /> <br /> <span id="lb">Jai plus de 18 ans</span> : <input id="cbPLusDe18ans" type="checkbox" name="cbPLusDe18ans" /><br /> <input type="submit" name="btGo" value="Envoyer" id="btGo" />

Les contrles de validation


ASP.NET vous fournit un ensemble de contrles qui vous permettront deffectuer des vrications sur les donnes entres par les utilisateurs. On peut donc amliorer notre formulaire en ajoutant un contrle pour vrier si lemail nest pas nul :
<asp:Label ID="lbNom" runat="server" Text="Nom"></asp:Label> : <asp:TextBox ID="tbNom" runat="server"></asp:TextBox> <br /> <asp:Label ID="lbPrenom" runat="server" Text="Prenom"></asp:Label> : <asp:TextBox ID="tbPrenom" runat="server"></asp:TextBox> <br /> <asp:Label ID="lbEmail" runat="server" Text="Email"></asp:Label> : <asp:TextBox ID="tbEmail" runat="server"></asp:TextBox> <asp:RequiredFieldValidator ID="ValEmail" ControlToValidate="tbEmail" runat="server" ErrorMessage="Email Requis"></asp:RequiredFieldValidator> <br /> <asp:Label ID="lb" runat="server" Text="Jai plus de 18 ans"> </asp:Label> : <asp:CheckBox ID="cbPLusDe18ans" Text="" runat="server" /><br /> <asp:Button ID="btGo" runat="server" Text="Envoyer" />

Il existe plusieurs contrles de ce type :


j j

RequiredFieldValidator ; RangeValidator ;

192

Les contrles ASP.NET

j j j

RegularExpressionValidator ; CompareValidator ; CustomValidator.

Vous pouvez galement crer vos propres contrles de validation.

Les contrles riches


ASP.NET vous propose quelques contrles avec une relle plus-value pour vous. Par exemple, crer un calendrier dynamique en ASP.NET est vraiment trs simple. Il existe en fait un contrle asp :calendar qui vous permet dafficher un calendrier dynamique. Dans ce type de contrles, on retrouve aussi la possibilit de crer des wizards facilement (exemple : cration de formulaires en plusieurs tapes). Voici un exemple de calendrier en ASP.NET :
<asp:Calendar id="Calendar1" runat="server" BorderStyle="Double" BorderWidth="3px" DayNameFormat="FirstTwoLetters" FirstDayOfWeek="Monday" ShowGridLines="True" CellPadding="0" SelectedDate="2004-05-03"> <OtherMonthDayStyle ForeColor="LightGray"> </OtherMonthDayStyle> </asp:Calendar>

Les contrles de donnes


Les contrles de donnes permettent daller rechercher facilement des donnes dans une base ou un chier XML. Vous utiliserez ces contrles pour ce qui concerne la visualisation, lajout, la modication ou la suppression des donnes. Vous pourrez par exemple aisment afficher les donnes dans un tableau laide dun GridView et un DataSource (ObjectDataSource, SQLDataSource ou XMLDataSource en fonction de la source des donnes).
Framework 3.5 et ASP.NET 3.5
Le Framework 3.5 a apport son lot de nouveauts ce niveau avec lajout du ListView, du DataPager et du LINQDataSource.

193

Silverlight et ASP.NET

Ci-aprs, un exemple dutilisation du contrle repeater et SQLDataSource :


<asp:Repeater ID="Repeater3" runat="server" DataSourceID="DSCC"> <ItemTemplate> <h1><%# Eval("Prenom") %> <%# Eval("Nom") %></h1> <p><%# Eval("Titre") %> - <%# Eval("Biographie")%></p> </ItemTemplate> </asp:Repeater> <asp:SqlDataSource ID="DSCC" runat="server" ConnectionString="<%$ ConnectionStrings:LimbourgBDConnectionString %>" SelectCommand="SELECT TOP 3 [PersonneId], [Nom], [Prenom], [Biographie], [Titre] FROM [Personne] WHERE ([PersonneId] = @PersonneId)"> <SelectParameters> <asp:QueryStringParameter DefaultValue="1" Name="PersonneId" QueryStringField="id" Type="Int32" /> </SelectParameters> </asp:SqlDataSource>

Ces quelques lignes vont permettre dafficher une liste de personnes. Eval permet de mapper un lment avec un champ de la base de donnes. Le repeater est comme une boucle qui parcourt tous les lments de la source de donnes passe comme valeur de la proprit DataSourceID. Ici la source de donnes contient les rsultats de la requte SQL passe comme valeur la proprit SelectCommand :
SELECT TOP 3 [PersonneId], [Nom], [Prenom], [Biographie], [Titre] FROM [Personne] WHERE ([PersonneId] = @PersonneId)

@PersonneId dsigne un paramtre que nous dnissons juste aprs :


<SelectParameters> <asp:QueryStringParameter DefaultValue="1" Name="PersonneId" QueryStringField="id" Type="Int32" /> </SelectParameters>

On indique que le paramtre doit tre trouv dans lURL de la requte. On va chercher le paramtre id de lURL. Sil nexiste pas, on prend par dfaut la valeur 1. Pour simplier lcriture de ce code, Visual Studio vous fournit un wizard de paramtrage dun DataSource. Pour utiliser ce dernier, rendez-vous en mode Design et cliquez sur la petite icne en haut droite de votre SQLDataSource.

194

Les contrles ASP.NET

c Fig. 4.6 : Datasource

Cliquez sur Congure DataSource. Une nouvelle fentre apparat ; vous avez la possibilit de dnir votre chane de connexion votre base de donnes. Cette chane peut tre dnie en cliquant sur New Connection et en remplissant les diffrents champs de connexion (nom du serveur, login, mot de passe, base de donnes). En cliquant sur Suivant, un utilitaire vous permet de crer votre requte.
c Fig. 4.7 : diteur de requtes

Cliquez sur Suivant puis sur Terminer. Votre DataSource est congur. Pour en savoir plus sur SQLDataSource, consultez le lien : http://msdn.microsoft.com/fr-fr/ library/system.web.ui.webcontrols.sqldatasource.aspx.

Les contrles de navigation


Ces contrles vous permettent dafficher des lments de navigation standard : menus, arbres dlments. En effet, on peut facilement afficher un arbre dlments avec le contrle asp :TreeView :
<asp:TreeView ID="TreeView1" runat="server"> <Nodes> <asp:TreeNode Text="Ordinateur"> <asp:TreeNode Text="Favory"> <asp:TreeNode Text="News">

195

Silverlight et ASP.NET

<asp:TreeNode Text="MSN" NavigateUrl="http://www.msn.com"/> <asp:TreeNode Text="MSNBC News" NavigateUrl="http://www.msnbc.msn.com"/> </asp:TreeNode> </asp:TreeNode> </asp:TreeNode> </Nodes> </asp:TreeView>

On obtient ceci :
c Fig. 4.8 : Vue dun arbre de donnes

Vous pouvez galement mapper le contenu de votre TreeView un chier XML, par exemple. Pour plus dinformation sur les contrles de navigation : http://quickstarts.asp.net/ QuickStartv20/aspnet/doc/ctrlref/navigation/default.aspx.

Les contrles de login


Ces contrles sont trs souvent utiliss pour tout ce qui est gestion utilisateur. Vous pouvez facilement grer des comptes utilisateur avec ASP.NET. Celui-ci vous fournit les contrles pour les actions suivantes :
j j j j j j j

login dun utilisateur ; affichage du nom de lutilisateur actuellement connect ; enregistrement dun utilisateur ; perte de mots de passe ; changement de mot de passe ; affichage dlments en fonction du statut de lutilisateur (connect, non connect, dans un groupe, ou pas) ; gestion de rles dutilisateur (administrateur, membre, etc.).

Pour permettre lutilisation de ces composants, vous devez rgler ces derniers laide de ladministration centrale de votre site ASP.NET :
c Fig. 4.9 : Centrale dadministration dASP.NET

196

Les contrles ASP.NET

Dans longlet Scurit, vous pouvez choisir dutiliser ASP.NET MemberShip Provider en cliquant sur le lien Slectionnez le type dauthentication. Slectionnez Par internet. Pour plus dinformations sur les composants login, consultez le lien suivant : http:// quickstarts.asp.net/QuickStartv20/aspnet/doc/ctrlref/login/default.aspx.

Les contrles HTML


Vous pouvez utiliser les contrles HTML que vous avez lhabitude demployer et interagir avec eux dans le code behind en leur ajoutant la proprit runat=server :
Entrez votre nom : <input id="Name" type=text size=40 runat=server>

Vous pouvez alors modier les proprits de ces contrles dans le code behind :
Name.Value = "ici";

Lorsque ASP.NET voit un tag HTML avec la proprit runat, il reconnat un contrle ASP.NET. Par exemple, ici, il sait que linput est un HtmlInputText. Plus dinformations ici : http://quickstarts.asp.net/QuickStartv20/aspnet/doc/ctrlref/html/default.aspx.

Postback et ViewState
Voici une petite introduction ce qui caractrise le modle de programmation ASP.NET. Revenons sur notre exemple de formulaire. Lorsque nous voulons envoyer les informations de notre formulaire, nous devons grer un vnement sur le clic du bouton. Pour cela, nous lui dclarons un handler :
<asp:Button ID="btGo" runat="server" Text="Envoyer" onclick="btGo_Click" />

Lorsque vous cliquez sur le bouton, il y a un Postback ou une requte POST sur la page en cours. Vous devez grer cet vnement dans le code behind sur la mthode btGo _Click :
protected void btGo_Click(object sender, EventArgs e) { // Traitement ici }

En HTML, llment form permet denvoyer une requte POST (ou GET). Si on regarde le code source de notre page, on voit que notre form runat=server sest transform en formulaire :

197

Silverlight et ASP.NET

<form name="form1" method="post" action="Default.aspx" onsubmit="javascript:return WebForm_OnSubmit();" id="form1"> . </form>

Laction du formulaire est bien la page actuelle. Le JavaScript est l car il y a des choses vrier aprs lenvoi du formulaire ( cause de notre validator). On remarque galement un champ de type input appel ViewState :
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKLTcwNjkwMjI1M2QYAQUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja 0tleV9fFgEFDWNiUEx1c0RlMThhbnOWq/eV0Z6qaaIUowq3lP+t4xSruA==" />

Ce champ hidden est gr automatiquement par ASP.NET pour sauvegarder ltat des diffrents contrles de la page. Cest grce cela que lorsque vous effectuez un PostBack, vos informations sont toujours visibles dans le formulaire. Vous navez donc pas besoin de sauver vous-mme ltat des diffrents lments de votre page en ASP.NET.

4.3 Les contrles ASP.NET pour Silverlight


Avec larrive et lutilisation de plus en plus massive de Silverlight, Microsoft a d rchir pour faciliter lutilisation de Silverlight dans ASP.NET. En effet, insrer Silverlight comme nous lavons vu auparavant dans le livre nest pas une bonne ide. Voici la structure HTML dune page avec Silverlight lintrieur :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <!-- saved from url=(0014)about:internet --> <head> <title>Mastermind</title> <style type="text/css"> html, body { height: 100%; overflow: auto; } body { padding: 0; margin: 0; }

198

Les contrles ASP.NET pour Silverlight

#SilverlightControlHost { height: 100%; } </style> <script type="text/javascript"> function onSilverlightError(sender, args) { var appSource = ""; if (sender != null && sender != 0) { appSource = sender.getHost().Source; } var errorType = args.ErrorType; var iErrorCode = args.ErrorCode; var errMsg = "Unhandled Error in Silverlight 2 Application " + appSource + "\n" ; errMsg += "Code: "+ iErrorCode + " \n"; errMsg += "Category: " + errorType + " \n"; errMsg += "Message: " + args.ErrorMessage + " \n"; if (errorType == "ParserError") { errMsg += "File: " + args.xamlFile + " \n"; errMsg += "Line: " + args.lineNumber + " \n"; errMsg += "Position: " + args.charPosition + " \n"; } else if (errorType == "RuntimeError") { if (args.lineNumber != 0) { errMsg += "Line: " + args.lineNumber + " \n"; errMsg += "Position: " + args.charPosition + " \n"; } errMsg += "MethodName: " + args.methodName + " \n"; } throw new Error(errMsg); } </script> </head> <body> <!-- Les erreurs dexcution Silverlight safficheront ici. Il sagit dinformations de dbogage qui doivent tre supprimes ou masques, une fois le dbogage termin --> <div id=errorLocation style="font-size: small;color: Gray;"></div>

199

Silverlight et ASP.NET

<div id="SilverlightControlHost"> <object data="data:application/x-Silverlight," type="application/x-Silverlight-2" width="100%" height="100%"> <param name="source" value="Mastermind.xap"/> <param name="onerror" value="onSilverlightError" /> <param name="background" value="white" /> <param name="minRuntimeVersion" value="2.0.31005.0" /> <param name="autoUpgrade" value="true" /> <a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;"> <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Tlchargez Microsoft Silverlight" style="border-style: none"/> </a> </object> <iframe style=visibility:hidden;height:0;width:0;border:0px></iframe> </div> </body> </html>

On remarque diffrents lments :


j j j

Ce nest pas dans la logique de ASP.NET dutiliser des contrles HTML sinitialisant avec JavaScript. Cette page ne ressemble en rien ce que nous avons lhabitude de voir en ASP.NET. La page a perdu beaucoup de lisibilit par rapport ASP.NET.

Dautre part, nous avons vu dans un autre chapitre ce que gnrait Expression Encoder :
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd"> <!-- saved from url=(0014)about:internet --> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <script type=text/javascript src="MicrosoftAjax.js"></script> <script type=text/javascript src="Silverlight.js"></script> <script type=text/javascript src="SilverlightControl.js"></script> <script type=text/javascript src="SilverlightMedia.js"></script> <script type=text/javascript src="ExpressionPlayer.js"></script> <script type=text/javascript src="PlayerStrings.js"></script> <script type=text/javascript src="player.js"></script> <script type=text/javascript src="StartPlayer.js"></script> <title></title> <style type="text/css"> html, body { margin: 0; padding: 0; height:100% }

200

Les contrles ASP.NET pour Silverlight

#divPlayer_0 { min-height: 100%; height:100%; } </style> </head> <body style="background-color:black;margin:0,0,0,0;overflow:auto;"> <div id="divPlayer_0"> <script type=text/javascript> var player = new StartPlayer_0(); </script> </div> </body> </html>

Mme chose ici, il est trs rare de voir linsertion de chier JavaScript comme cela dans ASP.NET. Pour remdier aux deux problmes, Microsoft a introduit deux nouveaux contrles dans ASP.NET :
j j

Silverlight ; MediaPlayer.

Le contrle MediaPlayer
Le contrle serveur ASP.NET MediaPlayer vous permet dintgrer des sources de mdia telles que des lments audio (WMA) et vido (WMV) dans une application web, sans quil soit ncessaire de disposer de connaissances en XAML ou en JavaScript. Le contrle MediaPlayer peut utiliser des apparences pr gnres, ou vous pouvez crer des apparences personnalises. Par exemple, vous pouvez rfrencer un document XAML personnalis gnr via Microsoft Expression Encoder et prenant en charge des lgendes, des chapitres et des marqueurs dans la source du mdia. Lorsque vous congurez le contrle MediaPlayer pour rfrencer une apparence pr gnre, le document XAML associ est copi dans le projet. La proprit MediaSkinSource du contrle MediaPlayer est galement congure pour pointer sur lapparence rfrence. Linteraction entre le contrle MediaPlayer et la page peut se faire laide de JavaScript. Ce lecteur ASP.NET sutilise trs facilement. Vous devez rfrencer un chier jouer (par exemple, un chier .wmv, .wma ou .mp3), puis vous slectionnez une apparence intgre. Le contrle serveur MediaPlayer reconnat les formats de mdia pris en charge par le plug-in Silverlight :
<asp:MediaPlayer ID="MediaPlayer1"

201

Silverlight et ASP.NET

runat="server" MediaSource="~/Media/video.wmv" MediaSkinSource="~/MediaSkins/Professional.xaml" ScaleMode="Stretch" AutoLoad="true" AutoPlay="false" PluginBackground="Black" Height="240px" Width="320px"> </asp:MediaPlayer>

Pour fonctionner, le MediaPlayer a besoin dun contrle ASP. NET ScriptManager. Ce contrle permet la gestion des lments JavaScript. Dans une page ASP.NET qui utilise le JavaScript, le ScriptManager charge les scripts JavaScript ncessaires au bon fonctionnement de la page :
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %> <%@ Register Assembly="System.Web.Silverlight" Namespace="System.Web.UI.SilverlightControls" TagPrefix="asp" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <div> <asp:MediaPlayer ID="MediaPlayer1" runat="server" Height="240px" Width="320px" MediaSource="~/Lake.wmv"> </asp:MediaPlayer> <br /> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> </div> </form> </body> </html>

202

Les contrles ASP.NET pour Silverlight

Si vous excutez ce code et que vous regardiez le code source, vous trouverez normment de JavaScript, notamment pour la cration du lecteur :
<span id="MediaPlayer1_parent"></span> <script type="text/javascript"> //<![CDATA[ Sys.UI.Silverlight.Control.createObject(MediaPlayer1_parent, \u003cobject type="application/x-Silverlight" id="MediaPlayer1" style="height:240px;width:320px;">\r\n\t\u003ca href="http://go2.microsoft.com/fwlink/?LinkID=114576&v=1.0">\u003cimg src="http://go2.microsoft.com/fwlink/?LinkID=108181" alt="Tlchargez Microsoft Silverlight" style="border-width:0;" /> \u003c/a>\r\n\u003c/object>); //]]> </script> c Fig. 4.10 : Lecteur Silverlight

Le contrle MediaPlayer permet de faire exactement la mme chose que ce que vous aviez fait avec Expression Encoder. Il en va de mme pour la gestion des chapitres. Vous pouvez facilement ajouter des chapitres votre vido :
<%@ Page Language="C#" %> <%@ Register Assembly="System.Web.Silverlight" Namespace="System.Web.UI.SilverlightControls" TagPrefix="asp" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html > <head id="Head1" runat="server"> <title>ASP.NET Controls for Silverlight</title> <link href="~/SilverlightStyles.css" type="text/css" rel="Stylesheet" /> </head> <body> <form id="form1" runat="server">

203

Silverlight et ASP.NET

<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="false" /> <div> <asp:MediaPlayer runat="server" ID="MediaPlayer1" ScaleMode="Stretch" AutoPlay="true" MediaSource="../media/expressionstudio.wmv" Height="480" Width="640" PluginBackground="Black" MediaSkinSource="../skins/Professional.xaml"> <Chapters> <asp:MediaChapter ThumbnailSource="../media/MarkerThumb 00.00.00.jpg" Position="0.0" Title="Chapter 1" /> <asp:MediaChapter ThumbnailSource="../media/MarkerThumb 00.00.10.jpg" Position="10" Title="Chapter 2" /> <asp:MediaChapter ThumbnailSource="../media/MarkerThumb 00.00.24.jpg" Position="24" Title="Chapter 3" /> </Chapters> </asp:MediaPlayer> </div> </form> </body> </html>

Llment Chapters que vous ajoutez permet de dnir des chapitres dans votre vido.
Information en provenance de votre base de donnes
Il se peut que certaines informations proviennent de votre base de donnes comme les chapitres et lemplacement sur chier de votre vido. Dans ce cas, vous pouvez crer un Web service qui expose sous forme XML les donnes de la vido. En effet, avec la proprit MediaDefinition vous pouvez donner lemplacement dun chier XML qui dnit votre vido en respectant le modle suivant : <mediaDefinition> <mediaItems> <mediaItem mediaSource="video.wmv" placeholderSource="image0.jpg"> <chapters> <chapter position="5.00" thumbnailSource="image1.jpg" title="marker1" /> <chapter position="10.00" thumbnailSource="image2.jpg" title="marker2" />

204

Les contrles ASP.NET pour Silverlight

</chapters> </mediaItem> </mediaItems> </mediaDefinition>

Comme indiqu prcdemment dans ce chapitre, vous pouvez interagir avec le lecteur Silverlight via JavaScript.

MediaPlayer et JavaScript
Le JavaScript permet dinteragir de manire pousse avec le lecteur Silverlight. Vous pouvez par exemple crer sur la page dautres boutons qui permettent deffectuer les actions pause ou play. Ces boutons contactent alors une fonction JavaScript connecte au lecteur. On peut aussi mettre jour certains lments de la page, par exemple savoir quand un chapitre change ou quand le statut change. Vous pouvez ainsi dclarer une srie dvnements dans votre lecteur :
<asp:MediaPlayer runat="server" ID="MediaPlayer1" Width="400" Height="300" ScaleMode="Stretch" MediaSource="../media/expressionstudio.wmv" Volume="1.0" PlaceholderSource="../media/placeholder.JPG" OnClientMediaOpened="onMediaOpened" OnClientChapterStarted="onChapterChanged" OnClientMarkerReached="onMarkerReached" OnClientCurrentStateChanged="onStateChanged" OnClientVolumeChanged="onVolumeChanged"> <Chapters> <asp:MediaChapter ThumbnailSource="../media/ExpressionStudio_ MarkerThumb 00.00.00.jpg" Position="0.0" Title="Opening credits and movie start." /> <asp:MediaChapter ThumbnailSource="../media/ExpressionStudio_ MarkerThumb 00.00.10.2390000.jpg" Position="10.2390000" Title="Designing and selecting." /> <asp:MediaChapter ThumbnailSource="../media/ExpressionStudio_ MarkerThumb 00.00.24.1360000.jpg" Position="24.1360000" Title="Producing designs." /> <asp:MediaChapter ThumbnailSource="../media/ExpressionStudio_ MarkerThumb 00.00.37.9290000.jpg" Position="37.9290000"

205

Silverlight et ASP.NET

Title="Checking inventory and orders." /> <asp:MediaChapter ThumbnailSource="../media/ExpressionStudio_ MarkerThumb 00.00.52.3490000.jpg" Position="52.3490000" Title="Purchasing." /> <asp:MediaChapter ThumbnailSource="../media/ExpressionStudio_MarkerThumb 00.00.58.6180000.jpg" Position="58.6180000" Title="Reviewing." /> <asp:MediaChapter ThumbnailSource="../media/ExpressionStudio_ MarkerThumb 00.01.14.0820000.jpg" Position="74.0820000" Title="End credits." /> <asp:MediaChapter ThumbnailSource="../media/ExpressionStudio_ MarkerThumb 00.01.22.9640000.jpg" Position="82.9640000" Title="Silverlight end." /> </Chapters> </asp:MediaPlayer>

On voit ici la dclaration de plusieurs vnements :


OnClientMediaOpened ; OnClientChapterStarted ; j OnClientMarkerReached, etc.
j j

chacun de ces vnements correspond une fonction JavaScript, comme ici dans le changement de chapitre qui modie le contenu HTML dune zone HTML :
function onChapterChanged(sender, args) { // When the chapters change, set the chapter image and text in markup. var chapter = __player.get_currentChapter(); if (chapter === -1) { $get(ChapterImage).src = "../media/placeholder.jpg"; $get(ChapterIndex).innerHTML = "(none)"; } else { $get(ChapterImage).src = __player.get_currentChapter().get_thumbnailSource(); $get(ChapterIndex).innerHTML = "#" + (__player.get_chapterStarted() + 1) + " - " + __player.get_currentChapter().get_title(); $get(MovieTime).innerHTML = __player.get_position(); }

206

Les contrles ASP.NET pour Silverlight

Si on veut contrler le lecteur (play, pause, stop), nous pouvons galement le faire en JavaScript :
function onPlay() { __player.play(); $get(pause).disabled = ""; $get(stop).disabled = ""; $get(play).disabled = "disabled"; } function onPause() { __player.pause(); $get(pause).disabled = "disabled"; $get(play).disabled = ""; } function onStop() { __player.stop(); $get(pause).disabled = "disabled"; $get(stop).disabled = "disabled"; $get(play).disabled = ""; }

Cest peu prs tout ce que vous pouvez effectuer avec le contrle MediaPlayer.

Le contrle Silverlight
Grce ce contrle, vous pouvez intgrer du code XAML et tout code de prise en charge (un assembly de code manag, un module de script de langage dynamique manag ou des bibliothques JavaScript client, voir annexe) dans votre site web.
Code manag
Le code manag est un code compil. linverse dun code interprt, le code compil est organis de manire intelligente. Plus dinformation : http://en.wikipedia.org/wiki/Compiler.

Lorsque vous crez un projet Silverlight dans Visual Studio, vous avez directement la possibilit de dnir un projet ASP.NET associ. Ds que cette connexion entre les deux projets est cre, vous voyez apparatre un chier xap dans le dossier ClientBin.

207

Silverlight et ASP.NET

Le contrle Silverlight a besoin de ce chier xap. Cest ce dernier qui va tre interprt.
c Fig. 4.11 : Explorateur de solution

Si vous crez un rectangle en XAML, que vous compiliez votre application ([Ctrl]+[Maj]+[B]) et que vous utilisiez le chier xap dans votre contrle Silverlight, vous obtenez le rsultat escompt :
<UserControl x:Class="SilverlightApplication2.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="400" Height="300"> <Grid x:Name="LayoutRoot" Background="White"> <Rectangle Height="83" Margin="68,50,137,0" VerticalAlignment="Top" Stroke="#FF000000"> <Rectangle.Fill> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#FF000000"/> <GradientStop Color="#FFA31212" Offset="1"/> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> </Grid> </UserControl>

Au niveau de la page HTML/ASP.NET :


<%@ Page Language="C#" AutoEventWireup="true" %>

208

Les contrles ASP.NET pour Silverlight

<%@ Register Assembly="System.Web.Silverlight" Namespace="System.Web.UI.SilverlightControls" TagPrefix="asp" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" style="height:100%;"> <head runat="server"> <title>SilverlightApplication2</title> </head> <body style="height:100%;margin:0;"> <form id="form1" runat="server" style="height:100%;"> <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager> <div style="height:100%;"> <asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/SilverlightApplication2.xap" MinimumVersion="2.0.31005.0" Width="100%" Height="100%" /> </div> </form> </body> </html>

Rsultat :
c Fig. 4.12 : Rsultat de notre application

209

Silverlight et ASP.NET

4.4 Interaction de Silverlight avec la page


Silverlight et le code C# derrire permettent dinteragir avec les lments de la page HTML (aussi appel DOM). Avant dentamer cette partie, lisez lannexe 2, Introduction au C#. Dans le code attach, vous pouvez ainsi rechercher un lment dans la page et interagir avec celui-ci ou mme ajouter des vnements sur ce bouton :
using using using using using using using using using using using using System; System.Collections.Generic; System.Linq; System.Net; System.Windows; System.Windows.Controls; System.Windows.Documents; System.Windows.Input; System.Windows.Media; System.Windows.Media.Animation; System.Windows.Shapes; System.Windows.Browser;

namespace SilverlightApplication2 { public partial class Page : UserControl { public Page() { InitializeComponent(); HtmlElement button = HtmlPage.Document.GetElementById("HTMLButtonA"); if (button != null) button.AttachEvent("onclick", new EventHandler<HtmlEventArgs>( delegate(object o, HtmlEventArgs e) { HtmlButtonClicked("A"); })); button = HtmlPage.Document.GetElementById("HTMLButtonB"); if (button != null) button.AttachEvent("onclick", new EventHandler<HtmlEventArgs>( delegate(object o, HtmlEventArgs e) { HtmlButtonClicked("B");

210

Check-list

})); button = HtmlPage.Document.GetElementById("HTMLButtonC"); if (button != null) button.AttachEvent("onclick", new EventHandler<HtmlEventArgs>( delegate(object o, HtmlEventArgs e) { HtmlButtonClicked("C"); }));

} private void HtmlButtonClicked(string which) { HTMLMessage.Text = "HTML Button " + which + " Clicked"; } } }

On attache trois vnements trois boutons de la page et on affiche quel bouton a t cliqu par la suite. C# permet davoir des interactions bien plus fortes entre le DOM et Silverlight, mais il sagit de concepts avancs qui ne seront pas abords dans ce livre. Pour plus dinformations, rendez-vous sur le site de MSDN (voir Annexe 3, Webographie).

4.5 Check-list
Nous avons tudi dans ce chapitre :

a lensemble des contrles ASP.NET ; a le contrle media pour jouer des vidos Silverlight ; a le contrle Silverlight pour mieux intgrer vos applications dans ASP.NET.

211

5
5.1 Le DataBinding en dtails .............................. 5.2 Les Styles et ControlTemplates ......................... 5.3 Crer un UserControl ................................... 5.4 Les contrles de la librairie System.Windows. Controls .................................................. 5.5 Le contrle DataGrid ................................... 5.6 Les contrles Silverlight Toolkit de CodePlex ......... 5.7 Check-list ................................................. 214 220 225 246 253 269 271

Concepts avancs
D
j

ans ce chapitre, nous allons approfondir les connaissances acquises au chapitre 2, Le langage XAML. Ce chapitre traitera principalement de linteraction humain-machine. Cette interaction peut tre simplie : pour le dveloppeur dune part, DataBinding deux sens, aux ControlTemplates et aux UserControls ; grce au Styles et

pour lutilisateur de lautre, grce une amlioration considrable de la qualit de linterface.

Concepts avancs

5.1 Le DataBinding en dtails


Jusqu prsent, nous avons utilis le DataBinding an dafficher des informations pour lutilisateur. Cependant, le DataBinding permet aussi de demander ce dernier des informations. En effet, une fois lie linterface et pour peu que linterface prsente des lments dentres utilisateur, une donne peut tre modie par lutilisateur sans que le dveloppeur nait crire la moindre ligne de code dans le code de la logique applicative. Lexemple que nous allons dvelopper ensemble va permettre lutilisateur de grer une liste de lms et de leur attribuer une apprciation en nombre dtoiles. Tout dabord, il faut dnir les objets Films. Un Film est un objet reprsent par son Titre, son Ralisateur et son Apprciation :
Film.cs
using using using using using using using using using using System; System.Net; System.Windows; System.Windows.Controls; System.Windows.Documents; System.Windows.Ink; System.Windows.Input; System.Windows.Media; System.Windows.Media.Animation; System.Windows.Shapes;

namespace Filmotheque { public class Film { private string titre; public string Titre { get { return titre; } set { titre = value; } } private string ralisateur; public string Ralisateur { get { return ralisateur; } set { ralisateur = value; } }

214

Le DataBinding en dtails

private int nombreDEtoiles; public int NombreDEtoiles { get { return nombreDEtoiles; } set { nombreDEtoiles = value; } } public Film() { } } }

Au cours de ce chapitre, nous aurons aussi besoin dune collection de lms sur laquelle travailler. Prenons les devants et dclarons-la :
Collection de lms
using using using using using using using using using using using System; System.Net; System.Windows; System.Windows.Controls; System.Windows.Documents; System.Windows.Ink; System.Windows.Input; System.Windows.Media; System.Windows.Media.Animation; System.Windows.Shapes; System.Collections.Generic;

namespace Filmotheque { public static class CollectionDeFilms { public static List<Film> Films = new List<Film>() { new Film() { Titre="Retour vers le Prsent 7", Ralisateur="Takis Ergopoulos", NombreDEtoiles=5}, new Film() { Titre="Il faut sauver le magicien dOz", Ralisateur="Orhan Benekhol", NombreDEtoiles=1}, new Film() { Titre="La guerre des Chtis",

215

Concepts avancs

Ralisateur="Gautier Lebeaugros", NombreDEtoiles=4}, new Film() { Titre="2009 lodise des Interfaces", Ralisateur="Ilkay Nmtzakis", NombreDEtoiles=3}, new Film() { Titre="Silverlight 2 Ze Movie", Ralisateur="Salvador Bargelot", NombreDEtoiles=4}, }; } }

DataContext
Lattribut DataContext est prsent dans chaque lment dinterface Silverlight. Cest lunit de ce quest la multitude ItemSource dune ListBox. Ainsi, lorsque vous "bindez" lItemSource dune ListBox une liste dobjets, par exemple une liste de lms, chaque item gnr comme enfant de cette ListBox par le DataBinding possdera un DataContext rfrence du Film ayant servi de source sa gnration. Pour simplier, si nous lions par DataBinding la CollectionDeFilms une ListBox :
Une ListBox (XAML)
<UserControl x:Class="Filmothque.Page" ()> <Grid x:Name="LayoutRoot" Background="White"> <ListBox Name="UneListBox"/> </Grid> </UserControl>

Une ListBox (C#)


(using ...) namespace Filmothque { public partial class Page : UserControl { public Page() { InitializeComponent(); UneListBox.ItemsSource = CollectionDeFilms.Films;

216

Le DataBinding en dtails

} } } c Fig. 5.1 : Une ListBox lie la Collection de lms

Chaque lment Filmotheque.Film de la ListBox contient un DataContext pointant vers le lm quil reprsente. Dans le code de la logique applicative, il est alors possible de rcuprer ce lm partir de llment XAML. Qui plus est, un DataContext peut tre rempli par le dveloppeur sur dautres lments quun lment auto-gnr par DataBinding. Par exemple, avec cette interface :
Interface recevant un DataContext cod en dure (Xaml)
<UserControl x:Class="Filmotheque.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="400" Height="300"> <StackPanel x:Name="LayoutRoot" Background="White"> <StackPanel Orientation="Horizontal" Margin="4"> <TextBlock Text="Titre:" Margin="5"/> <TextBlock Text="{Binding Path=Titre}" Margin="5"/> </StackPanel> <StackPanel Orientation="Horizontal" Margin="4"> <TextBlock Text="Ralisateur:" Margin="5"/> <TextBlock Text="{Binding Path=Ralisateur}" Margin="5"/> </StackPanel> <StackPanel Orientation="Horizontal" Margin="4"> <TextBlock Text="Etoiles:" Margin="5"/> <TextBlock Text="{Binding Path=NombreDEtoiles} Margin="5"/> </StackPanel> </StackPanel> </UserControl>

217

Concepts avancs

La ligne de code LayoutRoot.DataContext = CollectionDeFilms.Films[0]; donnera le rsultat suivant :


c Fig. 5.2 : Interface recevant un DataContext en dur

Cest exactement le mme procd qui est utilis par la plateforme lorsquelle gnre les items dune ListBox partir de DataTemplate. Pour chaque objet prsent dans la collection de donnes en ItemSource, la plateforme ajoute aux enfants de la ListBox une copie du DataTemplate dont le DataContext est lobjet courant.

Interaction avec lutilisateur


Comme il est crit dans lintroduction de ce chapitre, le DataBinding ne sert pas seulement afficher des donnes mais aussi les modier. Si nous ajoutons linterface prcdente quelques TextBoxs lies par binding aux mmes proprits du lm, et pour peu que la dclaration du binding le permettre, le fait de modier le texte contenu dans une TextBox changera directement les donnes en mmoire vive. Pour permettre ce tour de magie, il faut spcier la dclaration du binding son attribut Mode. Le Mode peut soit tre :
j j

OneWay ; ce Mode est destin uniquement laffichage de donnes. TwoWay ; ce Mode sert aussi bien laffichage et la modication de donnes.

Le code XAML est-il le seul code modier pour ajouter cette fonctionnalit ? On aimerait bien mais en fait, si modier uniquement le code XAML permet dajouter cette fonctionnalit, malheureusement, les modications apportes aux donnes ne seront pas propages nouveau vers linterface lors dune modication. Dans un cas tel que celui-ci avec des lments daffichage de donnes, linterface ne sera pas mise jour. Cela tant, ce cas reste isol. Usuellement, il est inutile dafficher des donnes dans deux lments dinterface diffrents. Quoi que Pour pallier ce problme, il faut attraper un vnement tel que LostFocus dans le code de la logique applicative et forcer la mise jour du DataContext.

218

Le DataBinding en dtails

Cest ce que fait le code suivant :


DataBinding Modes + Mise jour force (XAML)
<UserControl x:Class="Filmotheque.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="400" Height="300"> <StackPanel x:Name="LayoutRoot" Background="White"> <StackPanel Orientation="Horizontal" Margin="4"> <TextBlock Text="Titre:" Margin="5"/> <TextBlock Text="{Binding Path=Titre}" Margin="5"/> <TextBox Text="{Binding Path=Titre, Mode=OneWay}" Margin="5" LostFocus="Input_LostFocus"/> </StackPanel> <StackPanel Orientation="Horizontal" Margin="4"> <TextBlock Text="Ralisateur:" Margin="5"/> <TextBlock Text="{Binding Path=Ralisateur}" Margin="5"/> <TextBox Text="{Binding Path=Ralisateur, Mode=TwoWay}" Margin="5" LostFocus="Input_LostFocus"/> </StackPanel> <StackPanel Orientation="Horizontal" Margin="4"> <TextBlock Text="Etoiles:" Margin="5"/> <TextBlock Text="{Binding Path=NombreDEtoiles}" Margin="5"/> <Slider Value="{Binding Path=NombreDEtoiles, Mode=TwoWay}" Minimum="0" Maximum="5" Width="100" Margin="5" LostFocus="Input_LostFocus"/> </StackPanel> </StackPanel> </UserControl>

DataBinding Modes + Mise jour force (C#)


using (...); namespace Filmotheque { public partial class Page : UserControl { private bool isIntialized = false; public Page() { InitializeComponent();

219

Concepts avancs

isIntialized = true; LayoutRoot.DataContext = CollectionDeFilms.Films[0]; } private void Input_LostFocus(object sender, RoutedEventArgs e) { ResetDataContext(); } private void ResetDataContext() { if (!isIntialized) return; LayoutRoot.DataContext = null; LayoutRoot.DataContext = CollectionDeFilms.Films[0]; } } }

5.2 Les Styles et ControlTemplates


Style
Lors de la cration dune interface XAML, de nombreux attributs vous aident congurer laffichage des diffrents lments dinterface. Quil sagisse des attributs Background, Foreground, StorkeThickness, Fill ou dautres attributs, ils se retrouvent spontanment dans chacun de vos lments dinterface. Dans le but dobtenir une interface cohrente, vous serez amen copier ces lments dits de style dun contrle utilisateur lautre. Pour viter une prolifration ingrable de code similaire travers votre application, lutilisation de styles simpose. Un style est un ensemble dattributs prdnis applicables un type dlment pour en congurer le visuel. Considrons un code lourd tel que celui-ci :
Code lourd
<UserControl x:Class="Filmotheque.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="100" Height="80"> <StackPanel x:Name="LayoutRoot" Background="White"> <TextBlock Foreground="Black" FontSize="15" FontFamily="Arial"

220

Les Styles et ControlTemplates

FontWeight="Bold" HorizontalAlignment="Center" Text="TextBlock1"/> <TextBlock Foreground="Black" FontSize="15" FontFamily="Arial" FontWeight="Bold" HorizontalAlignment="Center" Text="TextBlock2"/> <TextBlock Foreground="Black" FontSize="15" FontFamily="Arial" FontWeight="Bold" HorizontalAlignment="Center" Text="TextBlock3"/> <TextBlock Foreground="Black" FontSize="15" FontFamily="Arial" FontWeight="Bold" HorizontalAlignment="Center" Text="TextBlock4"/> </StackPanel> </UserControl>

Remplaons la rptition dattributs de style par un lment Style unique :


Code allg par Style
<UserControl x:Class="Filmotheque.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="100" Height="80"> <StackPanel x:Name="LayoutRoot" Background="White"> <StackPanel.Resources> <Style x:Key="BoldTextBlockStyle" TargetType="TextBlock"> <Setter Property="Foreground" Value="Black"/> <Setter Property="FontSize" Value="15"/> <Setter Property="FontFamily" Value="Arial"/> <Setter Property="FontWeight" Value="Bold"/> <Setter Property="HorizontalAlignment" Value="Center"/> </Style> </StackPanel.Resources> <TextBlock Style="{StaticResource Text="TextBlock1"/> <TextBlock Style="{StaticResource Text="TextBlock2"/> <TextBlock Style="{StaticResource Text="TextBlock3"/> <TextBlock Style="{StaticResource Text="TextBlock4"/> </StackPanel> </UserControl> BoldTextBlockStyle}" BoldTextBlockStyle}" BoldTextBlockStyle}" BoldTextBlockStyle}"

221

Concepts avancs

Le code devient bien plus lisible et on peut en assurer facilement la maintenance. Changer globalement laspect des TextBlock du Style BoldTextBlock se fait en une modication au lieu de quatre. Le rsultat, quant lui, reste le mme :
c Fig. 5.3 : TextBlock avec Style

Un style possde comme attributs une x:Key le reprsentant et un TargetType. Le TargetType est le type dlment XAML auquel le style peut tre appliqu. Laisser vide cette dernire proprit vous permettra dappliquer ce style nimporte quel lment XAML. En contrepartie, il est dangereux de sy rsoudre par simplicit vu que certains attributs (tels que Foreground) ne sont pas partags par tous les lments XAML. Les lments enfants des styles sont les setters. Un setter congure lattribut du nom de Property avec la valeur Value.

ControlTemplate
Un ControlTemplate est une sorte de style qui, au lieu de congurer certains attributs dun lment dinterface, remplace compltement son affichage par un arbre XAML :
Exemple de ControlTemplate
<UserControl x:Class="Filmotheque.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="150" Height="150"> <StackPanel x:Name="LayoutRoot" Background="White"> <StackPanel.Resources> <Style x:Key="BoldTextBlockStyle" TargetType="TextBlock"> <Setter Property="Foreground" Value="Black"/> <Setter Property="FontSize" Value="15"/> <Setter Property="FontFamily" Value="Arial"/> <Setter Property="FontWeight" Value="Bold"/> <Setter Property="HorizontalAlignment" Value="Center"/> </Style> <ControlTemplate x:Key="ActionControlTemplate" TargetType="Button"> <Border Background="Silver"

222

Les Styles et ControlTemplates

BorderThickness="2" BorderBrush="Blue" CornerRadius="0,0,15,0" Margin="5"> <StackPanel Orientation="Vertical" Margin="5"> <TextBlock Style="{StaticResource BoldTextBlockStyle}" Text="{TemplateBinding Content}" HorizontalAlignment="Left"/> <Button Click="{TemplateBinding Click}"> <TextBlock Style="{StaticResource BoldTextBlockStyle}" HorizontalAlignment="Right" Text="Do it!"/> </Button> </StackPanel> </Border> </ControlTemplate> </StackPanel.Resources> <Button Template="{StaticResource ActionControlTemplate}" Content="Une Action"/> <Button Template="{StaticResource ActionControlTemplate}" Content="Autre Action"/> </StackPanel> </UserControl> c Fig. 5.4 : Exemple de ControlTemplate

trangement, assigner un ControlTemplate un lment XAML ne se fait pas par lattribut ControlTemplate mais via lattribut Template. lintrieur mme du ControlTemplate, un nouveau type de binding montre son nez : le TemplateBinding. Un TemplateBinding permet un ControlTemplate de rcuprer la valeur dun des attributs de llment quil utilise.

223

Concepts avancs

Ainsi en crivant Text="{TemplateBinding Content}", nous allons rechercher le Content des deux boutons qui utilisent ActionControlTemplate. Ceci est dangereux. En effet, nous avons assign par TemplateBinding lattribut Text dune TextBox une valeur qui peut ne pas tre du texte. Rappelons-nous quun Button peut contenir nimporte quel autre lment XAML, ce qui nest pas le cas de lattribut Text, qui lui, accepte uniquement du texte. Pour pallier ce risque, il est prfrable dutiliser un ContentPresenter.Un ContentPresenter est un lment XAML qui possde la capacit dafficher son contenu. Modions le code du ControlTemplate :
ControlTemplate avec ContentTemplate
<UserControl x:Class="Filmotheque.Page" (...) <ControlTemplate x:Key="ActionControlTemplate" TargetType="Button"> <Border Background="Silver" BorderThickness="2" BorderBrush="Blue" CornerRadius="0,0,15,0" Margin="5"> <StackPanel Orientation="Vertical" Margin="5"> <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Left"/> <Button Click="{TemplateBinding Click}"> <TextBlock Style="{StaticResource BoldTextBlockStyle}" HorizontalAlignment="Right" Text="Do it!"/> </Button> </StackPanel> </Border> </ControlTemplate> </StackPanel.Resources> <Button Template="{StaticResource ActionControlTemplate}" Content="Une Action"/> <Button Template="{StaticResource ActionControlTemplate}"> <StackPanel>

224

Crer un UserControl

<TextBlock Text="Ecrire un livre"/> <TextBlock Text="Publier un livre"/> </StackPanel> </Button> </StackPanel> </UserControl> c Fig. 5.5 : ControlTemplate avec ContentTemplate

Dans ce nouvel exemple, que le contenu du bouton soit un simple texte ou un arbre XAML complexe, le rsultat est le mme.

5.3 Crer un UserControl


Toutes ces congurations nous conduisent vers le concept dUserControl. Un UserControl, ou contrle utilisateur en franais, est un lment dinterface XAML dni par le dveloppeur. Il est crit laide dun chier XAML spar du corps de lapplication mais aussi dun chier de code applicatif personnel. En effet, un contrle utilisateur nest plus seulement un lment de conguration visuelle, mais aussi un lment englobant une part de logique interne. Pour crer un UserControl, il faut :
j j j

ajouter ses codes XAML et C# la solution Silverlight ; dnir linterface XAML ; crire la logique applicative.

Pour utiliser un UserControl, il faut :


j j

Si le UserControl est dni dans une autre assembly, sassurer quelle a t compile pour Silverlight et en ajouter la rfrence au projet Silverlight. Ajouter lapplication lespace de noms (namespace) contenant lUserControl.

225

Concepts avancs

UserControl ClickMe
Pour apprhender facilement ce concept de contrle utilisateur, nous allons en crire un basique. Cet UserControl contiendra un bouton et changera le contenu de ce bouton lorsquon cliquera dessus. Voici linterface de ClickMe :
ClickMe.xaml
<UserControl x:Class="Filmotheque.ClickMe" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Grid x:Name="LayoutRoot" Background="White"> <Button Name="ClickMeButton" Content="Click Me!" Click="Button_Click"/> </Grid> </UserControl>

Voici le code de la logique applicative :


ClickMe.cs
using using using using using using using using using using using System; System.Collections.Generic; System.Linq; System.Net; System.Windows; System.Windows.Controls; System.Windows.Documents; System.Windows.Input; System.Windows.Media; System.Windows.Media.Animation; System.Windows.Shapes;

namespace Filmotheque { public partial class ClickMe : UserControl { public ClickMe() { InitializeComponent(); } private void Button_Click(object sender, RoutedEventArgs e)

226

Crer un UserControl

{ ClickMeButton.Content = "Merci"; } } }

Utilisation de lUserControl ClickMe :


Utilisation du UserControle ClickMe
<UserControl x:Class="Filmotheque.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:MyApp="clr-namespace:Filmotheque" Width="150" Height="150"> <StackPanel x:Name="LayoutRoot" Background="White"> <MyApp:ClickMe Margin="5"/> <MyApp:ClickMe Margin="5"/> <MyApp:ClickMe Margin="5"/> <MyApp:ClickMe Margin="5"/> </StackPanel> </UserControl> c Fig. 5.6 : UserControle ClickMe sous diffrents tats

UserControl Ranking
Dans loptique de lapplication de gestion de lms, un UserControl permettant dattribuer un nombre dtoiles un lm de manire visuel peut avoir son importance. Le rsultat nal auquel nous aimerions arriver est le suivant :
c Fig. 5.7 : Ranking UserControl

227

Concepts avancs

Il doit tre possible dcrire le code suivant :


Objectif code XAML Ranking UserControl
<UserControl x:Class="Filmotheque.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:MyApp="clr-namespace:Filmotheque" Width="400" Height="300"> <StackPanel x:Name="LayoutRoot" Background="White"> <MyApp:Ranking NombreDEtoile="3"/> <MyApp:Ranking NombreDEtoile="{Binding Path=NomberDEtoile, Mode=TwoWay}"/> </StackPanel> </UserControl>

Un point reste voir avant darriver ce rsultat : Comment ajouter un UserControl une proprit pouvant servir dattributs dans le code XAML.

Les DependencyProperties
Une DependencyProperty est une proprit dclare dans le code applicatif dun UserControl grce la mthode Register de la classe DependencyProperty. Cest une proprit qui au lieu dtre enregistre dans une variable prive du code applicatif, est enregistre par le Framework lui-mme dune manire qui importe peu. Quoi quil en soit, seuls les DependencyProperties sont stables lorsque vous dsirez utiliser un attribut dans le code XAML. Lutilisation dune proprit publique du code applicatif dans ce but peut avoir des effets malencontreux et imprvisibles. Lemploi dune DependencyProperty la place dune proprit publique active la gestion des Animations, des Styles, des Templates et du binding sur cette proprit. Dclaration dune DependencyProperty :
public int MyProperty { get { return (int)GetValue(MyPropertyProperty); } set { SetValue(MyPropertyProperty, value); } }

228

Crer un UserControl

Dclaration dune DependencyProperty


public static readonly DependencyProperty MyPropertyProperty = DependencyProperty.Register("MyProperty", typeof(int), typeof(ownerclass), new PropertyMetadata(0));

La fonction DependencyProperty.Register demande 4 paramtres :


j j j j

le nom de la proprit ; son type ; le type de sa classe mre, la classe qui te cette DependencyProperty (gnralement la classe dans laquelle cette proprit est dclare) ; une instance de la classe PropertyMetadata spciant la valeur initiale de la proprit.

Dans ce cas, nous dclarons donc :


j j j j

une proprit du nom MyProperty ; de type nombre entier (int) ; dont la classe hte est ownerclass ; de valeur initiale 0.

Cration de lUserControl Ranking


Rappel du cahier des charges : Crer un UserControl affichant de 1 5 toiles selon une proprit NombreDEtoiles. Pour ce faire, nous allons crer deux contrles utilisateur :
j

Le premier du nom de Star tant une toile unique, capable de varier de couleur (jaune ou gris) quand on clique dessus ou lors de lappel dune de ses fonctions publiques. Le deuxime du nom de Ranking sera un conteneur de cinq UserControl Star, coordonnant leurs travaux.

Star
Pour crer lUserControl Star, nous allons partir dune CheckBox. En effet, comme nous lavons vu au chapitre 2, Le langage XAML, une CheckBox possde un attribut IsChecked deux tats. Cet attribut nous sera utile pour savoir si ltoile est jaune (IsChecked=True) ou si ltoile est grise (IsChecked=False).

229

Concepts avancs

Nous allons ensuite en rednir le ControlTemplate pour lui donner lapparence dune toile. Dans le code suivant, vous dcouvrirez lutilisation de llment gomtrique Path. Cet lment prend comme valeur de lattribut Data une srie de points reprsents par des coordonnes gomtriques. Lattribut Fill de ce Path est li par TemplateBinding au Background de la CheckBox. Cest en faisant varier ce Background de YellowStarBrush GreyStarBrush dans le code applicatif que nous changerons le visuel de ltoile :
Star.xaml
<UserControl x:Class="Filmotheque.Star" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Grid x:Name="LayoutRoot" Background="Transparent"> <Grid.Resources> <SolidColorBrush x:Key="YellowStarBrush" Color="#FFFF00"/> <SolidColorBrush x:Key="GreyStarBrush" Color="#C0C0C0"/> <Style x:Key="EmptyStarStyle" TargetType="CheckBox"> <Setter Property="Height" Value="40"/> <Setter Property="Width" Value="40"/> <Setter Property="Margin" Value="2"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate x:Name="EmptyStarTemplate"> <Canvas> <Canvas Canvas.Left="5" Canvas.Top="15"> <Path Stroke="#000080" Fill="{TemplateBinding Background}" MouseLeftButtonDown="Path_MouseLeftButtonDown" MouseEnter="Path_MouseEnter" MouseLeave="Path_MouseLeave" StrokeThickness="3" StrokeStartLineCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Round" Data="M 0,0 l 10,0 l 5,-10 l 5,10 l 10,0 l -7,10 l 2,10 l -10,-5 l -10,5 l 2,-10 Z"/> </Canvas> </Canvas> </ControlTemplate>

230

Crer un UserControl

</Setter.Value> </Setter> </Style> </Grid.Resources> <CheckBox Name="Star1" IsChecked="True" Style="{StaticResource EmptyStarStyle}" Background="{StaticResource YellowStarBrush}"/> </Grid> </UserControl>

Trois vnements sont utiliss dans ce ControlTemplate :

c Fig. 5.8 : Etoile solitaire

MouseLeftButtonDown lorsque lutilisateur cliquera sur ltoile, son attribut IsChecked sera invers. j MouseEnter et MouseLeave lorsque la souris de lutilisateur se trouve au-dessus de ltoile, nous en changerons le Background en Orange.
j

Star.cs
using using using using using using using using using using using System; System.Collections.Generic; System.Linq; System.Net; System.Windows; System.Windows.Controls; System.Windows.Documents; System.Windows.Input; System.Windows.Media; System.Windows.Media.Animation; System.Windows.Shapes;

namespace Filmotheque { public partial class Star : UserControl { public event EventHandler OnColorChanged; public bool? IsChecked { get { return (bool?)GetValue(IsCheckedProperty); }

231

Concepts avancs

set { SetValue(IsCheckedProperty, value); Star1.IsChecked = value; SetBackground(); } } public static readonly DependencyProperty IsCheckedProperty = DependencyProperty.Register( "IsChecked", typeof(bool?), typeof(Star), new PropertyMetadata(true));

public Star() { InitializeComponent(); SetBackground(); } private void Path_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { Star1.IsChecked = !Star1.IsChecked; SetBackground(); if (OnColorChanged != null) OnColorChanged(this,EventArgs.Empty); } private void SetBackground() { if (Star1.IsChecked.HasValue && Star1.IsChecked.Value) Star1.Background = (SolidColorBrush) LayoutRoot.Resources["YellowStarBrush"]; else Star1.Background = (SolidColorBrush) LayoutRoot.Resources["GreyStarBrush"]; } #region MouseOverManagement private Brush SolideStateBackground; private void Path_MouseEnter(object sender, MouseEventArgs e) { SolideStateBackground = Star1.Background; Star1.Background = new SolidColorBrush(Colors.Orange);

232

Crer un UserControl

} private void Path_MouseLeave(object sender, MouseEventArgs e) { Star1.Background = SolideStateBackground; } #endregion MouseOverManagement } }

Un point est mettre en vidence dans ce code applicatif : lvnement OnColorChanged qui prviendra lUserControl Ranking que lutilisateur a cliqu sur ltoile.

Ranking
Interface de lUserControl Ranking :
Ranking.xaml
<UserControl x:Class="Filmotheque.Ranking" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:MyApp="clr-namespace:Filmotheque" Width="Auto" Height="Auto" Margin="2" > <Grid x:Name="LayoutRoot" Background="White"> <Border HorizontalAlignment="Center" VerticalAlignment="Center" Background="White" CornerRadius="5" BorderBrush="#000080" BorderThickness="4"> <StackPanel Name="RankingPanel" Orientation="Horizontal"> <MyApp:Star Name="Star1"/> <MyApp:Star Name="Star2"/> <MyApp:Star Name="Star3"/> <MyApp:Star Name="Star4"/> <MyApp:Star Name="Star5"/> </StackPanel> </Border> </Grid> </UserControl>

Comme prvu, du ct de linterface du contrle utilisateur Ranking, il sagit seulement dune collection de contrle utilisateur Star.

233

Concepts avancs

c Fig. 5.9 : Ranking

On comprend ici lutilit davoir cr un contrle utilisateur pour les toiles ; il est devenu trs ais de faire varier le nombre dtoiles quun Ranking possde. Qui plus est, pour aller plus loin, il est possible de faire de ce nombre dtoiles maximal une DependencyProperty congurable. Le code applicatif de Ranking va devoir rester lcoute des clics de lutilisateur sur chaque toile et stocker en mmoire le nombre dtoiles qui lui est attribu. En effet, lorsque lutilisateur clique sur ltoile 3, toutes les toiles prcdentes doivent passer ltat jaune et inversement, toutes les toiles suivantes doivent passer ltat gris.
Ranking.cs
using using using using using using using using using using using System; System.Collections.Generic; System.Linq; System.Net; System.Windows; System.Windows.Controls; System.Windows.Documents; System.Windows.Input; System.Windows.Media; System.Windows.Media.Animation; System.Windows.Shapes;

namespace Filmotheque { public partial class Ranking : UserControl { public int NombreDEtoiles { get { return (int)GetValue(NombreDEtoilesProperty); } set { SetValue(NombreDEtoilesProperty, value); SetRanking(value); } } public static readonly DependencyProperty NombreDEtoilesProperty =

234

Crer un UserControl

DependencyProperty.Register("NombreDEtoiles", typeof(int), typeof(Ranking), new PropertyMetadata(0)); public Ranking() { InitializeComponent(); foreach(Star star in RankingPanel.Children) star.OnColorChanged += new EventHandler(star_OnColorChanged); } void star_OnColorChanged(object sender, EventArgs e) { Star star = (sender as Star); int Position = int.Parse(star.Name.Replace("Star", "")); SetRanking(Position); } public void SetRanking(int NombreDEtoiles) { for (int i = 1; i <= 5; i++) { Star star = (RankingPanel.FindName("Star" + i) as Star); star.IsChecked = (i <= NombreDEtoiles); } } } }

Intgration du contrle utilisateur Ranking dans une application Silverlight


Il suffit de reprendre le code tudi il y a quelque pages dans les spcications de lUserControl Ranking et dy ajouter un DataContext en code applicatif pour vrier quil fonctionne correctement :
Objectif code XAML Ranking UserControl
<UserControl x:Class="Filmotheque.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

235

Concepts avancs

xmlns:MyApp="clr-namespace:Filmotheque" Width="400" Height="300"> <StackPanel x:Name="LayoutRoot" Background="White"> <MyApp:Ranking NombreDEtoile="3"/> <MyApp:Ranking NombreDEtoile="{Binding Path=NomberDEtoile, Mode=TwoWay}"/> </StackPanel> </UserControl>

Code applicatif
using using using using using using using using using using using System; System.Collections.Generic; System.Linq; System.Net; System.Windows; System.Windows.Controls; System.Windows.Documents; System.Windows.Input; System.Windows.Media; System.Windows.Media.Animation; System.Windows.Shapes;

namespace Filmotheque { public partial class Page : UserControl { public Page() { InitializeComponent(); LayoutRoot.DataContext = CollectionDeFilms.Films[0]; } } }

Le rsultat est la hauteur de nos esprances :

c Fig. 5.10 : Ranking en action

236

Crer un UserControl

c Fig. 5.11 : Ranking en action

MediaElement
Dans une optique totalement diffrente, nous allons maintenant nous pencher sur un contrle Silverlight des plus puissants : le contrle MediaElement. Le contrle MediaElement permet dafficher et dinteragir avec une vido lintrieur dune application Silverlight.
Attribut MediaElement.Source en XAML bug
Lorsque vous ajoutez un contrle MediaElement votre application Silverlight, nen congurez pas la source partir du code XAML, vous recevrez dans ce cas une erreur de chargement de la vido (Erreur 4001). Ceci est un bogue ouvert chez Microsoft mais restons calme, ce bogue nest pas bloquant, il suffit de congurer la source des MediaElement partir du code applicatif.

Interface dun exemple dutilisation du contrle MediaElement :


Exemple de MediaElement
<UserControl x:Class="Filmotheque.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:MyApp="clr-namespace:Filmotheque" Width="430" Height="300"> <StackPanel x:Name="LayoutRoot" Background="Black"> <StackPanel Orientation="Horizontal"> <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> <Button Content="Play" Margin="5" Click="Play_Click"/> <Button Content="Pause" Margin="5" Click="Pause_Click"/> <Button Content="Stop" Margin="5" Click="Stop_Click"/>

237

Concepts avancs

<TextBlock Foreground="White" VerticalAlignment="Center" Margin="5" >Volume</TextBlock> <Slider Name="VolumeSlider" VerticalAlignment="Center" Minimum="0" Maximum="1" Value="0.5" Width="70" ValueChanged="VolumeSlider_ValueChanged"/> <ToggleButton Name="MuteToggleButton" Content="Mute" Margin="5" IsChecked="False" Checked="Mute" Unchecked="UnMute"/> </StackPanel> <Border Background="Black" BorderBrush="WhiteSmoke" BorderThickness="3" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5" CornerRadius="5"> <MediaElement Name="myMediaElement" Width="320" Height="240" Margin="5" Stretch="Fill" AutoPlay="False" MediaFailed="MediaElement_MediaFailed"/> </Border> </StackPanel> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <TextBlock Foreground="White" Margin="5" Grid.Column="0" VerticalAlignment="Center">Seek To</TextBlock> <Slider Name="TimeLineSlider" Margin="5" Minimum="0" Grid.Column="1"/> <TextBlock Name="TimeLineTextBlock" Grid.Column="2"

238

Crer un UserControl

Text="00:00:00/00:00:00" Foreground="White" Margin="5"/> </Grid> </StackPanel> </UserControl> c Fig. 5.12 : Exemple de MediaElement

Dans cette application Silverlight, vous retrouvez un MediaElement et quelques autres contrles destins interagir avec lui. Les diffrents contrles ajouts parlent deux-mmes, le bouton Play sert dmarrer la vido, le bouton Pause larrter temporairement, etc. Le code applicatif, quant lui, cache quelques subtilits :
Code applicatif de lexemple de MediaElement
using using using using using using using using using using using using using System; System.Collections.Generic; System.Linq; System.Net; System.Windows; System.Windows.Controls; System.Windows.Documents; System.Windows.Input; System.Windows.Media; System.Windows.Media.Animation; System.Windows.Shapes; System.Windows.Data; System.Threading;

namespace Filmotheque {

239

Concepts avancs

public partial class Page : UserControl { public Page() { InitializeComponent(); myMediaElement.Source = new Uri(@"media/Lake.wmv", UriKind.Relative); } private void MediaElement_MediaFailed(object sender, ExceptionRoutedEventArgs e) { } private void Play_Click(object sender, RoutedEventArgs e) { TimeLineSlider.Maximum = myMediaElement.NaturalDuration.TimeSpan.TotalSeconds; TimeLineSlider.Value = myMediaElement.Position.TotalSeconds;

myMediaElement.Play(); Timer T = new Timer(new TimerCallback(delegate { Dispatcher.BeginInvoke(new Action(delegate { TimeLineSlider.SetValue(Slider.ValueProperty, myMediaElement.Position.TotalSeconds); TimeLineTextBlock.Text = myMediaElement.Position.Hours + ":" + myMediaElement.Position.Minutes + ":" + myMediaElement.Position.Seconds + "/" + myMediaElement.NaturalDuration.TimeSpan.Hours + ":" + myMediaElement.NaturalDuration.TimeSpan.Minutes + ":" + myMediaElement.NaturalDuration.TimeSpan.Seconds; })); })); T.Change(0, 1000); }

240

Crer un UserControl

private void Pause_Click(object sender, RoutedEventArgs e) { myMediaElement.Pause(); } private void Stop_Click(object sender, RoutedEventArgs e) { myMediaElement.Stop(); } private void VolumeSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) { if (VolumeSlider != null && myMediaElement != null) myMediaElement.Volume = VolumeSlider.Value; } private void Mute(object sender, RoutedEventArgs e) { myMediaElement.IsMuted = true; } private void UnMute(object sender, RoutedEventArgs e) { myMediaElement.IsMuted = false; }

} }

Pour pallier le bogue relatif lattribut Source des MediaElement, cest dans ce code applicatif que lon se doit de lassigner.
c Fig. 5.13 : Exemple de MediaElement en fonctionnement

241

Concepts avancs

Pour faire varier lattribut Valeur du Silder TimeLineSlider, nous avons utilis un objet de la plateforme .Net du nom de Dispatcher.

Dispatcher
Dans une application Silverlight, comme dans une application WPF, linterface est proprit dun unique thread. Cest dans ce thread que sexcutent les diffrents vnements. Cependant, il est parfois ncessaire dattaquer linterface partir dun autre thread. Cest impossible. Le Dispatcher est un objet grant lordre dappel des fonctions du thread de linterface. Tout ce quil est possible de faire partir dun autre thread est de demander au Dispatcher de mettre en queue lappel dune fonction. Quand le Dispatcher en trouvera le temps, il lexcutera. Cette demande se fait partir de la mthode BeginInvoke du Dispatcher :
Utilisation du Dispatcher
Thread autre que le thread interface { /* interaction code interface impossible */ Dispatcher.BeginInvoke(new Action(delegate { /* interaction code interface possible */ })); }

Passer en mode Plein cran


Une fonctionnalit toujours apprcie par un utilisateur lorsquil regarde une vido est la possibilit de passer en mode Plein cran. Silverlight permet cette fonctionnalit grce la proprit bien cache : App.Current .Host.Content.IsFullScreen. Malheureusement dans notre cas, en assignant cette proprit True, cest lintgralit de lapplication Silverlight qui passe en mode Plein cran, alors que nous voudrions voir uniquement la vido. Pour complter cette fonctionnalit, il faut rorganiser la structure de lapplication.

242

Crer un UserControl

Lobjet App.Current.Host.Content contient deux autres proprits qui vont nous servir :
ActualHeight est la hauteur de lcran de lutilisateur. j ActuelWith est la largeur de lcran de lutilisateur.
j

Cet objet contient aussi un vnement : FullScreenChanged sur lequel nous ajouterons une mthode rorganisant la structure de lapplication. Ajout dun bouton FullScreen linterface et modication du code XAML :
MediaElement FullScreen (Xaml)
<UserControl x:Class="Filmotheque.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:MyApp="clr-namespace:Filmotheque" Width="Auto" Height="Auto"> <StackPanel x:Name="LayoutRoot" Background="Black"> <StackPanel Orientation="Horizontal"> <StackPanel HorizontalAlignment="Center" Name="ButtonStackPanel" VerticalAlignment="Center"> <Button <Button <Button <Button Content="Play" Margin="5" Click="Play_Click"/> Content="Pause" Margin="5" Click="Pause_Click"/> Content="Stop" Margin="5" Click="Stop_Click"/> Content="FullScreen" Margin="5" Click="FullScreen_Click"/>

<TextBlock Foreground="White" VerticalAlignment="Center" Margin="5" >Volume</TextBlock> <Slider Name="VolumeSlider" VerticalAlignment="Center" Minimum="0" Maximum="1" Value="0.5" Width="70" ValueChanged="VolumeSlider_ValueChanged"/> <ToggleButton Name="MuteToggleButton" Content="Mute" Margin="5" IsChecked="False" Checked="Mute" Unchecked="UnMute"/> </StackPanel> <Border Name="EcranBorder" Background="Black" BorderBrush="WhiteSmoke" BorderThickness="3"

243

Concepts avancs

HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5" Width="330" Height="250" CornerRadius="5"> <MediaElement Name="myMediaElement" Margin="5" Stretch="Fill" AutoPlay="False" MediaFailed="MediaElement_MediaFailed"/> </Border> </StackPanel> <Grid Name="SliderGrid" Width="400" HorizontalAlignment="Left"> </StackPanel> </UserControl>

Lors de lvnement Click du bouton FullScreen, nous allons :


j

Assigner les attributs Visible des lments ButtonStackPanel et SliderGrid Collapsed. La valeur Collapsed de cet attribut signie que les lments ne doivent ni tre affichs sur linterface, ni occuper la moindre place rsiduelle dans linterface. Redimensionner le Border EcranBorder pour quil occupe toute la place disponible sur lcran de lutilisateur.

Modication du code applicatif :


MediaElement FullScreen
() public Page() { InitializeComponent(); myMediaElement.Source = new Uri(@"media/Lake.wmv", UriKind.Relative); App.Current.Host.Content.FullScreenChanged += new EventHandler(Content_FullScreenChanged); } void Content_FullScreenChanged(object sender, EventArgs e) { if (!App.Current.Host.Content.IsFullScreen)

244

Crer un UserControl

{ ButtonStackPanel.Visibility = Visibility.Visible; SliderGrid.Visibility = Visibility.Visible; EcranBorder.SetValue(Border.HeightProperty, (double)250); EcranBorder.SetValue(Border.WidthProperty, (double)330); } else { ButtonStackPanel.Visibility = Visibility.Collapsed; SliderGrid.Visibility = Visibility.Collapsed; EcranBorder.SetValue(Border.HeightProperty, App.Current.Host.Content.ActualHeight - 10); EcranBorder.SetValue(Border.WidthProperty, App.Current.Host.Content.ActualWidth 10); } } private void FullScreen_Click(object sender, RoutedEventArgs e) { App.Current.Host.Content.IsFullScreen = true; } c Fig. 5.14 : MediaElement modi pour supporter le FullScreen

245

Concepts avancs

c Fig. 5.15 : MediaElement en mode FullScreen

5.4 Les contrles de la librairie System.Windows.Controls


En plus des contrles utilisateur Silverlight de base, la plateforme .Net permet lutilisation de 6 contrles utilisateur supplmentaires. Cinq de ces contrles sont prsents dans la bibliothque System.Windows.Controls. Pour utiliser cette librairie, vous devez lajouter en rfrence dans votre projet Silverlight : Cliquez du bouton droit sur Reference dans lExplorateur de solution. 2 Slectionnez laction Ajouter une rfrence.
1

246

Les contrles de la librairie System.Windows.Controls

c Fig. 5.16 : Add Reference

Dans la bote de dialogue Ajouter une rfrence, slectionnez longlet .Net. 4 Slectionnez System.Windows.Controls.
3 c Fig. 5.17 : Bote de dialogue Ajouter une rfrence

Cliquez sur OK

Calendar
Le premier de ces contrles utilisateur est un calendrier :
Exemple de Calendar
<UserControl x:Class="TestWindowsControls.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="clr-namespace:System.Windows.Controls; assembly=System.Windows.Controls"

247

Concepts avancs

xmlns:data="clr-namespace:System.Windows.Controls; assembly=System.Windows.Controls.Data" Width="Auto" Height="Auto"> <Grid x:Name="LayoutRoot" Background="White"> <controls:Calendar Name="calendar"/> </Grid> </UserControl> c Fig. 5.18 : Exemple de Calendar

Les attributs permettant de congurer ce calendrier sont :


DisplayDate spcie la date afficher par dfaut. j DisplayMode peut prendre les valeurs :
j

- Decade affiche 10 annes lutilisateur. - Year affiche 12 mois lutilisateur. - Mounth affiche un mois lutilisateur sous forme de tableau de jours.
j

DisplayDateStart et DisplayDateEnd permettent dafficher seulement une certaine priode de temps sur le calendrier.

Par exemple, pour afficher uniquement les 4 jours de chaque ct du 29 juillet 1985, il faut modier le code applicatif de lapplication :
Exemple de Calendar 2
using using using using using using using using using using using System; System.Collections.Generic; System.Linq; System.Net; System.Windows; System.Windows.Controls; System.Windows.Documents; System.Windows.Input; System.Windows.Media; System.Windows.Media.Animation; System.Windows.Shapes;

248

Les contrles de la librairie System.Windows.Controls

using Filmotheque; namespace TestWindowsControls { public partial class Page : UserControl { public Page() { InitializeComponent(); DateTime Lundi29Juillet85 = new DateTime(1985, 7, 29); calendar.DisplayDate = Lundi29Juillet85; calendar.DisplayDateStart = Lundi29Juillet85.AddDays(-4); calendar.DisplayDateEnd = Lundi29Juillet85.AddDays(4); } } } c Fig. 5.19 : Calendar de 8 jours

DatePicker
Le DatePicker fonctionne majoritairement de la mme faon que le Calendar. Il accepte lui aussi les attributs DisplayDate, DisplayDateStart et DisplayDateEnd. Lattribut DisplayMode y est par contre absent. La vue est xe sur un DisplayMode gal Month. Le DatePicker est un contrle de saisie dinformations, il demande lutilisateur de choisir une date. Lvnement SelectedDateChanged est dclench lorsque lutilisateur a ni sa slection. Cest dans lattribut SelectedDate que le dveloppeur retrouvera le DateTime choisi :
Exemple de DatePicker (Xaml)
<UserControl x:Class="TestWindowsControls.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

249

Concepts avancs

xmlns:controls="clr-namespace:System.Windows.Controls; assembly=System.Windows.Controls" xmlns:data="clr-namespace:System.Windows.Controls; assembly=System.Windows.Controls.Data" Width="Auto" Height="Auto"> <Grid x:Name="LayoutRoot" Background="White"> <controls:DatePicker Name="calendar" HorizontalAlignment="Center" VerticalAlignment="Center" SelectedDateChanged="DatePicker_SelectedDateChanged"/> </Grid> </UserControl> c Fig. 5.20 : Exemple de DatePicker

Exemple de DatePicker (C#)


using using using using using using using using using using using using System; System.Collections.Generic; System.Linq; System.Net; System.Windows; System.Windows.Controls; System.Windows.Documents; System.Windows.Input; System.Windows.Media; System.Windows.Media.Animation; System.Windows.Shapes; Filmotheque;

namespace TestWindowsControls { public partial class Page : UserControl { public Page() { InitializeComponent();

250

Les contrles de la librairie System.Windows.Controls

DateTime Lundi29Juillet85 = new DateTime(1985, 7, 29); calendar.DisplayDate = Lundi29Juillet85; calendar.DisplayDateStart = Lundi29Juillet85.AddDays(-4); calendar.DisplayDateEnd = Lundi29Juillet85.AddDays(4); } private void DatePicker_SelectedDateChanged(object sender, SelectionChangedEventArgs e) { if((sender as DatePicker).SelectedDate.HasValue) DateTime choix = (sender as DatePicker).SelectedDate.Value; } } }

GridSplitter
Un GridSplitter est un contrle utilisateur permettant de redimensionner les tailles des colonnes et des lignes dune grille :
Exemple de GridSplitter
<UserControl x:Class="TestWindowsControls.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="clr-namespace:System.Windows.Controls; assembly=System.Windows.Controls" xmlns:data="clr-namespace:System.Windows.Controls; assembly=System.Windows.Controls.Data" Width="250" Height="250"> <Grid x:Name="LayoutRoot" Background="White"> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Rectangle <Rectangle <Rectangle <Rectangle Grid.Row="0" Grid.Row="0" Grid.Row="1" Grid.Row="1" Grid.Column="0" Grid.Column="1" Grid.Column="0" Grid.Column="1" Fill="Red"/> Fill="Black"/> Fill="Black"/> Fill="Red"/>

251

Concepts avancs

<controls:GridSplitter Grid.Column="0" Grid.RowSpan="2"/> </Grid> </UserControl>

c Fig. 5.21 : Un GridSplitter en action

TabControl et TabItem
Un TabControl est un lment de la famille des Layout, il permet donc de structurer linterface. Ses enfants doivent obligatoirement tre des TabItem. Chaque TabItem est alors class dans le TabControl comme on classerait des feuilles dans un range document. Lattribut Header des TabItem permet de prciser le titre. Seul un TabItem peut tre slectionn (donc affich) simultanment. Lors dun clic sur le header dun TabItem, ce TabItem va directement tre slectionn. Les vnements SelectionChanged du TabControl et IsSelectedChanged des TabItems permettent toutefois dagir sur cette fonctionnalit dans le code applicatif :
Exemple de TabControl
<UserControl x:Class="TestWindowsControls.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="clr-namespace:System.Windows.Controls; assembly=System.Windows.Controls" xmlns:data="clr-namespace:System.Windows.Controls; assembly=System.Windows.Controls.Data" Width="250" Height="250"> <Grid x:Name="LayoutRoot" Background="White"> <controls:TabControl Name="MainTabControl">

252

Le contrle DataGrid

<controls:TabItem Header="StartPage"> <StackPanel> <TextBlock Text="Exemple de TabControl"/> </StackPanel> </controls:TabItem> <controls:TabItem Header="TabItem2" IsSelected="True"> <StackPanel> <Ellipse Fill="Blue" Height="50" Width="70"/> </StackPanel> </controls:TabItem> <controls:TabItem Header="TabItem3"> </controls:TabItem> </controls:TabControl> </Grid> </UserControl>

c Fig. 5.22 : Un TabControl en action

5.5 Le contrle DataGrid


Le DataGrid est le sixime contrle utilisateur supplmentaire par rapport aux contrles de base. Il se trouve dans la librairie System.Windows.Controls.Data. Dans lexemple qui suit, nous allons simplement lier un DataGrid notre collection de lms. Ce DataGrid aura la proprit AutoGeneratedColumn True. Cette proprit stipule la plateforme quelle doit crer une colonne par proprit des Films :
Exemple de DataGrid auto gnr
<UserControl x:Class="TestWindowsControls.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

253

Concepts avancs

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="clr-namespace:System.Windows.Controls; assembly=System.Windows.Controls" xmlns:data="clr-namespace:System.Windows.Controls; assembly=System.Windows.Controls.Data" Width="600" Height="200"> <Grid x:Name="LayoutRoot" Background="White"> <data:DataGrid Name="dataGrid" HeadersVisibility="All" ColumnWidth="150" RowHeight="20" AutoGenerateColumns="True" RowBackground="Beige" IsReadOnly="False" AlternatingRowBackground="LemonChiffon"> </data:DataGrid> </Grid> </UserControl>

Les quelques attributs utiliss ici sont :


j

HeadersVisibility pouvant prendre les valeurs :

- All. Tous les headers sont visible. - Column. Seuls les titres de colonnes sont visibles. - None. Aucun des headers nest visible. - Row. Seul le header de slection de ligne est visible.
j j

RowBackground et AlternatingRowBackground permettent de changer la couleur de

fond des lignes entre chaque item IsReadOnly spcie si les lments de chaque cellule auto gnre sont des lments daffichage ou de saisie dinformations :
Exemple de DataGrid (C#)

using using using using using using using using using

System; System.Collections.Generic; System.Linq; System.Net; System.Windows; System.Windows.Controls; System.Windows.Documents; System.Windows.Input; System.Windows.Media;

254

Le contrle DataGrid

using System.Windows.Media.Animation; using System.Windows.Shapes; using Filmotheque; namespace TestWindowsControls { public partial class Page : UserControl { public Page() { InitializeComponent(); dataGrid.ItemsSource = CollectionDeFilms.Films; } } }

c Fig. 5.23 : DataGrid auto gnre

DataGrid non auto gnr


Lauto gnration ses limites. En effet, ds que nous aurons des donnes plus complexes que des chanes de caractres, des nombres ou des valeurs boolennes, la mthode ToString de ces donnes sera affiche, nous donnant le mme problme quun DataBinding direct sans DataTemplates. Pour crer manuellement des colonnes dans une DataGrid, la librairie Microsoft.Windows .Controls.Data offre 3 UserTemplates :
j j

DataGridTextColumn. Il sagit du type de colonnes les plus communes. Elles utilisent un TextBlock pour afficher des donnes et une TextBox pour les diter. DataGridCheckBoxColumn. Ce type de colonne affiche une CheckBox. Comme son nom lindique, lattribut IsEditable de la DataGrid mre de cette colonne est li lattribut IsEditable de la CheckBox. DataGridTemplateColumn. Il sagit du type de colonne par excellence. Il reprend le principe de DataTemplate et il est donc totalement versatile.

255

Concepts avancs

Utiliser une collection de colonnes


Avant toutes grandes modications, essayons de recrer sans AutoGeneratedColumn le mme rsultat quavec AutoGeneratedColumn :
DataGrid avec collection de colonnes
<UserControl x:Class="TestWindowsControls.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="clr-namespace:System.Windows.Controls; assembly=System.Windows.Controls" xmlns:data="clr-namespace:System.Windows.Controls; assembly=System.Windows.Controls.Data" Width="600" Height="200"> <Grid x:Name="LayoutRoot" Background="White"> <data:DataGrid Name="dataGrid" HeadersVisibility="All" ColumnWidth="150" RowHeight="20" AutoGenerateColumns="False" RowBackground="Beige" IsReadOnly="False" AlternatingRowBackground="LemonChiffon"> <data:DataGrid.Columns> <data:DataGridTextColumn Header="Titre" Binding="{Binding Path=Titre}" /> <data:DataGridTextColumn Header="Ralisateur" Binding="{Binding Path=Ralisateur}" /> <data:DataGridTextColumn Header="Nombre dtoiles" Binding="{Binding Path=NombreDEtoiles}" /> </data:DataGrid.Columns> </data:DataGrid> </Grid> </UserControl>

c Fig. 5.24 : DataGrid avec collection de colonnes

256

Le contrle DataGrid

Remarquez dors et dj la subtile diffrence dans le titre de la colonne reprsentant le nombre dtoiles. Ayant la main sur le contenu de son Header, il nous a t possible de le faire passer de NombreDEtoile Nombre dtoiles.

DataGridCheckBoxColumn et DataGridTemplateColumn
Pour aller plus loin dans les exemples, nous devrons changer de collection de donnes. En effet, une collection de donnes contient uniquement des chanes de caractres et un nombre ne suffit pas exploiter la puissance des DataGridTemplateColumn. Le cas dtude parfait est une liste de projets. Un projet est dni par son nom, sa date de dpart, sa date butoir, sa liste demploys. Un employ est dni par son nom, son prnom, sa date de naissance, sa photo didentit, son adresse de blog et son email. Voici le code des sources de donnes :
Projet.cs
using using using using using using using using using using using System; System.Net; System.Windows; System.Windows.Controls; System.Windows.Documents; System.Windows.Ink; System.Windows.Input; System.Windows.Media; System.Windows.Media.Animation; System.Windows.Shapes; System.Collections.Generic;

namespace TestWindowsControls { public class Projet { private string nom; public string Nom { get { return nom; } set { nom = value; } } private DateTime dpart;

257

Concepts avancs

public DateTime Dpart { get { return dpart; } set { dpart = value; } } private DateTime buttoir; public DateTime Buttoir { get { return buttoir; } set { buttoir = value; } } private List<Employ> quipe; public List<Employ> Equipe { get { return quipe; } set { quipe = value; } } public Projet() { } } }

Employ.cs
using using using using using using using using using using System; System.Net; System.Windows; System.Windows.Controls; System.Windows.Documents; System.Windows.Ink; System.Windows.Input; System.Windows.Media; System.Windows.Media.Animation; System.Windows.Shapes;

namespace TestWindowsControls { public class Employ { private string nom; public string Nom

258

Le contrle DataGrid

{ get { return nom; } set { nom = value; } } private string prenom; public string Prenom { get { return prenom; } set { prenom = value; } } private Uri photo; public Uri Photo { get { return photo; } set { photo = value; } } private Uri blog; public Uri Blog { get { return blog; } set { blog = value; } } private string email; public string Email { get { return email; } set { email = value; } } public Employ() { } } }

CollectionDeProjet.cs
using System; using System.Net; using System.Windows;

259

Concepts avancs

using using using using using using using using

System.Windows.Controls; System.Windows.Documents; System.Windows.Ink; System.Windows.Input; System.Windows.Media; System.Windows.Media.Animation; System.Windows.Shapes; System.Collections.Generic;

namespace TestWindowsControls { public static class CollectionDeProjet { public static List<Projet> Projets = new List<Projet>() { new Projet() { Nom="OpenApp", Dpart=new DateTime(2009,1,12), Buttoir=new DateTime(2009,2,15), Equipe = new List<Employ>() { CollectionDeProjet.Simon, CollectionDeProjet.Caroline } }, new Projet() { Nom="Livre SL2", Dpart=new DateTime(2006,8,5), Buttoir=new DateTime(2000,1,10), Equipe = new List<Employ>() { CollectionDeProjet.Loc, CollectionDeProjet.Simon } }, new Projet() { Nom="Jubbeo", Dpart=new DateTime(2009,3,6), Buttoir=new DateTime(2009,8,21), Equipe = new List<Employ>() { CollectionDeProjet.Florent,

260

Le contrle DataGrid

CollectionDeProjet.Simon, CollectionDeProjet.Loc } }, new Projet() { Nom="Wipus", Dpart=new DateTime(2006,7,1), Buttoir=new DateTime(2009,4,8), Equipe = new List<Employ>() { CollectionDeProjet.Simon, CollectionDeProjet.Loc, CollectionDeProjet.X } } }; public static Employ Loc = new Employ() { Nom = "Loc", Prenom = "Bar", Email = "loic.bar@wipus.com", Photo = new Uri("Employe/Loic.jpg", UriKind.Relative), Blog = new Uri("http://www.loicbar.com",UriKind.Absolute) }; public static Employ Simon = new Employ() { Nom = "Simon", Prenom = "Boigelot", Email = "simon.boigelot@wipus.com", Photo = new Uri("Employe/Simon.jpg", UriKind.Relative), Blog = new Uri("http://www.simonboigelot.com", UriKind.Absolute) }; public static Employ Florent = new Employ() { Nom = "Florent", Prenom = "G.", Email = "MisterFlo@provider.com", Photo = new Uri("Employe/Buddy.JPG", UriKind.Relative), Blog = new Uri("http://fake.MisterFlo.com", UriKind.Absolute) };

261

Concepts avancs

public static Employ Caroline = new Employ() { Nom = "Caroline", Prenom = "L.", Email = "caroline@wipus.com", Photo = new Uri("Employe/Buddy.JPG", UriKind.Relative), Blog = new Uri("http://fake.KRO.com", UriKind.Absolute) }; public static Employ X = new Employ() { Nom = "", Prenom = "X", Email = "x@wipus.com", Photo = new Uri("Employe/Buddy.JPG", UriKind.Relative), Blog = new Uri("http://fake.X.com", UriKind.Absolute) }; } }

En guise dillustration du problme d lauto gnration, voici ce que donnerait une DataGrid auto gnre dont litemsSource est CollectionDeProjet.Projets.

c Fig. 5.25 : Problme du AutoGeneratedColumn

Les dates reprsentes dans cette DataGrid ont un aspect la limite de lillisible. Quant la liste demploys, impossible de savoir ce quelle contient. Reproduisons dabord ce rsultat :
Reproduction du rsultat auto gnr
<UserControl x:Class="TestWindowsControls.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="clr-namespace:System.Windows.Controls; assembly=System.Windows.Controls" xmlns:data="clr-namespace:System.Windows.Controls; assembly=System.Windows.Controls.Data"

262

Le contrle DataGrid

Width="Auto" Height="Auto"> <Grid x:Name="LayoutRoot" Background="White"> <data:DataGrid Name="dataGrid" HeadersVisibility="All" ColumnWidth="150" RowHeight="20" AutoGenerateColumns="False" RowBackground="Beige" IsReadOnly="False" AlternatingRowBackground="LemonChiffon"> <data:DataGrid.Columns> <data:DataGridTextColumn Header="Nom du Projet" Binding="{Binding Path=Nom}" /> <data:DataGridTextColumn Header="Date de dbut" Binding="{Binding Path=Dpart}" /> <data:DataGridTextColumn Header="Date buttoir" Binding="{Binding Path=Buttoir}" /> <data:DataGridTextColumn Header="Equipe" Binding="{Binding Path=Equipe}" /> </data:DataGrid.Columns> </data:DataGrid> </Grid> </UserControl>

c Fig. 5.26 : Reproduction du rsultat auto gnr

Modication de laffichage des dates


Pour afficher des dates, rien de mieux quun DatePicker. Nous allons remplacer dans le code XAML de lapplication les deux
DataGridTextColumns Date de dbut et Date buttoir par des DataGridTemplateColumns

contenant un DatePicker.
Exemple de DataGridTemplateColumn DatePicker
<data:DataGridTemplateColumn Header="Date de dbut"> <data:DataGridTemplateColumn.CellTemplate> <DataTemplate> <controls:DatePicker

263

Concepts avancs

SelectedDate="{Binding Dpart, Mode=OneWay}" /> </DataTemplate> </data:DataGridTemplateColumn.CellTemplate> <data:DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <controls:DatePicker SelectedDate="{Binding Dpart, Mode=TwoWay}" /> </DataTemplate> </data:DataGridTemplateColumn.CellEditingTemplate> </data:DataGridTemplateColumn>

Deux attributs de Template sont rednir dans cet UserControl, le CellTemplate (Template utilis en mode daffichage de donnes) et le CellEditingTemplate (Template utilis en mode ddition des donnes) Le remplacement de ces DataTemplate la sauce DataGrid contribue dj beaucoup la propret de notre interface :

c Fig. 5.27 : DataGrid avec DataGridTemplateColumn DatePicker

Modication de laffichage de la liste demploys


Pour ce qui est de la liste demploys, une bonne faon de sentraner la manipulation des DataGrid est dcrire DataGrid en tant que rednition dune cellule par une autre partie de DataGrid. Dbutons avec lattribut AutoGeneratedColumn True. Il est vident quil faudra changer cela le plus vite possible :
DataGridTemplateColumn contenant une DataGrid auto gnre
<data:DataGridTemplateColumn Header="Equipe"> <data:DataGridTemplateColumn.CellTemplate> <DataTemplate>

264

Le contrle DataGrid

<data:DataGrid AutoGenerateColumns="True" ItemsSource="{Binding Path=Equipe}" IsReadOnly="True"> <!--<data:DataGrid.Columns> <data:DataGridTextColumn Header="Nom" Binding="{Binding Nom}"/> </data:DataGrid.Columns>--> </data:DataGrid> </DataTemplate> </data:DataGridTemplateColumn.CellTemplate> <data:DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <data:DataGrid AutoGenerateColumns="True" ItemsSource="{Binding Path=Equipe}" IsReadOnly="False"> </data:DataGrid> </DataTemplate> </data:DataGridTemplateColumn.CellEditingTemplate> </data:DataGridTemplateColumn>

Le rsultat est dj trs satisfaisant :

c Fig. 5.28 : DataGridTemplateColumn contenant une DataGrid auto gnre

Pour rendre le tout encore plus beau, nous allons crer pour chaque employ une mini carte de visite.

265

Concepts avancs

Cest maintenant que lon passe False la valeur AutoGeneretedColumn de notre DataGrid Equipe, elle-mme DataTemplate dune DataGridTemplateColumn de notre DataGrid principale :
Carte de visite pour Employs
<data:DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Path=Equipe}" IsReadOnly="True"> <data:DataGrid.Columns> <data:DataGridTemplateColumn> <data:DataGridTemplateColumn.CellTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <Image Source="{Binding Path=ImageSourcePhoto}" Height="50" Width="50" Stretch="UniformToFill"/> <StackPanel Orientation="Vertical"> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Path=Prenom}" Margin="5"/> <TextBlock Text="{Binding Path=Nom}" Margin="5"/> </StackPanel> <HyperlinkButton Content="{Binding Blog}"/> <HyperlinkButton Content="{Binding Email}"/> </StackPanel> </StackPanel> </DataTemplate> </data:DataGridTemplateColumn.CellTemplate> </data:DataGridTemplateColumn> </data:DataGrid.Columns> </data:DataGrid> c Fig. 5.29 : DataGrid compltement customise

266

Le contrle DataGrid

Il a t ncessaire dajouter une proprit la dnition de classe Etudiant. Cette proprit est ImageSourcePhoto de type ImageSource. En effet, lattribut Source dune Image est une ImageSource et non un URI :
Proprit ImageSourcePhoto
namespace TestWindowsControls { public class Employ { (...) public ImageSource ImageSourcePhoto { get { return new BitmapImage(Photo); } } (...) } }

Listing de linterface complte de la DataGrid templatise


DataGrid Templatise
<UserControl x:Class="TestWindowsControls.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="clr-namespace:System.Windows.Controls; assembly=System.Windows.Controls" xmlns:data="clr-namespace:System.Windows.Controls; assembly=System.Windows.Controls.Data" Width="Auto" Height="Auto"> <Grid x:Name="LayoutRoot" Background="White"> <data:DataGrid Name="dataGrid" HeadersVisibility="All" AutoGenerateColumns="False" RowBackground="Beige" IsReadOnly="False" AlternatingRowBackground="LemonChiffon"> <data:DataGrid.Columns> <data:DataGridTextColumn Header="Nom du Projet"

267

Concepts avancs

Binding="{Binding Path=Nom}" /> <data:DataGridTemplateColumn Header="Date de dbut"> <data:DataGridTemplateColumn.CellTemplate> <DataTemplate> <controls:DatePicker VerticalAlignment="Top" SelectedDate="{Binding Dpart, Mode=OneWay}" /> </DataTemplate> </data:DataGridTemplateColumn.CellTemplate> <data:DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <controls:DatePicker VerticalAlignment="Top" SelectedDate="{Binding Dpart, Mode=TwoWay}" /> </DataTemplate> </data:DataGridTemplateColumn.CellEditingTemplate> </data:DataGridTemplateColumn> <data:DataGridTemplateColumn Header="Date buttoir"> <data:DataGridTemplateColumn.CellTemplate> <DataTemplate> <controls:DatePicker VerticalAlignment="Top" SelectedDate="{Binding Buttoir, Mode=OneWay}" /> </DataTemplate> </data:DataGridTemplateColumn.CellTemplate> <data:DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <controls:DatePicker VerticalAlignment="Top" SelectedDate="{Binding Buttoir, Mode=TwoWay}" /> </DataTemplate> </data:DataGridTemplateColumn.CellEditingTemplate> </data:DataGridTemplateColumn> <data:DataGridTemplateColumn Header="Equipe"> <data:DataGridTemplateColumn.CellTemplate> <DataTemplate> <data:DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Path=Equipe}" IsReadOnly="True"> <data:DataGrid.Columns> <data:DataGridTemplateColumn> <data:DataGridTemplateColumn.CellTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <Image Source="{Binding Path=ImageSourcePhoto}" Height="50" Width="50"

268

Les contrles Silverlight Toolkit de CodePlex

Stretch="UniformToFill"/> <StackPanel Orientation="Vertical"> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Path=Prenom}" Margin="5"/> <TextBlock Text="{Binding Path=Nom}" Margin="5"/> </StackPanel> <HyperlinkButton Content="{Binding Blog}"/> <HyperlinkButton Content="{Binding Email}"/> </StackPanel> </StackPanel> </DataTemplate> </data:DataGridTemplateColumn.CellTemplate> </data:DataGridTemplateColumn> </data:DataGrid.Columns> </data:DataGrid> </DataTemplate> </data:DataGridTemplateColumn.CellTemplate> </data:DataGridTemplateColumn> </data:DataGrid.Columns> </data:DataGrid> </Grid> </UserControl>

5.6 Les contrles Silverlight Toolkit de CodePlex


Les derniers contrles que ce livre aborde sont les contrles fournis par le Silverlight ToolKit de CodePlex. Ce ToolKit ajoute 12 nouveaux UserControl aux contrles utilisateur prsents dans la version de base de Silverlight. Ces 12 contrles utilisateur se rpartissent en trois catgories :
j j j

les contrles utilisateur de saisie dinformations ; les contrles utilisateur de structuration dinformations ; les contrles utilisateur de styles et thmes.

Pour utiliser ces nouveaux contrles, il faut pralablement en tlcharger la librairie sur le site de CodePlex : http://www.codeplex.com/Silverlight/. Ensuite, pour ajouter votre projet Silverlight les diffrentes DLL en tant que rfrences :
1

Cliquez du bouton droit sur Reference dans lExplorateur de solution.

269

Concepts avancs

Slectionnez laction Ajouter une rfrence.


c Fig. 5.30 : Add Reference

Dans la bote de dialogue Ajouter une rfrence, slectionnez longlet Parcourir. 4 Naviguez jusqu lemplacement des DLL et slectionnez les chiers Microsoft .Windows.Controls.Theming.dl, Microsoft.Windows.Controls.DataVisualization.dll, Microsoft.Windows.Controls.dll et Microsoft.Windows.Controls.Input.dll.
3 c Fig. 5.31 : Bote de dialogue Ajouter une rfrence

Cliquez sur OK.

Vous trouverez tous les exemples et toutes les informations ncessaires lutilisation de ces nouveaux UserControls dans le chier ZIP fourni par CodePlex.

270

Check-list

5.7 Check-list
Dans ce chapitre, nous avons amlior considrablement nos comptences en XAML, tudi des moyens efficaces pour rendre un code dinterface plus lisible ainsi que dautres moyens, tout aussi efficaces, pour obtenir leffet inverse. Le juste milieu entre un code propre et une exprience utilisateur riche ne semble pas encore accessible ; seule lexprience pourra vous aider sur cette voie. Sachez que rien nest impossible, en Silverlight, ou presque. Tout ce que vous pouvez imaginer, vous pouvez le coder ; la plateforme .Net vous y aidera.

271

6
6.1 Introduction Deepzoom .............................. 6.2 Fonctionnement de Deepzoom ........................ 6.3 Deepzoom par lexemple .............................. 6.4 Deepzoom et Virtual Earth ............................. 6.5 Check-list ................................................. 274 275 279 288 289

Dcouvrir Deepzoom
D
eepzoom est une technologie introduite dans Silverlight 2. Cest un des points forts de Silverlight. En effet, Deepzoom permet une gestion optimale des images. Nous allons dcouvrir dans ce chapitre comment utiliser cette technologie hors du commun au travers dun exemple simple mais efficace avec Deepzoom.

Dcouvrir Deepzoom

6.1 Introduction Deepzoom


DeepZoom permet deffectuer un zoom performant sur des images presque arbitrairement de grandes tailles dans Silverlight. Les images peuvent tre affiches une chelle trs petite et trs grande sans affecter les performances de lapplication qui affiche limage. La seule proprit qui affecte les performances est le nombre de pixels afficher lcran. Mais il existe des cas dj largement diffuss sur Internet qui utilisent des milliards de pixels. Cest le cas du hard rock que vous pouvez trouver cette adresse : http://memorabilia .hardrock.com/.

c Fig. 6.1 : Hard rock

Youtube, Dailymotion et dautres se sont mis la haute rsolution. Deepzoom est l pour que vous puissiez faire de mme avec les images. Souvent, les photos sur le Web sont de mauvaise qualit ; on peut trs rarement zoomer correctement sur une image. Vous pouvez utiliser deepzoom pour afficher des images de trs grande qualit. Vous pouvez ainsi imaginer un site de visualisation dimages haute rsolution pour les photos de vacances, de mariage ou les photos professionnelles. Deepzoom permet galement une visualisation panoramique dun paysage ou dune maison. Imaginez cela pour des sites consacrs limmobilier ! Cela permet galement de nouveaux modles de publicit. En effet, le zoom peut apporter des informations supplmentaires sur un produit mis en publicit.

274

Fonctionnement de Deepzoom

6.2 Fonctionnement de Deepzoom


Deepzoom charge en fait les images en basse rsolution et charge les rsolutions plus grandes au fur et mesure. Cest pour cette raison que le chargement de limage est trs rapide. Quand on regarde les sondages, ce qui embte le plus un utilisateur est de devoir attendre pour le chargement dune page. Ici on charge les informations de base de limage ; au dbut, limage reste oue mais bien prsente. Au fur et mesure, limage sclaircit et avant mme que lutilisateur nait eu le temps de commencer zoomer, limage est charge entirement. Ceci permet davoir une exprience utilisateur unique et vraiment satisfaisante.
c Fig. 6.2 : Image dans le temps

Limage haute rsolution est en fait dcoupe en plusieurs images. Microsoft appelle cela la pyramide dimages. Une pyramide dimages dcompose une image en fragments de 256 x 256 dimages JPG ou PNG (dans ce cas, la taille est arbitraire et peut tre modie) et stocke galement des versions de rsolution infrieure de limage dans les fragments. Chaque fragment est stock lintrieur dun chier distinct et chaque niveau de la pyramide est stock lintrieur de dossiers distincts. Limage ci-aprs dcrit schmatiquement le fonctionnement de la pyramide dimages. Limage elle-mme est disponible en pleine rsolution dans le bas de la pyramide (voir limage ci-aprs) et les versions de rsolution infrieure jusqu 4 x 4 pixels sont stockes avec limage pleine rsolution. Les images chaque niveau de la pyramide sont stockes dans des fragments de 256 x 256 pixels (lignes blanches dans les images). DeepZoom peut ainsi extraire uniquement les fragments requis pour la taille actuelle de limage lcran, au lieu de tlcharger toute limage. Par exemple, si vous effectuez un zoom avant pour afficher uniquement la partie centrale en surbrillance de limage, DeepZoom charge uniquement les fragments en surbrillance, plutt que toute limage au format 1 024 x 1 024. La cration manuelle de ces pyramides peut se rvler fastidieuse. Par consquent, il est recommand dutiliser un outil permettant de convertir les images en une pyramide dimages. Par exemple, pour ce faire, vous pouvez utiliser DeepZoom Composer. Vous trouverez cet utilitaire sur le site de Silverlight.net.

275

Dcouvrir Deepzoom

c Fig. 6.3 : Pyramide dimages

Le format de chier qui sert accder la pyramide dimages utilise un schma XML. nouveau, vous pouvez gnrer ce format de chier laide de DeepZoom Composer. Toutefois, si vous souhaitez exercer un contrle plus prcis sur le format de chier, vous pouvez crer manuellement le code XML ou apporter des modications manuelles un chier gnr par un outil. Vous pouvez vous-mme crer un les chiers XML. Mais cela est loin dtre simple. Dabord, il gnre un chier de metadata :
<?xml version="1.0"?> <Metadata version="1"> <AspectRatio>0.733841659419689</AspectRatio> <Image> <FileName>C:\Documents and Settings\samlan\Desktop\Labs\ DeepZoomCollections\DeepZoomOutput\DeepZoomComposer\source images\tree_blossoms.jpg</FileName> <x>0</x> <y>0</y> <Width>0.429715926819635</Width> <Height>0.4739336492891</Height> <ZOrder>1</ZOrder> <Tag /> </Image> <Image> <FileName>C:\Documents and Settings\samlan\Desktop\Labs\DeepZoomCollections\ DeepZoomOutput\DeepZoomComposer\source images\guy_by_the_beach.jpg</FileName>

276

Fonctionnement de Deepzoom

<x>0.55991053434817</x> <y>0</y> <Width>0.44008946565183</Width> <Height>0.4739336492891</Height> <ZOrder>2</ZOrder> <Tag /> </Image> <Image> <FileName>C:\Documents and Settings\samlan\Desktop\Labs\ DeepZoomCollections\DeepZoomOutput\DeepZoomComposer\source images\licorice.jpg</FileName> <x>0</x> <y>0.5260663507109</y> <Width>0.431362685784476</Width> <Height>0.4739336492891</Height> <ZOrder>3</ZOrder> <Tag /> </Image> <Image> <FileName>C:\Documents and Settings\samlan\Desktop\Labs\ DeepZoomCollections\DeepZoomOutput\DeepZoomComposer\source images\flower.jpg</FileName> <x>0.579552839832946</x> <y>0.5260663507109</y> <Width>0.420447160167053</Width> <Height>0.4739336492891</Height> <ZOrder>4</ZOrder> <Tag /> </Image> </Metadata>

Ainsi quun deuxime chier presque identique mais avec un ratio :


<?xml version="1.0"?> <SceneGraph version="1"> <AspectRatio>0.733841659419689</AspectRatio> <SceneNode> <FileName>C:\Documents and Settings\samlan\Desktop\Labs\ DeepZoomCollections\DeepZoomOutput\DeepZoomComposer\source images\tree_blossoms.jpg</FileName> <x>0</x> <y>0</y> <Width>0.429715926819635</Width> <Height>0.4739336492891</Height> <ZOrder>1</ZOrder> </SceneNode> <SceneNode>

277

Dcouvrir Deepzoom

<FileName>C:\Documents and Settings\samlan\Desktop\Labs\ DeepZoomCollections\DeepZoomOutput\DeepZoomComposer\source images\guy_by_the_beach.jpg</FileName> <x>0.55991053434817</x> <y>0</y> <Width>0.44008946565183</Width> <Height>0.4739336492891</Height> <ZOrder>2</ZOrder> </SceneNode> <SceneNode> <FileName>C:\Documents and Settings\samlan\Desktop\Labs\ DeepZoomCollections\DeepZoomOutput\DeepZoomComposer\source images\licorice.jpg</FileName> <x>0</x> <y>0.5260663507109</y> <Width>0.431362685784476</Width> <Height>0.4739336492891</Height> <ZOrder>3</ZOrder> </SceneNode> <SceneNode> <FileName>C:\Documents and Settings\samlan\Desktop\Labs\ DeepZoomCollections\DeepZoomOutput\DeepZoomComposer\source images\flower.jpg</FileName> <x>0.579552839832946</x> <y>0.5260663507109</y> <Width>0.420447160167053</Width> <Height>0.4739336492891</Height> <ZOrder>4</ZOrder> </SceneNode> </SceneGraph>

Il gnre enn un chier contenant des informations sur les images et des rfrences vers les metadata de chacune des images :
<?xml version="1.0" encoding="UTF-8"?> <Collection MaxLevel="8" TileSize="256" Format="png" NextItemId="4" xmlns="http://schemas.microsoft.com/deepzoom/2008"> <Items> <I Id="0" N="0" IsPath="1" Source="dzc_output_images/tree_blossoms.xml"> <Size Width="515" Height="774" /> <Viewport Width="2.32711864" X="0" Y="0" /> </I> <I Id="1" N="1" IsPath="1" Source="dzc_output_images/guy_by_the_beach.xml"> <Size Width="569" Height="835" /> <Viewport Width="2.2722652" X="-1.2722652" Y="0" /> </I>

278

Deepzoom par lexemple

<I Id="2" N="2" IsPath="1" Source="dzc_output_images/licorice.xml"> <Size Width="531" Height="795" /> <Viewport Width="2.318235" X="0" Y="-1.66186452" /> </I> <I Id="3" N="3" IsPath="1" Source="dzc_output_images/flower.xml"> <Size Width="541" Height="831" /> <Viewport Width="2.37842" X="-1.37842011" Y="-1.70500922" /> </I> </Items> </Collection>

Ce chier rfrence par exemple les informations sur ower :


<?xml version="1.0" encoding="UTF-8"?> <Image TileSize="256" Overlap="1" Format="png" xmlns="http://schemas.microsoft.com/deepzoom/2008"> <Size Width="541" Height="831"/> </Image>

Vous voyez galement une srie de dossiers : 1, 2, 3, 4, etc. Ces dossiers contiennent une ou plusieurs images. Elles reprsentent llment de plus en plus grand.

6.3 Deepzoom par lexemple


Pour bien comprendre Deepzoom, il faut lutiliser. Voici en image lapplication Silverlight que nous allons crer : Pour commencer, il faut dnir le XAML pour cette application. Si on regarde attentivement, on remarque seulement deux lments pertinents :
j j

une zone pour les images ; un bouton.

La zone pour les images est un peu particulire ; cest une zone spcique Deepzoom que vous navez probablement jamais rencontre auparavant. Cest un objet XAML MultiScaleImage :
<MultiScaleImage Height="600" x:Name="msi" Source="GeneratedImages/dzc_output.xml" Width="800"/>

279

Dcouvrir Deepzoom

c Fig. 6.4 : Application Silverlight de test

Cette zone fait rfrence au chier XML que nous avons vu prcdemment et qui ressemble ceci :
<?xml version="1.0" encoding="UTF-8"?> <Collection MaxLevel="8" TileSize="256" Format="png" NextItemId="4" xmlns="http://schemas.microsoft.com/deepzoom/2008"> <Items> <I Id="0" N="0" IsPath="1" Source="dzc_output_images/tree_blossoms.xml"> <Size Width="515" Height="774" /> <Viewport Width="2.32711864" X="0" Y="0" /> </I>

Une fois que vous avez assimil le nouvel lment XAML, le code nest pas trs compliqu :
<UserControl x:Class="DeepZoomProject.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

280

Deepzoom par lexemple

Width="800" Height="600"> <Grid x:Name="LayoutRoot" Background="White"> <Border BorderBrush="#FF727272" BorderThickness="1,1,1,1"> <MultiScaleImage Height="600" x:Name="msi" Source="GeneratedImages/dzc_output.xml" Width="800"/> </Border> <Button Height="31" Width="286" Content="Randomize Images" Click="Arrange_Click"/> </Grid> </UserControl>

Sur notre MultiScaleImage, nous allons dclarer une srie dvnements qui nous permettront de savoir ce que fait lutilisateur sur lapplication (clic, dplacement, etc.). Ceci se fera dans le constructeur de notre page (dans le code behind, code attach) :
msi.MouseMove += delegate(object sender, MouseEventArgs e) { if (mouseButtonPressed) { mouseIsDragging = true; } this.lastMousePos = e.GetPosition(this.msi); }; msi.MouseLeftButtonDown += delegate(object sender, MouseButtonEventArgs e) { mouseButtonPressed = true; mouseIsDragging = false; dragOffset = e.GetPosition(this); currentPosition = msi.ViewportOrigin; }; msi.MouseLeave += delegate(object sender, MouseEventArgs e) { mouseIsDragging = false; }; msi.MouseLeftButtonUp += delegate(object sender, MouseButtonEventArgs e) { mouseButtonPressed = false; if (mouseIsDragging == false) { bool shiftDown = (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift; ZoomFactor = 2.0; if (shiftDown) ZoomFactor = 0.5;

281

Dcouvrir Deepzoom

Zoom(ZoomFactor, this.lastMousePos); } mouseIsDragging = false; }; msi.MouseMove += delegate(object sender, MouseEventArgs e) { if (mouseIsDragging) { Point newOrigin = new Point(); newOrigin.X = currentPosition.X - (((e.GetPosition(msi).X dragOffset.X) / msi.ActualWidth) * msi.ViewportWidth); newOrigin.Y = currentPosition.Y - (((e.GetPosition(msi).Y dragOffset.Y) / msi.ActualHeight) * msi.ViewportWidth); msi.ViewportOrigin = newOrigin; } };

On voit apparatre lutilisation dune fonction Zoom, fonction que lon utilise pour atteindre un point :
public void Zoom(double zoom, Point pointToZoom) { Point logicalPoint = this.msi.ElementToLogicalPoint(pointToZoom); this.msi.ZoomAboutLogicalPoint(zoom, logicalPoint.X, logicalPoint.Y); }

Tout ce code ne prend malheureusement pas en compte la molette de la souris qui est pourtant trs utilise. Pour cela, nous pouvons crer une classe qui prendra en compte cette molette. Cette classe a t dnie au dpart par Pete Bois et adapte au projet. Vous trouverez le code de cette classe la n du chapitre. Vous pouvez vous attacher aux vnements de la molette de la manire suivante :
new MouseWheelHelper(msi).Moved += delegate(object sender, MouseWheelEventArgs e) { e.Handled = true; if (e.Delta > 0) ZoomFactor = 1.2; else ZoomFactor = .80; Zoom(ZoomFactor, this.lastMousePos); };

282

Deepzoom par lexemple

Dans notre programme, il faut juste grer correctement le clic sur le bouton au milieu de notre application Silverlight. Pour cela, une fonction intercepte lvnement click de notre bouton :
private void Arrange_Click(object sender, RoutedEventArgs e) { ArrangeIntoGrid(); }

Cette fonction va rarranger les images. Nous devons crer une animation. Vous avez vu dans un chapitre prcdent ce qutait les storyboards. Nous allons ici crer un storyboard de faon dynamique, cest--dire directement dans le code :
Storyboard moveStoryboard = new Storyboard();

Ensuite, il faut crer lanimation et les frames qui vont intervenir dedans :
// Create Animation PointAnimationUsingKeyFrames moveAnimation = new PointAnimationUsingKeyFrames(); // Create Keyframe SplinePointKeyFrame startKeyframe = new SplinePointKeyFrame(); startKeyframe.Value = currentPosition; startKeyframe.KeyTime = KeyTime.FromTimeSpan(TimeSpan.Zero); startKeyframe = new SplinePointKeyFrame(); startKeyframe.Value = futurePosition; startKeyframe.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(1)); KeySpline ks = new KeySpline(); ks.ControlPoint1 = new Point(0, 1); ks.ControlPoint2 = new Point(1, 1); startKeyframe.KeySpline = ks; moveAnimation.KeyFrames.Add(startKeyframe); Storyboard.SetTarget(moveAnimation, currentImage); Storyboard.SetTargetProperty(moveAnimation, new PropertyPath("ViewportOrigin")); moveStoryboard.Children.Add(moveAnimation); msi.Resources.Add("unique_id", moveStoryboard); // Play Storyboard moveStoryboard.Begin();

283

Dcouvrir Deepzoom

La seule chose faire auparavant est de rorganiser les images. Pour cela, nous disposons dune liste dimages qui est renvoye par notre fonction. Cette liste dtermine lordre :
private List<MultiScaleSubImage> RandomizedListOfImages() { List<MultiScaleSubImage> imageList = new List<MultiScaleSubImage>(); Random ranNum = new Random(); // Store List of Images foreach (MultiScaleSubImage subImage in msi.SubImages) { imageList.Add(subImage); } int numImages = imageList.Count; // Randomize Image List for (int i = 0; i < numImages; i++) { MultiScaleSubImage tempImage = imageList[i]; imageList.RemoveAt(i); int ranNumSelect = ranNum.Next(imageList.Count); imageList.Insert(ranNumSelect, tempImage); } return imageList; }

Dans la fonction ArrangeIntoGrid, nous rcuprons tout au dbut ces images :


List<MultiScaleSubImage> randomList = RandomizedListOfImages();

Ensuite, on effectue une boucle sur le nombre de colonnes de notre application (3) et sur le nombre dimages par colonne (nombre dimages/nombre de colonnes 1 ) . Ce sont les seules choses dont vous avez besoin pour crer cette application utilisant Deepzoom. Vous pourrez retrouver lexemple complet dans le code livr avec le livre sur le site de Micro Application.

284

Deepzoom par lexemple

MouseWheelHelper.cs
using using using using using using using using using using using System; System.Net; System.Windows; System.Windows.Controls; System.Windows.Documents; System.Windows.Ink; System.Windows.Input; System.Windows.Media; System.Windows.Media.Animation; System.Windows.Shapes; System.Windows.Browser;

namespace DeepZoomProject { // Courtesy of Pete Blois public class MouseWheelEventArgs : EventArgs { private double delta; private bool handled = false; public MouseWheelEventArgs(double delta) { this.delta = delta; } public double Delta { get { return this.delta; } } // Use handled to prevent the default browser behavior! public bool Handled { get { return this.handled; } set { this.handled = value; } } } public class MouseWheelHelper { public event EventHandler<MouseWheelEventArgs> Moved; private static Worker worker; private bool isMouseOver = false;

285

Dcouvrir Deepzoom

public MouseWheelHelper(FrameworkElement element) { if (MouseWheelHelper.worker == null) MouseWheelHelper.worker = new Worker(); MouseWheelHelper.worker.Moved += this.HandleMouseWheel; element.MouseEnter += this.HandleMouseEnter; element.MouseLeave += this.HandleMouseLeave; element.MouseMove += this.HandleMouseMove; } private void HandleMouseWheel(object sender, MouseWheelEventArgs args) { if (this.isMouseOver) this.Moved(this, args); } private void HandleMouseEnter(object sender, EventArgs e) { this.isMouseOver = true; } private void HandleMouseLeave(object sender, EventArgs e) { this.isMouseOver = false; } private void HandleMouseMove(object sender, EventArgs e) { this.isMouseOver = true; } private class Worker { public event EventHandler<MouseWheelEventArgs> Moved; public Worker() { if (HtmlPage.IsEnabled) { HtmlPage.Window.AttachEvent("DOMMouseScroll", this.HandleMouseWheel);

286

Deepzoom par lexemple

HtmlPage.Window.AttachEvent("onmousewheel", this.HandleMouseWheel); HtmlPage.Document.AttachEvent("onmousewheel", this.HandleMouseWheel); } } private void HandleMouseWheel(object sender, HtmlEventArgs args) { double delta = 0; ScriptObject eventObj = args.EventObject; if (eventObj.GetProperty("wheelDelta") != null) { delta = ((double)eventObj.GetProperty("wheelDelta")) / 120;

if (HtmlPage.Window.GetProperty("opera") != null) delta = -delta; } else if (eventObj.GetProperty("detail") != null) { delta = -((double)eventObj.GetProperty("detail")) / 3; if (HtmlPage.BrowserInformation.UserAgent.IndexOf ("Macintosh") != -1) delta = delta * 3; } if (delta != 0 && this.Moved != null) { MouseWheelEventArgs wheelArgs = new MouseWheelEventArgs(delta); this.Moved(this, wheelArgs); if (wheelArgs.Handled) args.PreventDefault(); } } }

287

Dcouvrir Deepzoom

} }

La partie la plus importante est la partie o nous allons attacher les vnements :
public Worker() { if (HtmlPage.IsEnabled) { HtmlPage.Window.AttachEvent("DOMMouseScroll", this.HandleMouseWheel); HtmlPage.Window.AttachEvent("onmousewheel", this.HandleMouseWheel); HtmlPage.Document.AttachEvent("onmousewheel", this.HandleMouseWheel); } }

6.4 Deepzoom et Virtual Earth


Virtual Earth est le Google Map de Microsoft. Il est dans un sens meilleur que Google Map au niveau du nombre de vues quil propose par dfaut. Son plus gros dfaut est dtre payant pour une utilisation pousse. Si on rchit au fonctionnement dun utilitaire de map, on se rend vite compte quau nal, ce nest quune srie dimages mises les unes ct des autres et les unes au-dessus des autres. On arrive bien imaginer que cela fonctionne un peu comme Deepzoom ou quil est trs facile dutiliser Deepzoom avec la structure dimages existantes. Vous pouvez dcouvrir un projet qui permet dintgrer Virtual Earth dans Deepzoom. Retrouvez ce projet ladresse suivante : http://www.codeplex.com/deepearth.

288

Check-list

6.5 Check-list
Dans ce chapitre sur Deepzoom, nous avons tudi :

a llment XAML MultiScaleImage ; a la manipulation des images dans Deepzoom laide de Deepzoom Composer.

289

7
7.1 Silverlight et les langages dynamiques ............... 7.2 Introduction au C# ...................................... 7.3 Webographie ........................................... 292 299 311

Annexes

Annexes

7.1 Silverlight et les langages dynamiques


Silverlight supporte les langages dynamiques. Dans ces langages, on retrouve Python et Ruby que vous connaissez peut-tre. On peut facilement imaginer que dautres langages viendront sajouter cette liste, comme PHP. Le support de ces langages dynamiques permet une meilleure prise en main de Silverlight, qui sappuie alors sur des langages bien plus largement utiliss. Dans cette annexe, nous verrons comment employer Silverlight avec Python et Ruby, renomms pour loccasion IronPython et IronRuby.

Silverlight et IronPyhton
Il faut savoir que la DLR, outil indispensable pour utiliser les langages dynamiques, est encore en dveloppement. Tous les tests que vous pouvez actuellement effectuer se font sur un composant en dveloppement. La DLR et les langages dynamiques ont t cons la communaut (en grande partie). Cest donc une dmarche de Microsoft vers lOpenSource. Cela amne de nombreux avantages mais aussi certains inconvnients. Ces langages ne sont pas encore bien intgrs Visual Studio. Comme vous allez le voir, nous devrons repasser en ligne de commandes pour crer notre projet IronPython. Cela devrait tre rgl peu de temps aprs la parution de ce livre dans le courant de 2009. En attendant, vous devez vous procurer le SDK de dveloppement. Ce SDK peut tre trouv sur le site de Silverlight.NET. Une fois install, vous pouvez ouvrir votre utilitaire de commande et vous rendre dans le dossier script du chier tlcharg. Pour crer un projet, il faut ensuite utiliser cette ligne de commandes :
> script/sl [ruby|python|jscript] <application_name>

Par exemple :
> script/sl python testPythonApp

De cette manire, un projet est gnr dans un dossier testPyhtonApp. lintrieur, vous trouvez quelques chiers dont un index et deux dossiers. Dans les deux dossiers, vous avez un chier de style ainsi que deux chiers composant lapplication Silverlight : un chier XAML et un chier Python. Vous pouvez les ouvrir avec Visual Studio :
<UserControl x:Class="System.Windows.Controls.UserControl" xmlns="http://schemas.microsoft.com/client/2007"

292

Silverlight et les langages dynamiques

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Grid x:Name="layout_root" Background="White"> <TextBlock x:Name="Message" FontSize="30" /> </Grid> </UserControl>

Ainsi que le chier Python :


from System.Windows import Application from System.Windows.Controls import UserControl class App: def __init__(self): root = Application.Current.LoadRootVisual(UserControl(), "app.xaml") root.Message.Text = "Welcome to Python and Silverlight!" App()

Pour gnrer ensuite un chier xap, vous avez besoin dun petit utilitaire appel Chiron. Vous pouvez trouver cet utilitaire dans le package que vous avez tlcharg (SDK de la DLR). Cet utilitaire sutilise de la manire suivante :
Chiron.exe /directory:MyApp\app /zipdlr:app.xap

Nous vous conseillons de dplacer le contenu du chier bin dans le rpertoire o vous voulez crer votre chier xap. Aprs avoir obtenu ce chier, vous avez toutes les cartes en main pour crer correctement une application Silverlight avec des langages dynamiques.

Une horloge en IronPython et Silverlight


Nous allons crer un simple exemple en IronPython. Nous ne reviendrons pas dans cette partie sur la cration et la compilation du projet. Cette application est vraiment simple et compose de deux chiers : app.xaml et app.py. Une horloge est anime, il faut donc dclarer, comme vous lavez vu au chapitre 2, Le langage XAML, une srie de triggers et de storyboards :
<Canvas.Triggers> <EventTrigger RoutedEvent="Canvas.Loaded"> <EventTrigger.Actions> <BeginStoryboard>

293

Annexes

<Storyboard> <DoubleAnimation x:Name="hourAnimation" Storyboard.TargetName="hourHandTransform" Storyboard.TargetProperty="Angle" From="180" To="540" Duration="12:0:0" RepeatBehavior="Forever"/> <DoubleAnimation x:Name="minuteAnimation" Storyboard.TargetName="minuteHandTransform" Storyboard.TargetProperty="Angle" From="180" To="540" Duration="1:0:0" RepeatBehavior="Forever"/> <DoubleAnimation x:Name="secondAnimation" Storyboard.TargetName="secondHandTransform" Storyboard.TargetProperty="Angle" From="180" To="540" Duration="0:1:0" RepeatBehavior="Forever"/> <DoubleAnimation Storyboard.TargetName="parentCanvas" Storyboard.TargetProperty="Opacity" From="0" To="0.7" Duration="0:0:4"/> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger> </Canvas.Triggers>

Une horloge est galement caractrise par une aiguille pour les heures, les minutes et les secondes. Les animations pour ces lments sont cres dans le storyboard :
<!-- Hour hand --> <Path Data="M -4, 16 l 3 40 3 0 2 -40 z" Fill="white"> <Path.RenderTransform> <TransformGroup> <RotateTransform x:Name="hourHandTransform" Angle="180"/> <TranslateTransform X="150.5" Y="145"/> </TransformGroup> </Path.RenderTransform> </Path> <!-- Minute hand --> <Path Data="M -4, 16 l 3 70 3 0 2 -70 z" Fill="white"> <Path.RenderTransform> <TransformGroup> <RotateTransform x:Name="minuteHandTransform"

294

Silverlight et les langages dynamiques

Angle="180"/> <TranslateTransform X="150.5" Y="145"/> </TransformGroup> </Path.RenderTransform> </Path> <!-- Second hand --> <Path Data="M -1, 16 l 0 70 2 0 0 -70 z" Fill="red"> <Path.RenderTransform> <TransformGroup> <RotateTransform x:Name="secondHandTransform" Angle="180"/> <TranslateTransform X="150.5" Y="145"/> </TransformGroup> </Path.RenderTransform> </Path>

Ensuite, il faut donner un dcor notre horloge (la face, une petite ombre, etc.) :
<!-- Drop shadow --> <Path Data="M 157, 5 a 150,150 0 1,0 1,0 z"> <Path.Fill> <SolidColorBrush Color="Black" Opacity="0.3"/> </Path.Fill> </Path> <!-- Clock bezel --> <Path Data="M 150, 0 a 150,150 0 1,0 1,0 z" Fill="black" /> <Path Data="M 150, 1 a 149,149 0 1,0 1,0 z" > <Path.Fill> <LinearGradientBrush> <LinearGradientBrush.GradientStops> <GradientStopCollection> <GradientStop Color="silver" Offset="0.05"/> <GradientStop Color="#333333" Offset="0.95"/> </GradientStopCollection> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Path.Fill> </Path> <Path Data="M 150, 15 a 135,135 0 1,0 1,0 z" Fill="black" Opacity="1"/> <Path Data="M 150, 16 a 134,134 0 1,0 1,0 z" Opacity="1"> <Path.Fill> <LinearGradientBrush> <LinearGradientBrush.GradientStops>

295

Annexes

<GradientStopCollection> <GradientStop Color="#333333" Offset="0.05"/> <GradientStop Color="silver" Offset="0.95"/> </GradientStopCollection> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Path.Fill> </Path> <!-- Clock face --> <Path Data="M 150, 23 a 127,127 0 1,0 1,0 z" Fill="black" Opacity="1"/>

Il ne reste plus qu ajouter un peu de code Python, qui ira chercher la date actuelle et placer les aiguilles en consquence :
from System.Windows import Application from System.Windows.Controls import Canvas from datetime import datetime class Clock: def __init__(self): self.scene = Application.Current.LoadRootVisual(Canvas(), "app.xaml") def fromAngle(self, time, divisor = 5, offset = 0): return ((time / (12.0 * divisor)) * 360) + offset + 180 def toAngle(self, time): return self.fromAngle(time) + 360 def start(self): d = datetime.now() self.scene.hourAnimation.From = self.fromAngle(d.hour, 1, d.minute/2) self.scene.hourAnimation.To = self.toAngle(d.hour) self.scene.minuteAnimation.From = self.fromAngle(d.minute) self.scene.minuteAnimation.To = self.toAngle(d.minute) self.scene.secondAnimation.From = self.fromAngle(d.second) self.scene.secondAnimation.To = self.toAngle(d.second) Clock().start()

Lhorloge est termine et fonctionnelle.

296

Silverlight et les langages dynamiques

Silverlight et IronRuby
Ruby fait galement partie des langages que supporte la DLR. Il est trs apprci de la communaut des dveloppeurs pour sa facilit et les nombreux paradigmes quil permet de dvelopper (fonctionnel, objet, etc.). Pour la cration dune application Ruby et Silverlight, cest le mme principe que pour Pyhton (IronPython) :
> script/sl ruby testRubyApp

Seule diffrence, il y a trois chiers au niveau du dossier app. Le fonctionnement est pourtant le mme. Le troisime chier ajout (Silverlight.rb) est une classe (SilverlightApplication) qui permet dtablir la liaison avec le chier XAML :
include System::Windows include System::Windows::Controls include System::Windows::Media class SilverlightApplication def application Application.current end def self.use_xaml(options = {}) options = {:type => UserControl, :name => "app"}.merge(options) Application.current.load_root_visual(options[:type].new, "#{options[:name]}.xaml") end def root application.root_visual end def method_missing(m) root.send(m) end end class FrameworkElement def method_missing(m) find_name(m.to_s.to_clr_string) end end

297

Annexes

Cette classe sera toujours la mme et vous ne devrez probablement jamais rien changer lintrieur. Le plus important se trouve dans le chier app.rb.

Une horloge en IronRuby et Silverlight


Il est assez facile dimaginer que le code XAML ne changera pas par rapport lapplication avec IronPyhton. Nous nallons donc pas tout ressaisir ici. La seule chose qui change, cest le code attach au XAML. Nous devons dterminer lheure actuelle et placer les aiguilles au bon endroit :
require Silverlight class Clock < SilverlightApplication use_xaml :type => Canvas def start d = Time.now root.hour_animation.from = from_angle d.hour, 1, d.minute/2 root.hour_animation.to = to_angle d.hour root.minute_animation.from = from_angle d.minute root.minute_animation.to = to_angle d.minute root.second_animation.from = from_angle d.second root.second_animation.to = to_angle d.second end def from_angle(time, divisor = 5, offset = 0) ((time / (12.0 * divisor)) * 360) + offset + 180 end def to_angle(time) from_angle(time) + 360 end end Clock.new.start

Lapplication est termine.

298

Introduction au C#

c Fig. 7.1 : Notre application

Check-list
Nous avons tudi dans cette annexe :
j j j

Siverlight et les langages dynamiques ; IronPyhton ; IronRuby.

7.2 Introduction au C#
Le C# est un langage de programmation typage fort et orient objet. Cela sous-entend :
j

Typage fort. Chaque variable doit tre dnie et respecte le type de sa dnition. Une variable dclare comme nombre entier restera un nombre entier tout au long de sa porte et ne pourra utiliser que les mthodes soit appartenant au type nombre entier soit utilisant le type nombre entier. Orient objet. Il est possible de dnir de nouveaux types nomms classes. Une classe est une structure de donnes pouvant contenir des fonctions.

Il existe donc deux sortes de types en C#, les types primitifs (nombre entier, nombre rel, chane de caractres, etc.) et les types de classe. Une variable instancie comme tant de type classe porte le nom dobjet.

299

Annexes

Dclaration dune variable de type primitif


Pour dclarer une variable de type primitif, il suffit den crire son type suivi de son nom et ventuellement sa valeur initiale. Chaque ligne de code suivante est une dclaration de variable valable :
Dclarartion de variables de type primitif
int nombre ; string teXte ; int nombre2 = 4 ; double nombreRel = 3.4 ; string TexTePasVide = " TextePasVide " ;

Un type primitif commence toujours par une minuscule. Si vous rencontrez un type commenant par une majuscule, cest quil sagit dun type de classe.

Rgles de nommage
Le nom des variables :
j j j

Commence par une lettre ou un caractre de soulignement. Indique clairement son contenu. Peut contenir invariablement des minuscules, majuscules, des chiffres et des caractres de soulignement. Attention, le C# considre comme diffrentes deux variables du mme nom dont seule la case change. (VaRiable1 et Variable1 ne sont pas les mmes variables.)

La convention de choix du nom de variable la plus courante est le CamelCase du nom anglais des chameaux. Tels les bosses dun chameau, chaque nouveau mot dans le nom dune variable commence par une majuscule. Cette convention simplie grandement la lecture. Comparez votre guise ces deux versions du mme nom :
j j

lavariablequivameservirdanslaboucledemonapplicationpourcalculerlatvasurmonsalaire ; LaVariableQuiVaMeServirDansLaBoucleDeMonApplicationPourCalculerLaTvaSurMonSalaire.

Il est vident quun nom de variable si long est aberrant et ne se retrouvera jamais dans un programme.

300

Introduction au C#

Dclaration dune variable de type de classe


Le mot-cl new suivi du nom dune classe permet de dclarer une nouvelle variable de type de classe. De nombreuses classes sont fournies par la plateforme C#. Les dclarations de classes suivantes sont correctes :
declaration de variable de Type de classe
Int32 nombre = new Int32(); String s = new String(); String ChaineVide;

Attention, dans le cas de la variable de nom ChaineVide, seule la dclaration du nom de la variable t assigne, mais aucune zone mmoire na t alloue via le mot-cl new. On dit de la variable ChaineVide quelle est null.

Fonctionnement par rfrence des types de classe


Les variables de type de classe ne dsignent pas uniquement une zone mmoire dans laquelle vous pouvez enregistrer des donnes. Il sagit de pointeur. Un nom de variable pointe une zone mmoire initialise par le mot-cl new. Il est donc possible de changer la zone mmoire que pointe un nom de variable. Ainsi dans le code qui suit, nombre1 va dabord pointer la zone mmoire dnie en ligne 1. Une fois la ligne 3, nombre1 pointera la zone mmoire dnie en ligne 2, comme nombre2 :
Zone mmoire et nom de variables
1 2 3 Int32 nombre1 = new Int32() ; Int32 nombre2 = new Int32() ; nombre1 = nombre2 ;

Ce qui est vrai pour les types de classe ne lest pas pour les types primitifs. Un type primitif reprsente directement sa zone mmoire. Le mme exemple en type primitif reviendrait copier le contenu de la zone mmoire de nombre2 dans la zone mmoire de nombre1. Revenons nos types de classe. Quest-il advenu de la zone mmoire dnie en ligne 1 ?

301

Annexes

La rponse est simple : elle nexiste plus. Lorsquune zone mmoire nest plus pointe par aucun nom de variable, cette zone mmoire est recycle par le ramasseur de poubelle de la plateforme .NET.

Porte des variables


La porte de vie dune variable est limite par les accolades qui entourent le bloc de code dans laquelle elle a t dclare :
Porte des variables
1 2 3 4 5 6 7 8 9 10 11 { int nombre1 = 3 ; String chaine = new String() ; { String chaine = new String() ; int nombre2 = 4 + nombre1; } { int nombre2 = 5; } }

Dans cet exemple :


j j

La variable nombre1 est accessible de la ligne 2 la ligne 10. La variable chane dnie en ligne 3 est accessible : - la ligne 3 ; - de la ligne 7 la ligne 10.

En effet, la variable chane dclare en ligne 5, dans un autre bloc de code, prvaut dans son bloc sur la variable chane dclare en ligne 3. Cependant, en ligne 5, il est possible dutiliser la variable nombre1 dnie en ligne 2, car aucune autre variable du nom nombre1 na t dnie dans le blog de la ligne 4 la ligne 7. De la mme faon, les variables nombre2 en ligne 6 et nombre2 en ligne 9 sont deux variables diffrentes. Chaque variable est recycle par le ramasseur de poubelle la n de son bloc ; la variable nombre2 de la ligne 6 cesse donc dexister en ligne 7.

302

Introduction au C#

Utilisation des proprits de classe


Les classes dnissent des objets pouvant contenir une multitude de donnes. Par exemple, la classe Point dnit un objet contenant un double X et un double Y. Pour accder ces sous-variables, nommes proprits, il suffit de faire suivre le nom de la variable dun point et du nom de la proprit :
accs aux proprits de classe
Point p = new Point() ; p.X = 3.0 ; p.Y = 4.0;

Utilisation des mthodes de classe


Une mthode est une fonction remplissant un certain usage. Les classes dnissent des objets pouvant contenir des donnes mais aussi des mthodes. Excuter la mthode dun objet seffectue en faisant suivre le nom de cet objet par un point, le nom de la mthode et deux parenthses, une ouvrante et une fermante :
accs aux methodes de classe
Int32 nombre = new Int32() ; String s = nombre.ToString() ;

Dans cet exemple, la mthode ToString de la variable nombre est appele. Cette mthode convertit la variable en une chane de caractres qui sera ensuite assigne la variable s.

Structure dun programme C# (Partie 1)


Un programme C# dbute toujours par limportation des librairies ncessaires lexcution de ce programme. Il y a toujours des librairies ncessaires. Par exemple, il serait difficile de se passer de la librairie System contenant les types primitifs. Le mot-cl permettant limportation dune librairie est using ; il est suivi du nom de la librairie voulue.

303

Annexes

Exemple de using
using Sytem; using Sytem.Net;

Ce qui suit est un namespace. Un namespace ou espace de noms est une sorte denclos dnissant une famille. Si dans la famille Boigelot, le nom de Simon signie un des auteurs de ce Livre, dans la famille Bible, Simon dnit un aptre. Il en va de mme pour les espaces de noms. Ensuite vient une dnition de classe car en C#, tout est objet.

Dnir un type de classe


Lavantage rel de la programmation oriente objet napparat que lorsque lon commence dnir nos propres classes. Pour rappel, une classe est la dnition dune structure contenant des proprits et des mthodes. Cette classe sera instancie par le mot-cl new pour crer des objets (zone mmoire) points par des noms de variables. Dans lautre sens, les noms de variables sont des pointeurs de zone mmoire (objets) respectant une dnition contenue dans leur type de classe. Crer une nouvelle classe se fait grce au mot-cl class. Toute variable dnie dans cette classe dnit en fait une proprit de la classe. Si nous dsirons crer une classe reprsentant des personnes et ayant comme proprit un nom et un age, voici ce que la dnition de class donne :
Dnition de la classe Personne (version 1)
class Personne { public string Nom ; public int Age ; }

304

Introduction au C#

Le mot-cl public devant chaque proprit signie quon peut accder cette proprit par lextrieur de la classe. Ainsi il est possible dcrire :
Dclaration dun objet de classe Personne
Personne p = new Personne(); p.Nom = " Simon pas moi mais laptre "; p.age = 2000;

Dnir une nouvelle mthode


Une mthode est reprsente par son nom, son type de retour et ses paramtres :
j j j

Son nom doit respecter les mmes rgles que ceux des variables. Son type de retour est le type de rsultat de la mthode, par exemple pour la mthode Add additionnant deux nombres entiers, le type de retour sera un nombre entier. Ses paramtres, pour la mme mthode Add, les paramtres de la mthode seront les deux nombres entiers additionner.

Cette mthode scrit :


Mthode Add
int Add(int nombre1, int nombre2) { return nombre1 + nombre2 ; }

Le mot-cl return est suivi du rsultat de la mthode. En effet, une mthode peut tre longue et demander de nombreuse lignes de code. Ce mot-cl stipule la plateforme le rsultat retourner. Utiliser cette mthode savre aussi simple mais les types de variables des paramtres doivent tre respects sous peine dobtenir une erreur.
Utilisation de la mthode Add
int ArgentEnPoche = 5 ; int ArgentEnChausette = 1 ; int ArgentTotal = Add(ArgentEnPoche,ArgentEnChausette) ;

305

Annexes

Ajouter une mthode une classe


Pour ajouter une mthode une classe, il suffit de dnir cette mthode lintrieur de cette classe. Par exemple, nous pouvons ajouter la mthode Add la classe Personne :
Dnition de la classe Personne (version 2)
class Personne { public string Nom ; public int Age ; public int Add(int nombre1, int nombre2) { return nombre1 + nombre2 ; } }

Cette mthode est elle aussi prcde du mot-cl public pour y accder depuis lextrieur de la classe. Il est maintenant possible dcrire :
Utilisation dune mthode de classe.
Personne p = new Personne(); int somme = p.Add(342,453);

Structure dun programme C# (Partie 2)


Pour en revenir la structure dun programme, nous avions vu les using, le namespace et nous tions bloqus sur la dnition dune classe. Dans cette annexe, nous nous contenterons de crer des programmes sexcutant dans une console dos. La classe de base dun programme sexcutant dans une console dos est simplement la class Program. Son code est :
Code dune application dos
using System; using System.Collections.Generic;

306

Introduction au C#

using System.Linq; using System.Text; namespace AnnexeConsoleApplication { class Program { static void Main(string[] args) { } } }

La classe Program contient une mthode de base, cette mthode est la mthode Main, cest elle qui sera appele par la plateforme au dmarrage du programme. Elle est prcde du mot-cl static. Ce dernier stipule que cette mthode nest dnie quune fois travers toutes les variables. Il est possible daccder aux mthodes et proprits static sans initialiser de variable. Cela se fait en crivant le nom de la classe suivi dun point et du nom de la proprit ou de la mthode. Ainsi, le code de la plateforme excutant tout programme console est :
code de la plateforme excutant tout programme console
Program.Main(paramtes) ;

Exemple dune application de gestion de donnes


Nous allons crire pas pas une application de gestion de donnes en mode Console. Notre premire tche consiste crer lapplication elle-mme :
Application de Gestion de donnes vide
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace GestionDeDonnees { class Program

307

Annexes

{ static void Main(string[] args) { } } }

Nous devons ensuite dnir les donnes que nous allons grer. Un bon exemple serait de grer une bibliothque. Les diffrentes classes que nous retrouvons dans une application de gestion de bibliothques sont :
j j j

la bibliothque elle-mme ; des livres ; des clients.

Les diffrentes actions se droulant dans une bibliothque sont :


j j

Un client emprunte un livre pour une certaine dure et paie un certain prix. Un client rapporte un livre.

Comme il faut bien commencer, dnissons la classe Livre :


Livre.cs
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace GestionDeDonnees { public class Livre { public string Titre; public string Auteur; public DateTime Echeance; public int NombreDePage; public int Prix; } }

Rien que nous nayons vu jusqu prsent. Passons la classe Bibliothque :

308

Introduction au C#

Les listes gnriques


Bibliothque.cs
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace GestionDeDonnees { public class Bibliotheque { public List<Livre> LivreEnMagasin = new List<Livre>(); public List<Client> Clientelle = new List<Client>(); } }

Dans ce cas, la liste attire sans doute votre regard. En C#, il est possible de dclarer une proprit comme tant une liste dobjets. Cette liste na pas de taille. Pour y ajouter un objet, il suffit den appeler la mthode Add(Objet o). Ainsi pour ajouter un Livre la liste LivreEnMagasin, vous utiliserez le code :
Liste.Add
Livre MonLivre = new Livre() ; Bibliothque.LivreEnMagasin.Add(MonLivre) ;

Pour atteindre un livre dans une liste, on peut utiliser son index, sa position dans la liste :
Utilisation des index dans une liste
Livre MonLivre = Bibliothque.LivreEnMagasin[4]

Retirer un livre de la liste se fait grce la mthode Remove :


Utilisation de List Remove
Livre.MonLive = Bibliothque.LivreEnMagasin[4] Bibliothque.LivreEnMagasin.Remove(MonLivre)

309

Annexes

Ce code donnera le mme rsultat avec la mthode RemoveAt(Positon) :


Utilisation de List.RemoveAt
Bibliothque.LivreEnMagasin.RemoveAt(4);

Il en va de mme pour la classe Client :


Client.cs
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace GestionDeDonnees { public class Client { public string Nom; public List<Livre> LivesEnEmprunt = new List<Livre>(); } }

Cration des mthode Emprunte et Rend


Exemple dutilisation des diffrentes classesExemple dutilisation des diffrentes classes
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace GestionDeDonnees { class Program { private Bibliotheque bibli = new Bibliotheque(); static void Main(string[] args) { }

310

Webographie

public void Emprunte(Client client, Livre livre) { bibli.LivreEnMagasin.Remove(livre); client.LivesEnEmprunt.Add(livre); } public void Rend(Client client, Livre livre) { client.LivesEnEmprunt.Remove(livre); bibli.LivreEnMagasin.Add(livre); } } }

Conclusion
Le C# est un langage trs structurant. Dans les nombreuses librairies offertes par la plateforme .NET se trouvent par milliers des dnitions de classe, les proprits et leurs mthodes. Ces mthodes, empiles couches sur couches, ont ajout une couche dabstraction par rapport au langage machine et aux autres langages de premire et deuxime gnration. Des mthodes telles que Mail.Send(Email mail) ou monPlayerVideo.PlayVideo (maVideo) forment la nourriture journalire du dveloppeur C#.

Check-list
Dans cette annexe, nous avons appris les rudiments de la programmation C#, et travers elle, les rudiments de la programmation oriente objet. Nous esprons que cette annexe aidera celles et ceux dentre vous qui dbutent plein de courage dans ce monde merveilleux de la programmation. Mais noubliez jamais quInternet est votre ami. De nombreux tutoriaux sont disponibles sur le sujet pour toutes personnes dsireuses den apprendre plus.

7.3 Webographie
Ce livre naura pas fait de vous un expert. Vous possdez toutes les bases ncessaires pour crer de trs bonnes applications Silverlight. Mais malheureusement, de Silverlight dcoule un grand nombre dautres technologies que nous navons pas pu aborder en dtail

311

Annexes

dans cet ouvrage. Cest pour cela que nous allons vous fournir une srie de liens sur diffrents sujets an que vous puissiez approfondir vos connaissances.

Visual Studio 2008


Pour respecter lordre du livre mais surtout lordre logique des choses, il vous faut matriser loutil qui permet la ralisation dapplications Silverlight. En effet, nous navons pas pris le temps dexpliquer chaque fois la cration de tel ou tel autre chier, par manque de place. Vous devez apprendre matriser loutil.

Sources officielles
Le site de Microsoft qui permet dobtenir toute linformation sur Visual Studio :
j

http://www.microsoft.com/france/msdn/vstudio/default.mspx

Une srie de vidos que vous pouvez regarder. Quelques-unes prsentent Visual Studio 2010 qui sera le prochain Visual Studio :
j

http://msdn.microsoft.com/fr-fr/vstudio/msdn.5minutes.pour.comprendre.visualstudio.aspx

Le site de la version gratuite de Visual Studio :


j

http://www.microsoft.com/Express/

Le portail des dveloppeurs ddi Visual Studio. Dcouvrez-y tout ce que voulez savoir sur Visual Studio 2008 :
j

http://msdn.microsoft.com/en-us/vstudio/default.aspx

Silverlight
Silverlight est le sujet de ce livre. Nous avons abord de nombreux thmes mais peut-tre reste-t-il des pistes explorer. Dans tous les cas, il est intressant de se tenir inform pour un ventuel Silverlight 3 ou la sortie de Silverlight pour application mobile

Sources officielles
Le site officiel de Silverlight. Vous y trouverez des actualits, des dmonstrations, etc. visiter quotidiennement :
j

http://silverlight.net/

312

Webographie

Le site officiel de Silverlight pour les dveloppeurs :


j

http://msdn.microsoft.com/fr-fr/silverlight/default.aspx

Communauts
Pour vous tenir informer des dernires nouveauts de Silverlight en franais :
j

http://www.silverlight-info.fr/

Le blog de Guillaume, un blogueur suivre sur le sujet Silverlight et RIA :


j

http://blogs.codes-sources.com/guillaume/default.aspx

Le blog de Christophe Lauer est un bon blog pour se tenir inform sur lactualit autour de Microsoft, dont celle de Silverlight :
j

http://blogs.msdn.com/clauer/default.aspx

Le blog de Scott Guthrie est un incontournable pour ceux qui voudraient tre au courant de tout la premire minute. Des exemples complets sur les dernires technologies :
j

http://weblogs.asp.net/scottgu/archive/2007/05/07/silverlight.aspx

Le blog de Jesse Liberty est un blog sur un fan de Silverlight :


j

http://silverlight.net/blogs/jesseliberty/

On ne saurait les lister tous tellement il y a dinformation. Utilisez Google pour davantage de liens.

Le Framework .NET
Voici la dernire et plus grande partie explorer. Le Framework .NET est un ensemble de technologies qui permettent aussi bien de crer des applications Silverlight, que web ou encore mobile en passant par des applications Desktop. Un trs grand nombre de produits gravitent autour de cette technologie qui ne cesse de samliorer danne en anne.

Sources officielles
Source officielle de Framework .NET de Microsoft :
j

http://www.microsoft.com/NET/

313

Annexes

La communaut officielle des dveloppeurs utilisant les technologies .NET :


j

http://www.msdn.com

Communauts
Trs importante communaut autour du .NET. Vous y dcouvrirez un forum, de lactualit et un grand nombre darticles :
j

http://dotnet.developpez.com/

Codes-Sources est la communaut par dfaut o tous les dveloppeurs .NET se rencontrent. Ce site rpertorie les derniers postes de blog de la communaut :
j

http://blogs.codes-sources.com/

Comme son nom lindique, vous trouverez normment de code tlcharger sur ce site :
j

http://www.codes-sources.com

Le blog de Loc Bar sur toutes les technologies Microsoft :


j

http://blogs.codes-sources.com/loicbar/

Le blog de Simon Boigelot. Le laboratoire dun vrai dveloppeur :


j

http://www.simonboigelot.com/

Voil qui nous a permis de faire le tour des sites avec lesquels il faut entretenir un contact. Bien entendu, au fur et mesure de vos visites, vous en dcouvrirez dautres.

314

INDEX

A
ActualHeight ............................................................................................... 243 ActualWith .................................................................................................. 243 ADO.NET ................................................................................................... 143 Adobe ........................................................................................................... 98 Animations .................................................................................................... 88 Apache ........................................................................................................ 184 ASMX ........................................................................................................ 135 Asp TreeView ................................................................................................... 195 ASP.NET ............................................................................................... 97, 182 MemberShip Provider ............................................................................... 197 Assembly .................................................................................................... 225 Auto .............................................................................................................. 33 AutoGeneratedColumn ................................................................ 253, 256, 264 AutoReverse .................................................................................................. 82

B
Background ................................................................................................... 74 BeginInvoke ................................................................................................ 242 BeginTime .................................................................................................... 82 Binding ......................................................................................................... 55 Border ........................................................................................................... 33 BorderColor .................................................................................................. 74 Brush ............................................................................................................ 73 Brushes ......................................................................................................... 73

C
Calendar .............................................................................................. 247, 249 CallBack ..................................................................................................... 146 Canvas .......................................................................................................... 31

316

INDEX

CellEditingTemplate .................................................................................... 264 Center ........................................................................................................... 77 CheckBox ................................................................................................ 42-43 Checked ................................................................................................ 43 45 Clic ......................................................................................................... 39, 54 CodePlex ..................................................................................................... 269 Collapsed .................................................................................................... 244 ColumnDenition .......................................................................................... 28 ComboBox .................................................................................................... 49 ComboBoxItem ............................................................................................. 49 CompareValidator ........................................................................................ 193 Content ................................................................................................... 40, 45 ContentPresenter ......................................................................................... 224 ControlTemplate ................................................................................... 222-223 Convert ......................................................................................................... 67 ConvertBack ................................................................................................. 67 CornerRadius ................................................................................................ 35 CustomValidator .......................................................................................... 193

D
Data ............................................................................................................ 230 DataBinding .................................................................................. 55, 214, 217 DataContext .......................................................................... 148, 216-217, 235 DataGrid ..................................................................................... 253, 255, 264 DataGridCheckBoxColumn .................................................................. 255, 257 DataGridTemplateColumn ................................................................... 255, 257 DataGridTextColumn ................................................................................... 255 DataReader .................................................................................................. 119 DataTemplate .............................................................................................. 255 DataTemplates ............................................................................................... 61 DatePicker ........................................................................................... 249, 263 DateTime .................................................................................................... 249 Decade ........................................................................................................ 248 Deepzoom ............................................................................................ 273-274
317

INDEX

Default.aspx ................................................................................................ 184 Default.aspx.cs ............................................................................................ 184 Dgrad ........................................................................................................ 76 DELETE ..................................................................................................... 116 DependencyProperties ................................................................................. 228 Disabled ........................................................................................................ 33 Dispatcher ................................................................................................... 242 DisplayDate .......................................................................................... 248-249 DisplayDateEnd .................................................................................... 248-249 DisplayDateStart ................................................................................... 248-249 DisplayMode ............................................................................................... 248 Document ...................................................................................................... 24 DOM ........................................................................................................... 210 DoubleAnimationUsingKeyFrame ................................................................. 82 Duration ........................................................................................................ 82 DynamicResource ......................................................................................... 65

E
lment ......................................................................................................... 24 EndPoint ....................................................................................................... 76 vnements ................................................................................................... 38 Expression Blend .......................................................................................................... 97 Design ........................................................................................................ 99 Encoder 2 ................................................................................................ 102 Media 2 ..................................................................................................... 98 Studio ......................................................................................................... 98 Web ............................................................................................................ 97

F
Flash/Flex ................................................................................................... 107 Foreground .................................................................................................... 74

318

INDEX

Forever ......................................................................................................... 82 Form ........................................................................................................... 185 FROM ......................................................................................................... 116 FullScreen ................................................................................................... 243 FullScreenChanged ...................................................................................... 243

G
Generic.XAML ............................................................................................. 72 GradientOrigin .............................................................................................. 77 Gradients ....................................................................................................... 73 Grid .............................................................................................................. 26 GridSplitter ................................................................................................. 251 GridView ............................................................................................. 188, 193 GroupName ................................................................................................... 45

H
Hackers ....................................................................................................... 117 Hidden .......................................................................................................... 33 HorizontalScrollBarVisibility ......................................................................... 33 HTML ......................................................................................................... 210

I
Illustrator ...................................................................................................... 98 ImageBrush ................................................................................................... 78 Images .......................................................................................................... 35 INSERT ....................................................................................................... 116 IronPyhton .................................................................................................. 292 IronRuby .............................................................................................. 297-298 IsChecked .......................................................................................... 42-43, 45 IsCheked ....................................................................................................... 45 IsFullScreen ................................................................................................ 242

319

INDEX

IsOpen .......................................................................................................... 54 IsSelectedChanged ....................................................................................... 252 IsThreeState ....................................................................................... 42, 44-45 ItemPanel ...................................................................................................... 72 ItemSource .................................................................................................... 62 ItemsSource ................................................................................................. 262 ItemTemplate ................................................................................................ 61 IValueConverter ............................................................................................ 67

K
Key ............................................................................................................... 64 KeyDown ...................................................................................................... 40 KeyUp .......................................................................................................... 40

L
Label ........................................................................................................... 188 LargeChange ................................................................................................. 51 Layout ........................................................................................................... 26 Line .............................................................................................................. 51 LinearGradientBrush ..................................................................................... 74 LINQ ................................................................................................... 113, 126 to Entities ................................................................................................. 134 to Object .................................................................................................. 126 to XML ..................................................................................................... 129 ListBox ................................................................................................... 47, 72 ListBoxItem .................................................................................................. 47 Live Encoding ............................................................................................. 103 Login .......................................................................................................... 196 LostFocus .................................................................................................... 218

320

INDEX

M
Margin .......................................................................................................... 35 Maximum ............................................................................................... 37, 51 MediaElement ............................................................................................. 237 MediaPlayer ................................................................................................ 201 MemberShip Provider ................................................................................. 197 Microsoft.Windows.Controls.Data ................................................................ 255 Minimum ................................................................................................ 37, 51 Mode ........................................................................................................... 218 Mounth ....................................................................................................... 248 MouseEnter ............................................................................................. 40, 90 MouseLeave .................................................................................................. 40 MouseLeftButtonClic .................................................................................... 80 MouseLeftButtonDown ................................................................................. 40 MouseLeftButtonUp ...................................................................................... 40 MouseMouve ................................................................................................ 90 MouseMove .................................................................................................. 40 MultiScaleImage .................................................................................. 279, 289 MySQL ....................................................................................................... 124 MySqlConnection ........................................................................................ 125 MySqlDataReader ....................................................................................... 125

N
Name ............................................................................................................ 38 Namespace .................................................................................................. 225

O
Objects LINQ ........................................................................................................ 126 Timeline .................................................................................................... 106 ObjectDataSource ........................................................................................ 193

321

INDEX

ODP.NET .................................................................................................... 120 OneWay ...................................................................................................... 218 Oracle ......................................................................................................... 120 OracleConnection ........................................................................................ 121 OracleDataReader ........................................................................................ 122 Orientation .................................................................................................... 31

P
Password ....................................................................................................... 47 PasswordBox ................................................................................................. 47 PasswordChar ............................................................................................... 47 Path ............................................................................................................. 230 Pause ........................................................................................................... 239 Photoshop ..................................................................................................... 98 Plateforme.NET ........................................................................................... 181 Play ............................................................................................................. 239 Plein cran .................................................................................................. 242 Popup ....................................................................................................... 53-54 Postback ...................................................................................................... 197 ProgressBar ................................................................................................... 37 Property ...................................................................................................... 222 PropertyMetadata ........................................................................................ 229 Provider ...................................................................................................... 127 Python ......................................................................................................... 292

R
RadialGradientBrush ..................................................................................... 76 RadioButton .................................................................................................. 45 RadiusX ........................................................................................................ 52 RadiusY ........................................................................................................ 52 RangeValidator ............................................................................................ 192 RatioValueConverter ...................................................................................... 70

322

INDEX

Rectangle ...................................................................................................... 52 Register ....................................................................................................... 229 RegularExpressionValidator ......................................................................... 193 RepeatBehavior ............................................................................................. 82 Repeater .............................................................................................. 188, 194 RequiredFieldValidator ................................................................................ 192 Ressources .................................................................................................... 64 RIA ............................................................................................................... 98 RowDenition ............................................................................................... 28 RSS ..................................................................................................... 170, 174 Ruby ........................................................................................................... 292

S
ScrollViewer ................................................................................................. 32 SELECT ...................................................................................................... 116 SelectedDate ............................................................................................... 249 SelectedDateChanged .................................................................................. 249 SelectedItemChanged ............................................................................... 49-50 SelectionChanged ........................................................................................ 252 SGBD ......................................................................................................... 114 Silverlight ..................................................................................... 97, 201, 207 3 ............................................................................................................... 312 pour application mobile ........................................................................... 312 Slider ............................................................................................................ 51 SmallChange ................................................................................................. 51 Soap ............................................................................................................ 162 Source ......................................................................................................... 241 SQL ...................................................................................................... 115-116 SQL Server ................................................................................................. 114 SQLDataSource ........................................................................................... 193 StackPanel .................................................................................................... 30 StartPoint ...................................................................................................... 76 StaticResource ............................................................................................... 65 Stoke ............................................................................................................. 74
323

INDEX

StoryBoard .................................................................................................... 79 StoryBoard.TagetName .................................................................................. 82 StoryBoard.TargetProperty ............................................................................. 82 Style ............................................................................................................ 220 System.Windows.Controls ........................................................................... 246 System.Windows.Controls.Data ................................................................... 253

T
TabControl .................................................................................................. 252 TabItem ....................................................................................................... 252 TargetType .................................................................................................. 222 Template ....................................................................................... 61, 223, 264 TemplateBinding ................................................................................. 223, 230 Text .......................................................................................................... 46-47 TextBlock ...................................................................................................... 36 TextBox ........................................................................................................ 46 TextChanged ................................................................................................. 46 TextWrapping ................................................................................................ 37 ToggleButton ................................................................................................. 43 ToString ........................................................................................................ 60 TreeView ..................................................................................................... 195 TwoWay ...................................................................................................... 218

U
UnChecked ........................................................................................... 43 45 UPDATE ..................................................................................................... 116 URI ............................................................................................................... 35

V
Value ....................................................................................................... 37, 51 ValueChanged ............................................................................................... 51

324

INDEX

ValueConverter ........................................................................................ 66, 70 VerticalScrollBarVisibility ............................................................................. 33 ViewState .................................................................................................... 197 Virtual Earth ............................................................................................... 288 Visible ................................................................................................... 33, 244 Visual Source Safe ...................................................................................... 109 Visual Studio 2008 .............................................................................. 109, 183

W
WCF ........................................................................................................... 135 WeatherBugWebServiceSoapClient .............................................................. 162 Web.cong .................................................................................................. 190 Webographie ................................................................................................ 311 Widget ........................................................................................................ 153 Width ............................................................................................................ 29 Wrap ............................................................................................................. 37 WrapPanel ..................................................................................................... 31

X
XAML ..................................................................................................... 23-24 XML ............................................................................................................. 24 LINQ ........................................................................................................ 129 XMLDataSource ......................................................................................... 193

Y
Year ............................................................................................................ 248

325

Notes

Notes

Notes

Notes

Notes

Notes

Notes

Notes

Notes

Notes

Compos en France par Jouve 11, bd de Sbastopol - 75001 Paris

You might also like