Dot.Blog

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

La mer, les propriétés de dépendance et les user control's...

La mer... un souvenir qui va s'effacer jusqu'à l'année prochaine... Mais pour prolonger le plaisir nous avons Silverlight !

Et comment mieux rendre grâce à la Grande Bleue qu'en fabriquant un User Control la mettant en scène ? Et bien c'est ce que nous allons faire, ce qui permettra ludiquement d'aborder un problème épineux concernant les propriétés de dépendance sous Silverlight. Mais d'abord le visuel :

[silverlight:source=/SLSamples/LaMer/LaMer.xap;width=480;height=480]

La mer bleue, ou la mer rouge, au choix... et c'est bien ce choix qui va poser problème.

La base du UserControl 

Concernant le composant lui-même je suis parti d'un UserControl vide créé pour l'occasion. A l'intérieur un Path dessiné avec l'outil plume. Ce path est dupliqué deux fois (ce qui donne donc 3 exemplaires au final). Les deux copies sont modifiées : l'une tassée en largeur, l'autre agrandie sur le même axe.

Un StoryBoard complète le tout : les trois vagues sont déplacées de gauche à droite, l'animation est mise en mode Auto-Reverse et boucle infinie. Pour un mouvement plus doux en début et fin j'ai ajouté un ease in/out choisi parmi les nouveaux modes offerts par SL 3.

Le tout est englobé dans une grid pour bénéficier du clipping, le layout root étant une ViewBox, mais cette partie là de la cuisine interne du composant n'est pas forcément la plus subtile. Pour terminer j'ajoute un rectangle sans bordure qui est placé en mode Stretch au fond du Z-Order, il servira a définir un éventuel background.

Jusqu'à là rien de bien compliqué, juste un peu d'imagination est suffisant.

Là où ça se complique c'est lorsqu'il faut gérer la couleur des vagues et celle du rectangle de fond...

Héritage et propriété de dépendance sous Silverlight

Pour terminer correctement le UserControl il faut en effet penser à son utilisation. C'est à dire à ajouter des propriétés qui permettront à l'utilisateur du contrôle (le développeur ou l'intégrateur sous Blend) de modifier ses caractéristiques sans avoir besoin, bien entendu, de bricoler le source du contrôle lui-même.

Ici, nous souhaitons pouvoir modifier la couleur des vagues et celle du fond. Parfait me direz-vous, cela tombe bien, un UserControl descend de Control qui lui-même définit deux propriétés on ne peut plus à propos : Foreground et Background. Il "suffit" de les surcharger.

En effet, "il suffit de". Yaka.

Première chose, ces propriétés sont dites de dépendance (dependency property). Voir à ce sujet mon article Les propriétés de dépendance et les propriétés jointes sous WPF (article à télécharger). Ces propriétés ne sont pas définies comme ce qu'on nomme aujourd'hui pour les différencier les "propriétés CLR", les propriétés habituelles. Je vous renvoie à l'article cité ici pour creuser la question si vous ne connaissez pas les propriétés de dépendance.

Dès lors, et telles que fonctionnent ces propriétés spécifiques de Silverlight et WPF, pour les surcharger il faut passer par un système de métadonnées autorisant l'affectation d'une méthode callback. Dans cette dernière il est facile de répercuter sur le visuel les changements de valeur de la propriété. L'override d'une propriété de dépendance est donc assez simple. Sous WPF. Et c'est là qu'est le problème.

En effet, tout à l'air tellement merveilleux sous Silverlight depuis la version 2 qui accèpte du code C#, qu'on en oublie que si tout le Framework .NET pouvait tenir dans quelques méga octets on se demanderait bien pourquoi l'installation du dit Framework pour une application classique (desktop) réclame des dizaines et des dizaines de méga octets... Y'a un truc. Y'a même une grosse astuce je dirais : forcément yapatou. En clair, le Framework Silverlight est un découpage chirurgical de haute précision pour donner l'impression que tout fonctionne tout en évitant 90% du code du Framework. Et il y a des petits bouts qui manquent, et parfois des gros !

Concernant les propriétés de dépendance, l'équipe de Silverlight a implémenté le principal mais a laissé de côté les subtilités. Les métadonnées sont par exemple moins sophistiquées. Mais il n'y a pas que les données qui ont été simplifiées, les méthodes aussi. Et de fait, en tout cas pour l'instant, il manque aux propriétés de dépendance Silverlight la possibilité de les surcharger.

Aie ! Comment réutiliser Foreground et Background définies dans Control et accessibles dans le UserControl s'il n'est pas possible de modifier les métadonnées et d'enregistrer notre propre callback ? J'ai longuement cherché car le problème est loin d'être évident à résoudre. Certains préconisent même face à ce problème de redéfinir vos propres propriétés. C'est tellement horrible comme solution que je m'y suis refusé. Comment avoir le courrage de définir une couleur de fond et une couleur d'avant plan au sein d'un composant visuel qui affichera fièrement de toute façon Foreground et Background qui n'auront, hélas, aucun effet ? Quant à faire une réintroduction de ces propriétés (avec le mot clé "new"), n'y pensez pas, j'ai essayé et ça coince un peu (par code ça marche, mais le XAML se fiche de la redéfinition et utilise toujours la propriété originale, ce n'est pas un bug mais une feature ou plutôt un effet assumé du fameux découpage savant dans le Framework).

J'avoue que pour l'instant cet oubli volontaire dans Silverlight me chagrine. Pourquoi l'équipe Silverlight, qui fait la chasse au gaspi un peu partout, s'est amusée à définir ces deux propriétés dans la classe Control si on ne peut pas en hériter, sachant que Control ne sert à rien d'autre qu'à créer des classes héritées  ? C'est assez mystèrieux même si je suppose qu'il s'agit d'un problème de compatibilité avec WPF, Silverlight en faisant moins que son grand frère mais toujours en permettant que cela soit transparent pour le code. Bref, à satisfaire deux besoins opposés, d'un côté en coder le moins possible pour assurer la taille la plus petite au plugin et de l'autre assurer la compatibilité du code avec WPF, on finit par tomber sur des paradoxes de ce genre.

L'Element binding (ajouté dans SL 3) n'est pas utilisable non plus, à moins de donner un nom au UserControl (je veux dire à l'intérieur même de la définition de celui-ci). Ce qui n'est pas acceptable car si l'utilisateur du composant change ce dernier, le binding est cassé. Pire si l'utilisateur tente de placer deux instances sur une fiche, il y aura un conflit de nom. Solution inacceptable donc. J'ai testé, je pense, toutes les combines possibles. Mais j'ai enfin trouvé celle qui fonctionne !

La Solution

La piste de l'Element binding, nouvelle feature de SL 3, n'était pas mauvaise. Le problème c'est qu'en Xaml cela réclamait de pouvoir indiquer le nom de la source (le UserControl) alors même qu'à l'intérieur de la définition de notre contrôle il n'était pas question de lui donner un x:Name figé.

Mais en revanche, ce qui est possible en Xaml l'est tout autant par code (et souvent inversement d'ailleurs). Par chance, la classe permettant de définir un Binding n'utilise pas les noms pour la source ni le destinataire. Elle utilise les noms des propriétés mais là on les connait et ils ne changeront pas. Du coup, en définissant le Binding dans le constructeur (ou plutôt dans le gestionnaire de l'événement Loaded) on peut référencer "this", c'est à dire l'instance du UserControl, sans connaître son nom. On peut donc créer un lien élément à élément entre la propriété Fill des Path's et la propriété Foreground du UserControl (idem pour le Fill du rectangle et la propriété Background du UserControl).

Et ça marche ! Lorsqu'on compile tout ça et qu'on pose un composant "LaMer" sur une fiche on peut modifier la propriété Foreground et les vagues changent de couleur.

 

   1:          public LaMer()
   2:          {
   3:              // Required to initialize variables
   4:              InitializeComponent();
   5:              Loaded += new System.Windows.RoutedEventHandler(LaMer_Loaded);
   6:          }
   7:   
   8:   
   9:          private void LaMer_Loaded(object sender, System.Windows.RoutedEventArgs e)
  10:          {
  11:              // l'astuce est là !
  12:              var b = new Binding("Foreground") { Source = this, Mode = BindingMode.OneWay };
  13:              Vague1.SetBinding(Shape.FillProperty, b);
  14:              Vague2.SetBinding(Shape.FillProperty, b);
  15:              Vague3.SetBinding(Shape.FillProperty, b);
  16:   
  17:              var bb = new Binding("Background") { Source = this, Mode = BindingMode.OneWay };
  18:              rectBackground.SetBinding(Shape.FillProperty, bb);
  19:             
  20:              VaguesAnim.Begin();
  21:          }

Pour le Background on fait pareil avec le rectangle. Mais, allez-vous me dire (si si, vous y auriez pensé, un jour :-) ), pourquoi aller mettre un rectangle pour obtenir une couleur de fond alors même qu'il y a déjà une grille en dessous ? La grille possède aussi une propriété Background. Pourquoi, hein ?

La réponse est simple, j'ai forcément essayé, et ça fait un magnifique plantage avec une erreur dont le message fait peur en plus (du genre "anomalie irrémédiable dans cinq secondes tout va sauter, non ça a déjà sauté!"). Le message d'erreur étant assez peu clair quant aux raisons du plantage j'ai fini par abandonner. Ce qui marche une ligne avant pour la propriété Fill des rectangle avec la propriété Foreground du UserControl ne fonctionne pas du tout pour le Background de la grille liée au Background du UserControl. Là, ce n'est pas une feature, je penche sérieusement pour un gros bug.

Cela étant donné, j'ai donc ajouté un rectangle en fond pour qu'il puisse justement servir de ... Background. Et là ça passe. Ouf !

Ouf !

Silverlight c'est génial, c'est tout .NET et tout WPF dans un petit plugin. Mais dès qu'on sort du carré de verdure, on tombe dans les bois et là des loups il y en a quelques uns qui vous attendent au tournant ! Cela est logique, on s'y attend, c'est le prix à payer pour avoir .NET dans un browser Internet. Forcément le costume est un peu serré, le tissu a été économisé. Mais cela ne change rien à l'amour qu'on porte à Silverlight, au contraire, on se rend compte ainsi à quel point le travail de l'équipe Silverlight a été (et est encore) un véritable casse-tête et à quel point ils ont réussi un tour de force en faisant entrer un éléphant dans une boîte d'allumettes... Tout de même, une fois arrivé à la solution j'ai poussé un grand Ouf!

Le code source du projet : LaMer.zip (62,54 kb)

Pour de nouvelles aventures : Stay Tuned !

Bien commencer avec Silverlight 3 (les setup indispensables)

Silverlight 3 est disponible depuis juillet dernier mais il n'est pas toujours évident de savoir exactement ce qu'il est nécessaire de télécharger et où pour bien commencer.

Les vacances sont passées par dessus tout ça, du coup vous n'avez pas forcément bien suivi l'action, alors pour vous voici en mode slow motion, le replay des indispensables à installer pour s'amuser comme un fou avec Silverlight 3 et surtout être au point pour concevoir des applications RIA !

Silverlight 3

Le runtime est indispensable pour, au minimum, pouvoir exécuter les applications : Le runtime Silverlight 3
Le SDK est en revanche le minimum syndical pour concevoir des applications Silverlight 3 : Le SDK Silverlight 3

Expression Blend 3 avec Sketchflow

Blend est un l'outil indispensable pour créer des applications WPF et Silverlight. D'autant plus que depuis la version 3 de Silverlight il n'y a plus d'affichage du visuel sous VS 2008. Il reste la possibilité de tout faire à la main en mode éditeur de XAML mais franchement ce n'est pas comme ça qu'on peut créer sérieusement un visuel alors : Blend 3 et Sketchflow
Vous noterez qu'il s'agit d'une version d'essai, Blend 3 n'a pas de version gratuite.

Visual Studio 2008

En attendant la version 2010 qui intègrera le designer visuel de Silverlight, il est toujours nécessaire de posséder VS 2008. En effet, Blend ne gère pas le debug qui ne peut s'effectuer que par VS. Bien qu'un éditeur de code a été ajouté à Blend 3 il est aussi plus confortable d'utiliser Visual Studio pour toute la partie code. Si vous ne possédez pas VS 2008 : Version d'essai de VS 2008

Visual Web Developer Express 

Si vous préférez un outil gratuit, n'oubliez pas que Visual Web Express est une bonne alternative à Visual Studio.

Outils Silverlight

Tout un tas de choses indispensables notamment pour permettre de travailler sous Visual Studio ou Visual Web Express. A noter que VS doit être absolument patché avec le SP1 avant d'installer tout ça : Les Silverlight Tools.

Le Toolkit

Silverlight 3 est un produit riche, mais il l'est encore plus lorsque le toolkit est installé. De très nombreux contrôles indispensables sont ajoutés : le Silverlight Toolkit.

Les RIA Services

Grâces aux Services RIA, la gestion de données distantes (n-tiers) devient un jeu d'enfant. C'est un must pour tous ceux qui souhaitent développer des applications orientées données avec Silverlight : .NET RIA Services.

Deep Zoom Composer

Si vous souhaitez créer des images Deep Zoom, il est nécessaire de posséder le Composer : Deep Zoom Composer.

Le site officiel

Encore un lien indispensable ! La partie "getting started" vous renseigne sur les téléchargement de base et propose même un installeur global "Microsoft Web Platform". Vous trouverez aussi sur ce site de nombreuses vidéos de présentation et de formation (en anglais) : Le Site officiel Silverlight.

Dot.Blog

Et oui ! Si vous souhaitez rester à jour et être au courant, le mieux c'est encore de venir sur Dot.Blog le plus souvent possible ou mieux, de s'abonner au flux RSS et surtout : Stay Tuned !

 

Silverlight 3 : Un média player complet bien caché !

Silverlight 3 est livré de base avec un contrôle très versatile, MediaElement, capable de jouer de nombreux formats comme les mp3 ou les vidéos.

Si ce contrôle est très puissant il est un peu "nu" de base et il faut soi-même ajouter les boutons de commande comme "play" et looker l'ensemble. Avec Expression Blend 3 c'est un jeu d'enfant. Enfin, de grand enfant qui a un peu de temps devant lui tout de même. D'où la question : n'existerait-il pas un MediaElement déjà tout habillé ?

Si vous possédez Expression Media Encoder 3 vous savez que cet extraordinaire outil (servant principalement à encoder des médias) donne le choix entre plusieurs formats de sortie dont des projets HTML tout fait intégrant un média player tout looké, et mieux encore, avec le choix parmi de nombreux modèles.

Quel rapport entre Media Encoder et un projet Blend/VS ? C'est tout simple : lorsque vous installez Media Encoder, sous Blend 3 dans l'onglet Assets vous disposez, en plus de MediaElement d'un nouveau contrôle "MediaPlayer" !

Par défaut ce composant ressemble à l'image ci-dessous. Pour le relooker, il suffit de faire un clic droit et d'éditer un copie du template !

Reste la question à 10 centimes d'euro : oui mais Media Encoder est livré avec de nombreux modèles dont certains ont déjà un look sympa, ne pourrait-on pas récupérer ces modèles au lieu de templater à la main le MediaPlayer ?

Si, c'est possible (© Les Nuls, "Hassan Cehef").

Comment ? Là c'est plus cher... Non, comme je suis un chic type, voici la solution gratuite :

Encoder 3 s'installe avec le code source des modèles qui se trouvent dans le répertoire "C:\Program Files\Microsoft Expression\Encoder 3\Templates\en", il suffit donc de piocher le modèle qu'on désire utiliser, et grâce aux sources d'extraire le contrôle avec son template et de l'intégrer à son propre projet !

Le célèbre Tim Heuer décrit (en englais) la méthode à suivre, je vous renvoie ainsi à son billet Using Encoder Templates in your Silverlight Application si jamais vous n'arrivez pas à vous dépatouiller seul avec le code source des projets Encoder 3.

Intégrer de la vidéo, même HD, dans une application Silverlight n'a jamais été aussi simple... et beau.

Amusez-vous bien, et .. Stay Tuned !

Silverlight 3 : Les Pixel shaders (effets bitmap) et l'accélération GPU

L'une des grandes nouveautés de Silverlight 3 c'est le support de l'accélération graphique. L'application principale se trouve déchargée de certaines tâches qui sont routées vers le GPU de la carte graphique. Mais attention, l'accélération GPU de Silverlight 3 ne fait pas tout comme sa grande soeur sous WPF (qui utilise DirectX et toutes ses ficelles pour accélérer le traitement vidéo). On aurait pu croire que les effets bitmaps (pixel shaders) de WPF qui viennent d'être portés sous Silverlight 3 utilisent l'accélération GPU, en réalité il n'en est rien. Mais cela n'enlève rien à ces nouveaux effets parfaitement utilisables pour enrichir le visuel d'une application et dont je vais vous parler maintenant...

Quelques mots sur l'accélération GPU : Même si ce n'est pas le sujet du présent billet, il s'agit d'une nouvelle feature très intéressante de SL3. On a tendance hélas (et j'ai été le premier à me faire "avoir") à trop vite faire le parallèle avec WPF et à transposer ce que fait l'accélération sous ce dernier. En fait, le support de l'accélération GPU de SL3 est pour l'instant assez limité et ne se met en route que de façon volontaire. Elle ne s'applique pas aux effets bitmaps ni aux nouveaux Codecs vidéos qui restent traités par le CPU. Malgré tout le système d'accélération graphique peut rendre d'immense service, dans certains de mes tests sur l'animation d'images assez grandes j'ai pu voir mon PC de test passer de 88% d'utilisation CPU (double coeur Asus plutôt rapide) à moins de 4% ! Ce qui est énorme. Mais pour profiter de l'accélération il faut aboslument en connaître le fonctionnement et les limitations. Je vous invite ainsi à lire l'excellent billet de Andras Verlvart sur la question. Il est assorti d'une application exemple qui permet de bien voir l'effet des différentes possibilités d'accélération et leur impact sur le CPU et le GPU. Cet article est en anglais, pour ceux qui préfère la lecture en français, David Rousset a écrit un billet qui fait le point sur cette même question.

Les Pixel Shaders 

Par défaut Silverlight 3 est fourni avec deux effets : le blur (flou) et le drop shadow (ombre portée). Mais on trouve sur CodePlex un très beau projet offrant toute une série de nouveaux effets comme le swirl ou l'emboss (WPF Effects Library pour WPF et Silverlight). Grâce au SDK Directx et au langage HSL il possible de développer ses propres effets.

L'exemple ci-dessous illustre mon propos : la fenêtre principale est décorée d'une magnifique photo d'éclair (copyrigthée par moi-même) sur laquelle un flou peut être appliqué grâce à un slider se trouvant dans une petite fenêtre semi transparente sur laquelle est appliqué un drop-shadow.

Vous remarquerez que la petite fenêtre en question peut être déplacée par drag-drop grâce à une autre nouveauté de Silverlight 3 : les behaviors (comportements), sorte de petits bouts de code compilés qu'on peut "jeter" sur n'importe quel contrôle pour lui offrir le dit comportement, ici un déplacement par drag-drop. Le tout sans une ligne de C#. Le slider a été templaté "à l'arrache" mais il a été templaté tout de même :-). Autre nouveauté de Silverlight 3 qui est ici démontrée : le databinding entre éléments d'interface, ainsi le texte indiquant la quantité de flou appliquée est directement lié à la propriété Value du Slider. Pour formater cette valeur un convertisseur a été ajouté.

Bref, une petite application vite fait pour montrer les Pixel Shaders, mais pas seulement...

Le mieux étant maintenant de jouer avec et de télécharger le projet (VS2008 + SL3 toolkit ou Blend 3 de préférence) : PixelShader.zip (168,29 kb)

[silverlight:source=/SLSamples/PixelShader/PixelShader.xap;width=550;height=480]

Et Stay Tuned !

nota: cet article du 28 juillet 2009 a été mis à jour le  3 août à propos de l'accélération GPU.

Silverlight 3 : La multi-sélection

Parmi les petites évolutions de Silverlight 3 qui ne méritent pas un article de fond mais qu'il faut noter tellement elles simplifient les choses, j'apprécie le support de la multi sélection dans les ListBox.

La nouvelle propriété s'appelle sans malice : SelectionMode et elle peut prendre les valeurs suivantes : Single, Multiple, Extended. En mode Single on retrouve le comportement par défaut mono sélection. Les deux autres modes permettent d'accéder au comportement multi sélection. En mode Multiple la sélection s'opère par le clic sur un item, en enfonçant Ctrl ou Shift. Le mode Extended fait que le Shift permet de sélectionner des étendues.

Jouez avec notre ami Casimir dans l'exemple ci-dessous, et grâce à la nouvelle ListBox Silverlight 3 confectionnez votre propre Gloubiboulga en partant de la recette originale et de ses options (pour les plus gourmands !) :

[silverlight:source=/SLSamples/MultiSelect/MultiSelect.xap;width=411;height=203]

Bon appétit, et... Stay Tuned !

Silverlight 3 : Styles Cascadés (BasedOn Styles)

Toujours dans ma petite série sur les nouveautés de Silverlight 3 je vais vous présenter aujourd'hui une feature plaisante : les styles cascadés.

En soi rien de nouveau à l'ouest puisque c'est le principe même des feuilles de styles CSS (qui y puisent d'ailleurs leur nom). Mais le CSS s'applique à quelques éléments simples HTML alors que là nous parlons de styles Silverlight, c'est à dire d'objet complexes pouvant définir tout un visuel, animations comprises.

[silverlight:source=/SLSamples/BasedOnStyle/BasedOnStyle.xap;width=405;height=150]

Dans l'application Sivlerlight 3 ci-dessus (fonctionnelle, ce n'est pas une capture écran), vous voyez 4 boutons. Tous sont des boutons standard du framework.

  • Le premier, intitulé "Base SL" possède le style Silverlight par défaut
  • Le second, "Normal" est décoré par le style "BoutonNormal"
  • Le troisième "Gros" est décoré par le style "BoutonGros"
  • Et le quatrième "Alarme" est décoré par le style "BoutonGrosAlarme"

Visuellement c'est plutôt moche, je vous l'accorde, mais le but du jeu est de voir l'effet du cascading styling...

Le style "BoutonNormal" est défini comme suit :

<Style x:Key="BoutonNormal" TargetType="Button">
     <Setter Property="Width" Value="90" />
     <Setter Property="Height" Value="30" />
     <Setter Property="HorizontalAlignment" Value="Left" />
     <Setter Property="VerticalAlignment" Value="Bottom" />
     <Setter Property="BorderThickness" Value="2"/>
</Style>

Là où les choses deviennent plus intéressantes, c'est dans le style "BoutonGros" ci-dessous où l'on voit apparaître l'attribut BasedOn qui permet de fonder le style courant sur celui qu'on indique :

<Style x:Key="BoutonGros" 
         BasedOn="{StaticResource BoutonNormal}"
         TargetType="Button">
  <Setter Property="Width" Value="180" />
  <Setter Property="Height" Value="60" />
  <Setter Property="FontFamily" Value="Comic Sans MS"/>
</Style>

Enfin, le dernier style se fonde lui-même sur le précédent par le même mécanisme, le niveau de cascading n'étant pas limité. On peut voir notamment que le changement de famille de fonte introduit dans le style "BoutonGros" s'est propagé au style "BoutonGrosAlarme" (fonte Comic).

<Style x:Key="BoutonGrosAlarme" 
         BasedOn="{StaticResource BoutonGros}"
         TargetType="Button">
  <Setter Property="Width" Value="160" />
  <Setter Property="Height" Value="40" />
  <Setter Property="FontSize" Value="18"/>
  <Setter Property="FontWeight" Value="Bold"/>
  <Setter Property="Foreground" Value="Red"/>
  <Setter Property="BorderThickness" Value="4"/>
  <Setter Property="BorderBrush" Value="#FFFF0202"/>
</Style>

Voilà, c'est tout simple, mais cela peut radicalement simplifier la création de gros templates pour des applications. Tous les avantages du Cascading Style Sheet de HTML dont l'intérêt ne se démontre plus, mais appliqué à des objets et à la sophistication de Silverlight. Que du bonheur...

Bon Styling,

...Et Stay Tuned !

Silverlight 3 : L'Element Binding

L’Element Binding est une nouvelle feature de Silverlight 3 déjà présente sous WPF.

L’Element Binding définit la capacité de lier les propriétés des objets entre eux sans passer par du code intermédiaire. Cette possibilité existait déjà sous WPF, on la retrouve désormais sous SL3.

Pour simplifier prenons l’exemple d’un panneau d’information, par exemple un Border avec un texte à l’intérieur. Imaginons que l’utilisateur puisse régler l’opacité de cette fenêtre par le biais d’un Slider. (ci-dessous l'application exemple pour jouer en live).

[silverlight:source=/SLSamples/EBinding/EBinding.xap;width=452;height=240]

On place quelques éléments visuels sous le Border (ici des rectangles) afin de mieux voir l’effet du changement d’opacité.

Trois méthodes s'offre à nous pour régler le lien entre le Slider et l'opacité du Border. J'appellerai la première "méthode à l'ancienne", la seconde "méthode du certifié" et la troisième "méthode Silverlight 3". Les trois ont leur intérêt mais si vous êtes très pressé vous pouvez directement vous jeter sur la 3eme solution :-)

Méthode 1 dite « à l’ancienne »

Le développeur Win32 habitué aux MFC ou à des environnements comme Delphi aura comme réflexe immédiat d’aller chercher l’événement ValueChanged du Slider et de taper un code behind de ce type :

MonBorder.Opacity = MonSlider.Value ;

Ça a l’avantage d’être simple, efficace, de répondre (apparemment) au besoin et de recycler les vielles méthodes de travail sans avoir à se poser de questions…

Méthode 2 dite « du certifié »

Ici nous avons affaire à un spécialiste. Son truc c’est la techno, suivre les guide-lines et écrire un code qui suit tous les dogmes de l’instant est un plaisir intellectuel. Parfois ses solutions sont un peu complexes mais elles sont belles et à la pointe de la techno !

Conscient que la solution « à l’ancienne » a un petit problème (en dehors d’être trop simple pour être « belle », elle est one way, le slider modifie l'opacité du border mais l'inverse ne fonctionne pas) il va chercher une solution objet élégante répondant à l’ensemble des cas possibles couvrant ainsi le two way, considération technique trop technophile pour le développeur du cas précédent.

Ici forcément ça se complique. C’est techniquement et intellectuellement plus sexy que la méthode « à l’ancienne » mais cela réclame un effort de compréhension et de codage :

Il faut en fait créer un objet intermédiaire. Cet objet représente la valeur du Slider auquel il est lié lors de son instanciation. Quant à l’objet Border, sa propriété Opacity sera liée par Data Binding standard à l’objet valeur.

Voici le code de la classe de liaison :

public class ValueBinder : INotifyPropertyChanged
       {
             public event PropertyChangedEventHandler PropertyChanged;
             private Slider boundSlider;
             public ValueBinder(Slider origine)
             {
                    boundSlider = origine;
             }
 
             public double Value
             {
                    get { return boundSlider==null?0:boundSlider.Value; }
                    set {
                           if (PropertyChanged!=null)
                                  PropertyChanged(this,
                                    new PropertyChangedEventArgs("Value"));
                           boundSlider.Value = value;
                    }
             }
       }

Cette classe, ou plutôt l’une de ses instances, servira a représenter la valeur courante du Slider. Ce dernier est lié à l’instance lors de la création de cette dernière (voir le constructeur de la classe ValueBinder ci-dessus).

Comment utiliser cette classe ?

La première chose est qu’il faut en créer une instance, cela peut se faire dans le code XAML ou bien dans le code behind de la façon suivante (dans le constructeur de la page par exemple) :

var valueBinder = new ValueBinder(slider);

Maintenant il suffit dans le code XAML de lier les deux objets à la valeur de la classe intermédiaire, par Data Binding :

Côté Slider, le code est :

<Slider x:Name="slider"Value="{Binding Value, Mode=TwoWay}"/> 

Côté Border :

<Border x:Name="borderInfo"Opacity="{Binding Value, Mode=TwoWay}"> 

Ne reste plus qu’à rendre visible l’objet intermédiaire par exemple en en faisant la valeur courante du DataContext de l’objet LayoutRoot :

LayoutRoot.DataContext = valueBinder;

Et voilà ! Ne reste plus qu’à compiler et vous le plaisir de voir que l’opacité du Border change bien lorsque le Slider est déplacé.

La chaîne est la suivante : la modification de la position du Thumb entraîne dans le composant Slider la modification de la valeur de la propriété Value. Comme celle-ci est liée par Data Binding TwoWay à la propriété Value de l’objet intermédiaire cette propriété va se trouver modifiée dans le même temps. Comme le Setter de la propriété notifie le changement de valeur de la propriété (la classe implémente INotifyPropertyChanged) et comme la propriété Opacity du Border est elle aussi liée par Data Binding à la propriété Value de l’objet intermédiaire, le Border sera « prévenu » du changement de valeur et sa propriété Opacité sera immédiatement modifiée pour recevoir la valeur courante de Value de l’objet intermédiaire ! C’est pas fun tout ça ? (hmmm j’en vois un qui suit pas là bas au fond… !).

Vous allez me dire, TwoWay, on veut bien te croire mais on ne le voit pas là … Pour l’instant cela se comporte exactement comme la première solution, juste qu’il faut avoir un niveau de certifié pour comprendre…

C’est pas faux. C’est pourquoi je vais maintenant ajouter un petit bout de code pour faire varier la valeur de la propriété Opacity du Border. Le plus simple est de gérer la roulette de la souris dans le Border :

<Border x:Name="borderInfo"MouseWheel="Border_MouseWheel"> 

Et dans le code behind :

private void Border_MouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e) 
             { 
                    borderInfo.Opacity += e.Delta/1000d; 
                    e.Handled = true;
             }

Il suffit maintenant de faire rouler la molette au dessus du Border pour en changer l’opacité. Le TwoWay ? Regardez bien : le curseur du Slider avance ou recule tout seul… Pour éviter que la page HTML contenant le plugin Silverlight ne se mette à scroller il faut bien entendu indiquer que l'événement est géré (Handled=true) ce qui est fait dans le code ci-dessus.

Cette solution est élégante, complète mais complexe. Elle reste l’approche à préconiser dans tous les cas du même type car, on le voit bien, si la première solution est simple, elle n’est pas complète. Complexifier par plaisir est un mauvais réflexe, mais ne pas voir qu’une solution est trop simpliste est aussi un défaut qu’il faut fuir !

Bref, sous Silverlight 2 la solution présentée ici est une bonne solution. Sous Silverlight 3 qui supporte le Binding direct entre éléments (comme WPF) nous allons pouvoir faire plaisir à la fois au développeur du premier cas et à celui du second :

Méthode 3 dite « Silverlight 3 »

Comment marier le reflexe (plutôt sain) du premier développeur de notre parabole de vouloir faire vite et simple avec l’exigence intellectuelle (tout aussi saine) du second qui implique de faire « complet » ?

Pour illustrer l’Element Binding de façon simple, prenons un Scrollbar en mode horizontal et un Slider en mode vertical.

Et regardons le code XAML de leur déclaration :

<ScrollBar x:Name="scrollA"Value="{Binding Value, ElementName=sliderB, Mode=TwoWay}"/> 
 
<Slider x:Name="sliderB"Value="{Binding Value, ElementName=scrollA, Mode=TwoWay}" /> 

Et c’est tout ce qu’il y a à faire pour obtenir une solution complète, élégante, sans code behind et très facile à mettre en œuvre ! Merci Silverlight 3 !

En début de billet vous pouvez jouer avec les deux dernières implémentations (je n’ai pas implémenté la méthode 1) .

Vous pouvez aussi télécharger le code du projet (Blend 3 ou VS2008 avec les extensions SL3) : elementBinding.zip (61,43 kb)

Pour d'autres nouvelles, Stay Tuned !

Silverlight 3 : Nouveau contrôle DataForm et Validation des données

Je continue ma petite série sur les nouveautés de Silverlight 3. Au menu un composant des plus intéressant et un nouveau système de validation.

Le composant s'appelle DataForm, il est en quelque sorte le pendant mono enregistrement du composant DataGrid. Avec cette dernière on montre plusieurs enregistrements à la fois, avec la DataForm on présente les données d'une seule fiche. On conserve malgré tout la possibilité de navigueur de fiche en fiche, et le composant est hautement personnalisable grâce aux styles et templates.

Imaginons une petite fiche permettant de créer un login : pseudo, e-mail et mot de passe sont le lot de ce genre de cadres de saisie. Pour les besoins de la démo commençons par créer une classe représentant l'ensemble des informations à saisir (voir le code en fin de billet).

Rien d'exceptionnel ici donc, juste une petite classe. Mais vous remarquerez plusieurs choses :

  • Les propriétés sont décorées d'attributs qui permettent de modifier notamment l'affichage des labels dans la DataForm, un nom interne de propriété n'est pas forcément adapté pour une lecture par l'utilisateur final.
  • Les propriétés sont décorées de l'attribut Required. Autre particularité pour la DataForm : certains champs peuvent être obligatoires.      

Dans le code ci-dessous chaque propriété prend en charge sa validation : elle lève une exception dès que la valeur passée n'est pas conforme à celle attendue. Il existe d'ailleurs un doublon fonctionnel dans ce code : la présence de la méthode CheckNull qui s'assure qu'une propriété n'est pas vide, et l'attribut Required. En l'état c'est la méthode CheckNull qui prend le dessus, on pourrait donc supprimer l'attribut.


Il existe bien d'autres attributs pour la DataForm et le propos de ce billet n'est pas de tous les détailler, mais il est important de noter comment le code peut prévoir certains comportements qui seront reportés sur l'interface utilisateur sans réellement interférer avec elle... subtile.

Regardons maintenant le code XAML de la page affichée par Silverlight (en fin de billet). 

Tout d'abord vous remarquerez que l'instance de LoginInfo n'est pas créée dans le code C# mais sous forme de ressource dans la fiche, en XAML.
Ensuite nous définissions une balise DataForm dont l'item courrant est lié à l'instance de LoginInfo.

Et c'est tout. Pour la décoration j'ai ajouté un bouton "ok" qui accessoirement lance la valitation totale de la fiche. Ne saisissez rien et cliquez dessus : vous verrez apparaître le cadre des erreurs avec la liste de toutes les validations qui ont échouées. Bien entendu l'aspect de ce cadre est templatable aussi.

Le mieux est de jouer avec l'application de test ci-dessous:



Vous pouvez aussi télécharger le code du projet (à utiliser sous Blend 3 ou VS2008 avec les extensions SL3): SL3DataValidation.zip (60,40 kb)


[silverlight:source=/SLSamples/Validation/DataValidation.xap;width=400;height=320]

A noter : la présence du petit symbole info, il répond à l'attribut Description prévu dans le code de la classe et permet d'informer l'utilisateur.
Vous remarquerez aussi qu'en passant d'un champ à un autre les champs invalidés sont décorés par une lisière rouge dont un coin est plus marqué : cliquez sur ce dernier et vous obtiendrez le message d'erreur avec sa petite animation. L'aspect de ce cadre ainsi que l'animation sont bien entendu modifiables à souhait.

Stay Tuned pour d'autres nouveautés de SL3 !

 

Code de la classe LogInfo :

 

   1:  public class LoginInfo : INotifyPropertyChanged
   2:      {
   3:          private string loginName;
   4:          
   5:          [Required()]
   6:          [Display(Name="Login name:",Description="Votre login personnel.")]
   7:          public string LoginName
   8:          {
   9:              get { return loginName; }
  10:              set 
  11:              {
  12:                  checkNull(value);
  13:                  loginName = value.Trim();
  14:                  dochange("LoginName");
  15:              }
  16:          }
  17:          
  18:          
  19:          private string email;
  20:          
  21:          [Required()]
  22:          [Display(Name="e-mail:",Description="Adresse mail pour vous joindre.")]
  23:          public string Email
  24:          {
  25:              get { return email; }
  26:              set 
  27:              {
  28:                  checkNull(value);
  29:                  checkMail(value);
  30:                  email = value.Trim();
  31:                  dochange("Email");
  32:              }
  33:          }
  34:          
  35:          private string password;
  36:          
  37:          [Required()]
  38:          [Display(Name="Mot de passe:",Description="Votre mot de passe de connexion.")]
  39:          public string Password
  40:          {
  41:              get { return password; }
  42:              set 
  43:              {
  44:                  checkNull(value);
  45:                  password = value.Trim();
  46:                  dochange("Password");
  47:              }
  48:          }
  49:          
  50:          private string passwordCheck;
  51:          
  52:          [Required()]
  53:          [Display(Name="Contrôle:",Description="Retapez ici votre mot de passe.")]
  54:          public string PasswordCheck
  55:          {
  56:              get { return passwordCheck; }
  57:              set 
  58:              {
  59:                  checkNull(value);
  60:                  passwordCheck = value.Trim();
  61:                  if (string.Compare(password,passwordCheck)!=0)
  62:                      throw new Exception("Les mots de passe diffèrent !");
  63:                  dochange("PasswordCheck");
  64:              }
  65:          }
  66:          
  67:          private void checkMail(string value)
  68:          {
  69:              string pattern = @"^(([^<>()[\]\\.,;:\s@\""]+" 
  70:                          + @"(\.[^<>()[\]\\.,;:\s@\""]+)*)|(\"".+\""))@" 
  71:                          + @"((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" 
  72:                          + @"\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+" 
  73:                          + @"[a-zA-Z]{2,}))$";
  74:                    Regex regMail = new Regex(pattern);
  75:                   if (!regMail.IsMatch(value)) throw new Exception("E-mail non valide !");
  76:          }
  77:          
  78:          private void checkNull(string value)
  79:          { 
  80:              if (string.IsNullOrEmpty(value)) throw new Exception("Ne peut être vide !");
  81:          }
  82:   
  83:          #region INotifyPropertyChanged Members
  84:   
  85:          public event PropertyChangedEventHandler PropertyChanged;
  86:          private void dochange(string property)
  87:          {
  88:              if (PropertyChanged!=null) PropertyChanged(this,new PropertyChangedEventArgs(property));
  89:          }
  90:   
  91:          #endregion
  92:      }

le code XAML de la fiche :

 

   1:  <UserControl
   2:      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:      xmlns:dataFormToolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit"
   5:      xmlns:local="clr-namespace:DataValidation"
   6:      x:Class="DataValidation.MainPage"
   7:      Width="300" Height="320">
   8:   
   9:      <UserControl.Resources>
  10:       <local:LoginInfo x:Key="loginRec"  />
  11:      </UserControl.Resources>
  12:   
  13:      <StackPanel x:Name="LayoutRoot">
  14:          <dataFormToolkit:DataForm 
  15:              x:Name="PwForm" 
  16:              CurrentItem="{StaticResource loginRec}" 
  17:              Foreground="Black" 
  18:              Height="292" 
  19:              VerticalAlignment="Top" 
  20:              TabNavigation="Cycle"/>
  21:          <Button 
  22:              Content="Ok" 
  23:              VerticalAlignment="Center" 
  24:              HorizontalAlignment="Center" 
  25:              Click="Button_Click"/>
  26:      </StackPanel>
  27:  </UserControl>

Exemple Silverlight 3 : Projection 3D

Silverlight 3 est arrivé avec son lot de nouveautés, toutes sont intéressantes et poussent encore plus loin la limite du possible. Dans le même temps la convergence avec WPF se fait de plus en plus forte.

Aujourd'hui je vais vous parler de la projection 3D. Ce qu'on appelle de la "2,5D" car ce n'est déjà plus de la 2D mais ce n'est pas encore de la vraie 3D (qui implique la manipulation d'objets vectoriels 3D comme WPF sait le faire). Sous Silverlight 3, la 2,5D est un groupe de transformation qui s'ajoute à celui déjà présent (et permettant les translation, le skew, les rotations, etc). Ce nouveau groupe se présente globalement de la même façon (en tout cas sous Blend 3) mais les effets sont différents puisqu'il s'agit de créer des effets de perspectives 3D avec les objets 2D de Silverlight.

A quoi cela peut-il bien servir ?

A plein de choses ! Au niveau graphique et visuel s'entend.

Pour illustrer tout cela voici un exemple qui montre comment on peut animer une petite fiche d'information qui donne l'impression d'avoir deux faces, comme une carte de jeu par exemple : Exemple SL3 Projection. Vous pouvez aussi directement jouer avec l'exemple qui s'affiche ci-dessous (je teste en même temps l'excellent plugin Silverlight pour BlogEngine) :

[silverlight:source=/SLSamples/3DProjection/3DProjection.xap;width=350;height=446]

Je me suis inspiré de l'exemple de Jesse Liberty (que j'appelle affectueusement Droopy en raison de la tonalité de sa voix) un grand fan de Silverlight chez MS qui propose des tas de tutors et autres vidéos. En revanche Jesse est un gars qui travaille un peu "à l'ancienne", et pour arriver au résultat il faut deux vidéos d'explications car tout est tapé à la main en XAML. Cela a l'avantage de bien détailler l'astuce utilisée, mais ce n'est pas ce que je vise. Personnellement je veux arriver à tout faire sous Blend car on ne forme pas des infographistes en leur expliquant les arcanes de XAML mais en leur montrant comment on arrive au résultat interactivement. Et justement je prépare une série de vidéos de formation autant pour les développeurs que pour les infographistes...

J'ai donc totalement refait l'exemple sous Blend 3, sans une ligne de C# ni aucune de XAML tapée à la main (car forcément, il y a du XAML mais c'est Blend qui s'en occupe). J'arrive d'ailleurs à obtenir le même effet que Jesse en deux storyboards au lieu de 3 et en utilisant un Behavior pour déclencher les animations depuis les boutons au lieu de code behind C#. Je me suis même offert le luxe d'utiliser les nouveaux modes de EaseIn/Out qui permettent d'obtenir des mouvements plus "organiques" (effets de rebonds ou d'élastique par exemple).

Comme il n'y a rien dans ce projet d'autre que deux timelines, plutôt qu'un long discours je vous propose de charger le projet exemple (VS 2008 avec toutes les extensions Silverlight 3 ou bien mieux, ouvrez le projet directement dans Blend 3) : 3DProjection.zip (61,42 kb)

En deux mots, l'astuce consiste à avoir deux fiches identiques au niveau de leur forme extérieure. L'une est la face A, l'autre la face B. Le contenu des deux fiches est totalement libre.

Au début la fiche A est visible "à plat", "normalement" donc. Sur l'appui du bouton "aide" (simple exemple) l'animation FlipToBack est lancée. Elle consiste à appliquer une transformation perspective sur l'axe Y pour donner l'impression que la fiche tourne. Pour que la fiche B ne soit pas visible durant cette phase, elle a subit en début d'animation une simple translation pour l'amener en dehors de l'espace de l'application (par exemple en position 1000 sur l'axe Y).

Au moment où la fiche A passe à 90 degrés, c'est à dire quand elle est vue par la tranche, et comme elle n'a aucune épaisseur, elle disparait visuellement. C'est à ce moment précis que la magie s'opère : on fait faire une rotation à la fiche B pour qu'elle soit sur sa tranche aussi et on l'amène à la place de la fiche A (en annulant la translation sur Y de B) et dans le même temps on fait une translation de 1000 sur Y de la fiche A. Les keyframes utilisées pour cette substitution sont de type HoldIn, c'est à dire qu'il n'y a pas de transition douce avec l'état précédant, tout est instantané. Maintenant que la fiche B est à la place de la fiche A, on peut continuer l'animation de B pour qu'elle s'affiche. Le "spectateur" est dupé : durant la microseconde où la fiche A était vue par la tranche nous lui avons substitué la fiche B vue sous le même angle. Le début de l'animation fait tourner A, alors que la seconde partie de l'animation fait tourner B, mais on a l'impression visuelle que c'est la même fiche qui tourne et qu'on en découvre le dos...

Pour revenir de la page B à la page A, il suffit de créer une seconde timeline qui reprend le même principe mais qui fait les choses dans l'autre sens...

Krafty non ?

Amusez vous bien avec l'exemple et surtout...

Stay tuned !

Silverlight 3 Releasé !

Ca y est, Silverlight 3 est releasé ! Avec Blend 3 RC (la finale dans 1 mois) et son nouveau système Sketchflow et des tonnes de nouveautés.

Silverlight 3 est une release d'importance qui pousse un cran plus loin encore le niveau des performances et de services rendus. On trouve parmi les nouveautés (sans ordre de préférence et avec des oublis) :

  • La vidéo HD avec accélérateur GPU d'une fluidité à couper le souffle ! Surtout cela permet de libérer le CPU et de tirer parti de la puissance de la carte graphique, donc d'avoir une qualité plus grande sur des PC moins puissants. Bien entendu, sur les plus puissants le gain est nettement visible aussi. De nouveaux Codec viennent s'ajouter avec le support H.264, l'audio AAC et le MPEG-4. Une API permet de créer de nouveaux Codec dans tout langage .NET ! Microsoft propose dans le même temps IIS Media Service, une application de streaming gratuite à installer sous IIS pour offrir un service de diffusion fluide et efficace.
  • L'accélération vidéo via le matériel (GPU) profite aussi et bien entendu à tous les logiciels développés en Silverlight pour une plus grande fluidité graphique. Ce qui permet au passage d'ajouter à Silverlight 3 le support des effets bitmap tant attendus comme le drop shadow ou le blur. Une interface ouverte permettant de créer soi-même de nouveaux effets.
  • De Nouveaux composants arrivent aussi. Avec Silverlight 3 et son SDK ce sont plus de 100 contrôles qui sont livrés pour concevoir des applications innovantes et fonctionnelles. L'accès aux données est largement amélioré avec la présence de la DataForm qui complète la DataGrid en fournissant une vision fiche de saisie plus orientée business.
  • Silverlight 3 améliore aussi la navigation en permettant l'exploitation des touches avance/recul du navigateur. La nouvelle fonction des bookmarks internes permet aussi de créer des liens mémorisables par les navigateurs qui peuvent alors plonger à l'intérieur d'une application Sliverlight.
  • Les styles deviennent héritables, on retrouve ainsi tout l'intérêt du cascading de CSS appliqué non pas à quelques styles HTML mais à des graphiques, des templates et des animations !
  • Les applications Silverlight peuvent désormais vivre en dehors du navigateur et être installées "sans installation" dans les menus de Windows. Les applications sont exécutables directement sans même plus avoir conscience qu'il s'agit, au départ, d'une application internet. Le tout en un clic...
  • En matière de communication la partie WCF est aussi améliorée avec une meilleure propagation des erreurs, la possibilité d'utiliser du XML binaire, c'est à dire compressé pour diminuer la taille des paquets échangés entre l'application et le serveur WCF.
  • Les Services .NET RIA permettent d'écrire du code de validation plus efficacement agissant à la fois sur la couche de présentation et celle du code métier, le tout sans avoir besoin de réécrire les mêmes régles dans plusieurs codes différents.
  • Visual Studio 2010 supportera bien entendu toutes les nouveautés mais il est déjà possible de bénéficier de tous les avantages cités depuis VS 2008.
  • Blend 3, évoqué en introduction est fourni en RC avant sa sortie officielle dans 1 mois. On y trouve de très nombreuses améliorations sur lesquelles je reviendrai prochainement dont le Sketchflow qui méritera à lui seul tout un article tellement le concept est génial pour faciliter le maquettage tant sous Silverlight que WPF.
  • Blend 3 introduit aussi des notions nouvelles comme les comportements (behaviors), sortes d'automates logiciels qu'on peut poser par drag-and-drop sur tout contrôle ou graphique pour lui permettre d'agir sans aucune programmation en code behind. Par exemple il existe un comportement de changement de propriété : déposez-le sur un cercle, et vous pourrez régler quel événement sera la source (le mouse enter par exemple), et quel autre objet sera la cible (couple objet / propriété). Fixer la nouvelle valeur (par exemple changer la couleur d'un autre contrôle). Le tout peut se faire immédiatement ou avec une timelime automatique pour un effet visuel plus "smooth" (on entre la durée voulue) !
  • Silverlight 3 supporte la 3D perspective, c'est à dire qu'on n'est pas encore arrivé au niveau de WPF qui sait manipuler des scènes 3D (objets 3D, lumières, caméras...) mais qu'il est possible de donner un effet de perspective à tout objet en application des rotations sur les 3 axes de l'espace. Cela ouvre de nouvelles ... perspectives pour créer par exemple des effets de transition novateurs sans une ligne de code.
  • Que dire aussi des Ease-in/out complexes qui permettent facilement de changer une animation un peu trop rigide en quelque chose de plus "organique", comme l'impression de rebond ou celle du comportement d'un elastique...
  • Blend 3 supporte aussi Intellisense dans le code XAML ce qui manquait cruellement.
  • Il permet aussi d'importer des graphiques PhotoShop ou Illustrator en conservant les layers, avec sélection des parties à importer.
  • Le templating inversé est aussi une nouveauté fantastique : vous partez d'un dessin fait par le graphiste et vous expliquez à Blend qu'il va devenir un bouton, un slider.. et Blend vous guide pour indiquer quel bout du dessin joue le rôle de piste, de curseur, etc. Réellement bluffant !
  • Les données manquent souvent lors de la conception d'un écran, et il est parfois difficile de templater une listbox ou une grille sans voir des exemples réalistes de contenu (un nom, une adresse mail, un numéro de téléphone etc). Blend 3 propose un mini générateur de données aléatoire typées (dans l'esprit de DataGen, le générateur de données que j'ai conçu, mais la fonction de Blend est de loin moins puissante). En tout cas cela permet d'immédiatement disposer de données assez réalistes pour mettre au point les écrans. On peut aussi charger des données de test depuis un fichier XML externe (généré par DataGen par exemple ? !).
  • Blend supporte l'intégration des projets au système de versionning. Cette évolution tombe sous le sens puisque Blend et VS sont conçus pour travailler de concert sur les mêmes projets et que dans ce cadre les deux produits doivent pouvoir gérer les changements dans un repository centralisé. Cette option s'entend pour le travail en équipe principalement.
  • Media Encoder 3 est lui aussi releasé dans la même vague, avec Design 3. Encoder permet de supporter les nouveaux modes videos de streaming HD de Silverlight 3.

Bref, je m'arrête là, c'est une moisson extraordinaire. Des outils de plus en plus puissants, de plus en plus agréables à utiliser, une gamme cohérente.

J'ai forcément oublié plein de choses, mais j'aurai forcément l'occasion de revenir sur toutes ces nouveautés dans des papiers à venir.

Entre temps, vous pouvez télécharger tout le nécessaire en vous rendant sur http://www.silverlight.net/ (téléchargements, tutors...), http://expression.microsoft.com/en-us/default.aspx (le site de la communauté Expression), ou encore http://www.microsoft.com/silverlight (le site de base de Silverligth avec des démos des nouveautés de la V3)

Amusez-vous bien !

Et Stay tuned, car des nouveaux papiers, il va forcément y en avoir d'ici quelques temps !