Accueil Nos publications Blog [TechDays 2012] : Améliorer sa productivité XAML en entreprise

[TechDays 2012] : Améliorer sa productivité XAML en entreprise


Cette session animée par Luc Vo Van, consultant chez Microsoft Consulting Services spécialisé dans le développement XAML/UI, et Thomas Lebrun, consultant Infinite Square et co-auteur du livre “MVVM – De la découverte à la maîtrise“, avait pour but de nous présenter quelques astuces et techniques éprouvées pour améliorer la productivité des développeurs XAML.

Ces astuces sont valables à la fois en WPF, Silverlight “classique”, Windows Phone et Windows 8.

Les Behaviors

Le premier conseil concernait l’utilisation des Behaviors, qui sont en général trop peu connus des développeurs XAML mais qui permettent de gagner énormément de temps lorsque l’on souhaite ajouter certaines fonctionnalités à des contrôles (boutons, champs de texte…). Pour les développeurs C#, ces Behaviors peuvent être vus comme des méthodes d’extension pour les contrôles XAML. Leur principal avantage est donc qu’ils permettent de modifier le comportement par défaut de contrôles sans avoir besoin de les étendre ou de modifier leur code, et ce de manière générique et réutilisable.

Concrètement, un Behavior est une classe qui étend la classe “Behavior<T>” (fournie avec le SDK Expression Blend), “T” désignant le type de contrôle auquel le Behavior pourra s’appliquer (Button, TextBox…). Il suffit ensuite de surcharger la méthode “OnAttached” qui donne alors accès au contrôle auquel le Behavior est attaché, par la propriété “AttachedObject”. On peut alors s’abonner à des évènements de ce contrôle, modifier ses propriétés… Pour “attacher” ce Behavior à un contrôle, on le déclare ensuite dans le XAML de cette façon :

<Button>
    <interactivity:Interaction.Behaviors>
        <local:MonBehavior/>
    </interactivity:Interaction.Behaviors>
</Button>

On peut évidemment aussi créer des Behaviors “génériques” qui s’appliquent à plusieurs types de contrôles, simplement en les créant pour une classe mère comme FrameworkElement ou Control.

Utilisation des VisualStates

Autre fonctionnalité trop peu connue : les VisualStates qui permettent de définir des états visuels sur les contrôles ainsi que des transitions et animations entre ces états, le tout intégralement en XAML.

La plupart des contrôles de base ont déjà des VisualStates définis (par exemple les boutons avec leurs états Normal, Pressed, Inactive…), mais il peut être judicieux d’appliquer cette astuce à des formulaires d’édition par exemple (avec des états lecture seule/édition ou simple/détaillé).

Il faut tout de même faire attention à la taille du XAML que l’on produit en stockant ainsi tous les états d’un contrôle, car cela peut augmenter le temps nécessaire pour le parser et nuire à la lisibilité du code.

Choix d’un framework MVVM

Pour les projets XAML d’entreprise architecturés en MVVM, choisir un framework qui implémente les fonctionnalités architecturales dont on a besoin peut faire gagner beaucoup de temps.

Il existe une multitude de ces frameworks, les plus connus étant MVVM Light de Laurent Bugnion, Prism, Caliburn, Cinch… Ils proposent la plupart du temps une implémentation de base de l’interface INotifyPropertyChanged pour les Binding, des implémentations de commandes, une solution de Messaging pour la communication entre les ViewModels, ainsi que d’autres fonctionnalités plus avancées en fonction du framework choisi. Baser ses développements MVVM sur un de ces frameworks permet donc de ne pas avoir à re-développer ces éléments, mais il est important de bien les choisir en fonction de ses besoins et de ses contraintes, certains étant plus complets, mais aussi plus complexes que d’autres.

Pattern ViewModel locator

Une autre astuce proposée consiste à utiliser le pattern ViewModel locator qui permet de simplifier la déclaration des liaisons entre les vues et leurs ViewModels et de disposer d’un point d’accès centralisé à tous les ViewModels d’une application. Ce pattern a un autre avantage si on utilise de l’injection de dépendances : on peut alors facilement déclarer et utiliser des ViewModels spéciaux “Design-Time” en plus des ViewModels métiers afin d’améliorer la Blendabilité des applications.

Le framework MVVM Light propose une implémentation de ce pattern.

Mieux choisir ses contrôles

Lorsque l’on a besoin d’un contrôle spécifique, plusieurs choix s’offrent à nous :

  • Modifier le comportement d’un contrôle existant, par exemple à l’aide de Behaviors
  • Hériter d’un contrôle existant, ou le re-templater
  • Utiliser un composant du marché
  • Réécrire un contrôle “from scratch”

Le choix doit découler d’une réflexion sur l’équilibre entre la quantité de fonctionnalités souhaitées, la complexité de la solution choisie et ses performances. Par exemple, les gros éditeurs de contrôles comme Telerik proposent souvent des démos très tape-à-l’œil et des contrôles riches en fonctionnalités, mais si leurs solutions ne correspondent pas exactement à nos besoins, il est souvent complexe de les modifier et les performances seront probablement moins bonnes qu’un contrôle développé spécifiquement pour nos besoins. En revanche, créer un contrôle de toutes pièces peut s’avérer assez complexe et nécessite des compétences plus avancées. Il faut donc choisir le meilleur compromis pour gagner du temps tout en satisfaisant les besoins.

Pour ces contrôles spécifiques, il est également conseillé de créer une application de test dédiée, avec des exemples de code pour leur utilisation, mais surtout pas de code “métier” : cela permet de faciliter les développements et les tests sur ces contrôles (pour ne pas avoir à lancer une application métier lourde et complexe à chaque fois que l’on veut tester une modification de ce contrôle) et s’assurer de leur généricité et leur indépendance vis-à-vis de ces codes métiers.

Peu importe la solution choisie, il faut aussi garder à l’esprit que l’on développe toujours une sorte de framework autour de nos applications, et qu’il faut donc réfléchir à la réutilisabilité des composants choisis, à leur complexité ainsi qu’au “coût d’entrée” d’un potentiel nouveau développeur sur notre architecture.

Gestion élégante des erreurs

Il est important de consacrer un peu de temps à personnaliser les erreurs qui peuvent survenir sur les applications, et ne pas se contenter d’afficher un message générique sans valeur ou, au contraire, des données techniques incompréhensibles. Par exemple, sur les popups d’erreur, il peut être très utile de proposer aux utilisateurs un bouton qui permet d’envoyer directement les messages d’erreur et les stacktraces par email aux personnes concernées, avec un message “humain” et rassurant. Cela facilitera grandement le travail des développeurs pour débugger ces problèmes et améliorera par la même occasion le ressenti des utilisateurs.