Visual Studio, vue design et services : éviter les crashs du designer

Si vous développez une application .net utilisant du Binding en XAML, que vous faites des appels à des services et que la vue design de votre environnement de développement plante lamentablement, vous devez peut être avoir besoin de mocks, de faux services pour permettre à VS d’afficher des données.

Jusqu’à présent, mes développements en .net se faisaient selon la norme ISO 1664 (autrement appelé méthode Larache) et mon code manquait d’organisation. J’ai alors entrepris de regarder la structure MVVM et d’en apprendre ses principes et son fonctionnement pour l’implémenter dans une application que je suis en train de développer. Cet article n’a pas pour vocation à vous apprendre le pattern MVVM ni à le mettre en place, mais je vais quand même rappeler le principe avant de parler de mon problème.

Pour rappel, la structure d’un projet MVVM est grosso modo découpée en 3 couches : La couche Modèle : Elle comprend les appels à des webservice, base de données et leur retour sous forme de liste d’objet généralement.

La couche View pour « Vue » est la couche représentant l’affichage des données à l’utilisateur. Jusqu’à présent, dans mes applications, cette couche comprenait beaucoup trop de code métier. Avec MVVM, la vue ne fait que ce qu’elle devrait faire depuis toujours : afficher des données.

Et enfin, la dernière couche, le ViewModel, c’est cette couche qui fait le lien entre la couche modèle et la vue.

Il existe un pattern MVVM qui consiste à rajouter une couche entre le view model et le model. Cette couche est appelée Locator. Dans cette classe, nous indiquons à notre code quels sont les éléments que nous allons utiliser. On va alors « enregistrer » nos composants via cette couche auprès de l’application pour ensuite en disposer quand on veut. Cela permet entre autre de structurer un peu plus le code mais aussi de ne pas à s’occuper de créer les objets des différents services et view model avec le mot clé « new », l’application s’en charge pour vous, la magie de l’injection.

Pourquoi parler de tout ça ? Et bien depuis quelques jours, la vue Design de Visual Studio 2012 crashait sur la même vue dans mon projet et je ne savais pas pourquoi. Cette application est mon premier projet MVVM et comme maintenant j’utilise l’accès aux données dans les règles de l’art, visual studio est capable d’afficher les retours des donnés directement dans la vue Design ! En effet, auparavant, j’utilisais l’attribut ItemSource d’un composant listbox par exemple pour mettre une liste dans le code behind, et j’utilisais un binding classique dans l’itemtemplate de la listbox pour l’affichage en xaml.

Aujourd’hui, plus d’attribut ItemSource, je passe directement par l’attribut DataContext disponible dans la vue XAML, autrement dit, plus aucune gestion de binding dans le code behind.

Cela se traduit par l’ajout d’une balise Datacontext dans le XAML de votre page faisant référence à votre view model déclaré dans votre Locator, qui lui-même est déclaré dans le App.xaml (à tes souhaits…)

 

VehiculesViewModel possède un attribut de classe ListeVehicules :

Et notre LongListSelector, par Binding, va utiliser les données de cette liste :

 

Sacrément pratique pour façonner votre écran ! Oui mais voilà, VS utilise les « vrais » services et ces services peuvent mal répondre ou être en échec au moment du design. Et c’est précisément ce qu’il se passe dans mon cas, et la vue de VS plante lamentablement.

Et bien entendu, le message de l’erreur ne vous en informe pas explicitement.

La solution : écrire des « faux » service qui retournent toujours des données. Il faut ensuite dans votre code, à l’endroit où vous initialisez vos objets service d’appliquer un bloc if/else pour utiliser les classes adéquates.

Si votre code est « correct », vous devez avoir une interface par service qui expose les méthodes que votre implémentation va traiter. Pour réaliser votre classe destinée au mode design, il suffit que celle-ci implémente l’interface réelle du service, et fasse un traitement simple.

 

Exemple : Une interface IVehiculeDataService avec une méthode récupérant une liste de véhicule :

 

 

On créé une classe DesignVehiculeDataService qui implemente l’interface décrite ci-dessus :

 

Cette classe retournera toujours les mêmes valeurs.

Si vous utilisez MVVM Light pour vos projets, le locator utilise un système permettant de déclarer auprès de l’application les objets à instancier, permettant de les récupérer automatiquement plus tard. Il suffit d’ajouter la condition à cet endroit pour que le mode soit appliqué aux objets dans toute l’application :

 

L’élément clé ici est l’attribut “IsInDesignModeStatic” qui permet de déterminer si nous sommes en mode design ou non. Dans cet exemple de code, la variable est présente dans ViewModelBase car j’utilise MVVM Light. Pour les projets sans toolkit,  des solutions sont données via des recherches google, ça a l’air d’être un poil différent selon la nature du projet .net (WPF, Silverlight…)

Ainsi, la vue Design de VS reprendra les données retournées par vos faux services :

VS Vue Design

leave your comment

What is 5 + 23 ?
Please leave these two fields as-is:
Vous êtes humain ? Alors faites un petit calcul mental et c\'est terminé :)