Dot.Blog

C#, XAML, WinUI, WPF, Android, MAUI, IoT, IA, ChatGPT, Prompt Engineering

Quelques conseils de design (UserControl, Blend, Visual State manager, Silverlight / WPF)

L’une des avancées les plus intéressantes introduite dans Silverlight 2 (puis reprise sous WPF et naturellement sous Silverlight 3) est très certainement le Visual State Manager. Gestionnaire des états visuels simplifiant la conception visuelle des contrôles (UserControl). Bien utiliser le VSM, outre de rendre plus simple la représentation des états visuels d’un composant, apporte aussi une clarification essentielle à la gestion des transitions entre ces derniers.Plus...

Silverlight : Enum.GetValues qui n'existe pas, binding et autres considérations

Silverlight, comme vous le savez, propose dans quelques méga octets un mini framework .NET qui est tellement bien "découpé" que la plupart du temps on ne se rend même pas compte qu'il manque des dizaines de méga de code binaire... Pourtant entre une installation complète du Framework 3.5 ou 4.0 à venir et l'installation du plugin Silverlight il y a comme une énorme différence ! De deux choses l'une, soit Silverlight ne sait rien faire tellement il est diminué par ce découpage, ce qui n'est pas le cas, soit le Framework complet est juste gonflé avec des fichiers inutiles pour "faire sérieux", ce qui n'est pas le cas non plus :-)

Un découpage savant 

Donc ce n'est ni l'un ni l'autre. La troisième possibilité, qui est la bonne réponse, est que le Framework complet est d'une richesse infinie dans les moindres détails, et que le Framework Silverlight "ruse" en zappant beaucoup de détails mais sans perdre l'essentiel. Cela donne l'impression qu'on peut tout faire en Silverlight comme en WPF. C'est "presque" vrai. Assez rapidement on tombe sur les fameux petits détails qui manquent. Cela implique de les compenser par du code.

Cela dit loin d'être une critique négative de Silverlight s'en est au contraire une apologie ! Je trouve en effet le découpage savant qui a été effectué dans Silverlight particulièrement bien fait. L'approche est très sensée : il est rarissime (même impossible) qu'une application utilise et nécessite d'accéder à toutes les méthodes, toutes les propriétés de toutes les classes du Framework tellement celui-ci est riche. Du coup, en faisant des coupes bien choisies, on peut laisser les squelettes de presque tout le Framework ainsi que les principales méthodes et propriétés utilisées le plus souvent. On obtient le Framework Silverlight dans lequel un code standard trouvera 95% de tout ce qu'il lui faut pour tourner. Beaucoup d'applications simples ne verront même pas qu'il manque quelque chose. En revanche pour les autres cas, le développeur ajoutera les contournements nécessaires ce qui grossira un peu son code binaire Silverlight, mais d'une petite fraction très supportable. Rien à voir avec le coût d'une installation du Framework complet.

Il n'en reste pas moins vrai que parfois pour des choses très simples on se retrouve un peu le bec dans l'eau. "Tiens, c'est bizarre, j'aurais juré que la méthode xxx existait !" Et non, on n'a pas rêvé, elle existe bien, mais dans le Framework complet, pas dans celui de Silverlight. Un exemple tout simple : la méthode GetValues() de la classe Enum.

Enum.GetValues où es tu ?

Un cas d'utilisation très basique qui fait voir immédiatement qu'il manque quelque chose : essayez de faire un binding entre une combobox et une énumération. Truc classique par excellence.

Que le binding soit fait par Xaml ou bien par code, à un moment où un autre il faut que l'énumération sache retourner la liste de ses valeurs. C'est justement la fonction de la méthode Enum.GetValues().

Mais dans le Framework Silverlight cette méthode n'existe tout simplement pas. Victime de la cure d'amaigrissement évoquée plus haut. Il ne s'agit donc ni d'un oubli ni d'un dommage collatéral, c'est un parti pris, assumé.

Et alors on fait comment ?

Assumé, assumé... comme il y va ! Non, je vous l'assure, c'est assumé. Par l'équipe qui développe le Framework Silverlight en tout cas. Mais pas forcément par les développeurs qui l'utilisent ! Car pour eux c'est une autre histoire puisque, en effet, il va falloir réinventer cette méthode.

A l'aide d'un peu de Linq to Object et de Reflexion, on peut s'en sortir.

Linq et Reflexion

Il existe en effet un moyen d'obtenir les valeurs d'une Enum par la réflexion, en utilisant la méthode GetFields() sur le type de l'Enum dont on souhaite obtenir les valeurs. 

GetFields() retourne un tableau de FieldInfo. Une Enum présente alors ses différentes valeurs comme un tableau de champs. En plus de ces champs, GetFields() retournera aussi des éléments qui ne sont pas des valeurs de l'énumération mais d'autres champs de la classe. Au sein de FieldInfo vous trouverez un ensemble de méthodes nommées Isxxx(), l'une d'entre elles nous intéresse plus particulièrement ici; c'est IsLiteral. Toutes les valeurs de l'énumération retournent True. La solution est alors simple en ajoutant à la Réflexion un peu de Linq to Object :

   1:  var enumType = typeof(monEnumeration);
   2:  var fields =  from field in enumType.GetFields()
   3:                where field.IsLiteral
   4:                select field.GetValue(null).ToString();
   5:  LaCombobox.ItemsSource = fields;

A partir du type de l'énumération (ligne 1) on construit une requête Linq to Object qui filtre tous les champs ayant IsLiteral à vrai et qui sélectionne la valeur de ce champ sous la forme d'une string.

Ne reste plus qu'à faire le binding entre cette requête Linq et ItemsSource de la combo box.

Il faudra ajouter un peu de code pour transformer la chaîne sélectionnée dans la combo en une valeur de l'énumération grâce à un appel à Enum.Parse().

C'est la version simple et courte. Bien entendu dans le cas où on souhaite faire du binding plus automatisé, notamment directement en Xaml, la solution donnée ici est un peu trop simple. L'esprit est le bon mais il manque des petites choses comme un convertisseur de valeurs.

D'autres versions plus sophistiquées

Il est bien sûr possible d'aller plus loin et de formuler une solution plus sophistiquée qui permettent de faire du binding en Xaml notamment. Je vous laisse y réfléchir, ça fait un bon excercice C# et ce n'est pas un MVP C# qui vous dira que s'entraîner mentalement de la sorte sur le langage est inutile ! :-)

Mais sachez que d'autres y ont déjà pensé et ont proposé des solutions souvent assez proches (ce problème ne peut pas être résolu de dix milles façons). En voici quelques unes dans lesquelles vous pourrez piocher matière à aller plus loin :

Silverlight c'est sympa et en plus ça fait travailler les méninges, que du bon ! 

Stay Tuned !

 

 

 

Fichiers PFX de signature de projet Visual Studio / objet déjà existant après migration Windows 7

Vous l'avez compris, l'entrée de blog d'aujourd'hui ne parle pas de Silverlight ni d'autres sujets technologiques passionnants mais d'un problème très ennuyeux intervenant après la migration sous Windows 7. Cela concerne les projets signés numériquement sous Visual Studio, ceux possédant un fichier PFX donc.

Une fois cette migration effectuée, tout semble tellement bien marcher que vous lancer fièrement Visual Studio sans vous douter du complot sournois qui se trame contre vous et qui se révèlera au moment où vous tenterez d'ouvrir une solution contenant des projets signés... Vous allez me dire, l'attente est courte. En effet, il est rare d'ouvrir VS juste pour le plaisir de le regarder, assez rapidement, même pour les plus lents d'entre nous, on finit par faire Fichier / Ouvrir (les plus créatifs préférant Fichier / Nouveau, mais ce n'est pas le sujet du jour).

A ce moment là, tous les projets signés déclenchent une importation du fichier PFX (même si vous êtes toujours sur la même machine et que rien n'a changé, n'oubliez pas que cette machine vient de migrer de Vista à 7 !). Comme vous êtes un développeur honnête, vous connaissez bien entendu les mots de passe des fichiers PFX de vos projets. Donc pas de problème vous tapez le mot de passe. Bang ! Erreur "l'objet existe déjà" (Object already exists). Et pour peu que votre solution contienne des dizaines de projets, ce qui est mon cas assez fréquemment, vous allez boucler sur cette séquence pour tous les fichiers PFX. A la fin vous pourrez travailler sur votre solution, mais à toute tentative de compilation vous vous reprendrez la même séquence : importation de la clé, demande de mot de passe, échec pour cause d'objet existant, etc pour chaque projet signé.

C'est un peu gênant... Mais il existe une raison et une solution !

La raison, en tout cas pour ce que j'en ai vu, c'est que la migration vers W7 modifie les droits du répertoire dans lequel sont cachés les clés importées. Pourquoi ? Je n'en sais rien et pour l'instant je n'ai rien trouvé sur le Web à ce sujet.

En tout cas, le problème étant identifié, il existe une solution : changer les droits et s'approprier le dit répertoire. Ca peut être plus compliqué que prévu, en tout cas j'ai galéré un peu (j'avoue franchement ne pas avoir un niveau d'expert en matière de gestion de sécurité sous Windows). En effet il faut déjà trouver le répertoire en question. (roulements de tambours) c'est... c'est... C:\Users\All Users\Microsoft\Crypto\RSA

Maintenant que faire... Clic droit sur le répertoire (dont l'image possède un petit verrou d'ailleurs, verrou qui disparaitra en fin de manip), onglet sécurité et on essaye de s'approprier tout ça. Ca plantouille car Windows répond qu'on n'a pas les droits sur xxxx (à remplacer par le nom imbuvable de chaque fichier de ce répertoire, justement ceux posant problème).

Bref, il faut y aller à la main. On entre dans le répetoire et on fait un clic droit / sécurité sur chaque fichier. Certains laissent voir la page Sécurité immédiatement. Laissez tomber. Mais un certain nombre d'autres fichiers affichent un message vous indiquant que vous n'avez pas le droit de voir l'onglet Sécurité ! Heureusement Windows vous permet de vous les approprier, donc d'en devenir le propriétaire (au passage je vois mal l'intérêt d'interdire un truc en proposant de l'autoriser, je vous l'ai dit, je ne suis pas un expert en Sécurité Windows !). C'est ce que j'ai fait pour chaque fichier. En fin de manip j'ai recommencé la modification des droits sur le répertoire lui-même, et là c'est passé. Plus de petit verrou affiché dans le symbole dossier.

Et immédiatement, Visual Studio ne redemande plus l'importation des clés. Ca remarche. Ouf !

Je suis convaincu que je m'y suis pris comme un pied pour régler le problème (il doit y avoir plus simple et plus propre que de devenir propriétaire de chaque fichier un par un), en tout cas ça règle bien le problème qui avait été bien identifié : problème de droits sur le répertoire des clés.

Pour l'instant c'est la seule surprise que j'ai eu en migrant cette machine de Vista à Windows 7. Le reste marche très bien et on ne perd rien ce qui est très appréciable (comme j'aurai aimé que cette option de migration sans douleur existe sur les anciennes versions de Windows !).

J'espère que le récit de cette mésaventure (et surtout sa solution) évitera à certains de perdre quelques heures... Si oui, n'hésitez pas à me le dire, ça fait toujours plaisir de savoir qu'un billet a été utile !

Et sir parmi vous il y en a qui sont plus doués que moi niveau sécurité Windows, qu'ils n'hésitent pas à indiquer la "bonne" manip pour arriver au résultat je modifierai en conséquence le présent billet...

Dans tous les cas, Stay Tuned !

Blend survey : donnez votre avis pour le prochain Blend 4 !

Microsoft prépare déjà la prochaine version de Blend qui, avec la version 3, est déjà un outil d'une grande maturité. Mais on peut toujours faire mieux... Alors au lieu de grogner dans votre coin, dites ce que vous aimez ou pas, proposez ce qui vous semble manquer, bref répondez au sondage lancé par l'équipe Blend : https://connect.microsoft.com/Expression/Survey/Survey.aspx?SurveyID=9391

Attention, ce sondage est assez long (pas énorme mais bien plus que trois cases à cocher) prévoyez un petit quart d'heure, et, of course, totalement en anglais avec pas mal de zones de commentaires qu'il faudra remplir dans la même langue. N'oubliez pas que google traduction est votre ami et qu'il vaut mieux donner votre avis que de vous taire, même si certains commentaires sont traduits par une machine (demandez à un collègue plus anglophone que vous de relire quand même :-) ).

A la clé, un Zune à gagner par tirage au sort. Mais surtout, un Blend 4 plus proche de vos besoins.

Alors exprimez-vous !

Création de jeux et détection de touches clavier multiples sous xaml

Xaml est conçu pour s'intégrer dans des chaînes de développement "sérieuses". Son but est principalement la création d'Apps LOB ou utilitaires le plus souvent associées à des applications métier desktop. Avec MAUI il s'agit en fait de porter WPF sur les devices mobiles et de faire ainsi converger applications "desktop" et applications mobiles de façon transparente. Mais Xaml est aussi un merveilleux outil pour écrire des jeux ou autres Apps ayant le même type d'interaction. Plus loin, et j'en parle souvent, les techniques visuelles du jeu ne sont pas à négliger pour créer des applications professionnelles disposant d'interfaces innovantes.Plus...

Le défi des nouvelles interfaces XAML - La cassure conceptuelle

J'ai l'habitude de publier ici du code, des tutors et des informations qui sont majoritairement très techniques. Il y a certains sujets où il me semble bon de prendre un peu de recul, les nouvelles interfaces utilisateurs le méritent largement. En effet, l'avalanche à la fois technologique et visuelle qui accompagne Silverlight et WPF, peut faire oublier l'objectif réel et le changement de paradigme, le nez collé à la vitrine, la tête dans le guidon pour ingurgiter les propriétés de dépendance ou les RIA Services on ne prend pas assez le temps de réfléchir plus globalement...

Ce billet sera donc une pause dans ce rush, on s'assoit, on prend le temps de réfléchir.

Pourquoi "nouvelles" interfaces ?

Comme vous l'avez certainement compris, quelque chose a changé. Il suffit de regarder Surface et son interface pour comprendre que ce changement n'est pas uniquement cosmétique, il est profond et touche aussi bien à la représentation des données qu'à l'interaction homme / machine. C'est pourquoi je parle ici de "nouvelles" interfaces utilisateur.

N'est-ce qu'une question de mode ?

Oui et non.

Oui car tout est mode chez l'humain... La façon de se coiffer, de s'habiller, la forme des voitures, celle des cafetières, etc. L'informatique, dans sa partie visuelle et interactive n'échappe pas à ce mouvement perpétuel. Le fait qu'un programme puisse se manipuler selon des concepts "à la mode" n'est donc pas "honteux" ni même accessoire ! C'est ainsi que l'humain vit, c'est ainsi qu'il imprime sa marque à l'environnement qui l'entoure.
L'humain est le seul animal a modifier son environnement pour le faire correspondre à ses rêves, là où tous les autres animaux subissent de plein fouet la sélection darwinienne et ce qu'on appelle la pression de l'environnement sans rien pouvoir y changer. Il y a donc bien un phénomène de mode dans ces "nouvelles interfaces" mais nous venons de voir que mode et civilisation humaine sont deux choses inséparables...

Non car on a tendance à associer les modes à la simple cosmétique et que le changement qui s'opère est bien plus conceptuel qu'un simple "relookage". J'y reviens plus loin.

Qu'est-ce qu'une mode ?

Pour ce qui nous intéresse ici, car sinon on pourrait en faire largement un sujet de thèse, disons qu'une mode est une façon collective et temporaire de faire les choses ou de les représenter.

Comment passe-t-on d'une mode à l'autre ?

Pour l'illustrer, une petite anecdote :

J'étais chez mon père il y a quelques jours et il venait de s'acheter une machine à café Senseo (lassé qu'il était de se faire racketter par les dosettes Nespresso du bellâtre "What else?"). Surprise ! ce modèle est rectangulaire alors que les Senseo, jusqu'à lors, était tout en rondeur (le nouveau modèle n'est d'ailleurs même pas encore sur leur site). Un changement de mode s'opère... Mais comment ? Ici on le voit, la mode était aux rondeurs, elles semblent passer aux formes plus carrées. Il est de même en informatique : Windows nous a habitués à ses débuts à des fenêtres bien rectangulaires aux angles bien droits. Ces fenêtres plates et rectangulaires ont fini par lasser. Windows avec XP et plus encore avec Vista et 7 est donc passé aux rondeurs. La "classe" absolue ayant été au début de cette mode de faire tourner ses applications dans une fenêtre non rectangulaire ! Allons-nous revenir à des fenêtres rectangulaires à l'instar des formes de la nouvelles Senseo ? Le nouveau paradigme qui préside à la conception des "nouvelles interfaces" se résume-t-il à cela ?

La cassure conceptuelle

De nombreuses modes en effet se sont juste résumées à cela : un changement de forme. Quand tout est rond on finit par revenir à quelque chose de plus carré et inversement. Le triangle, malgré sa très grande force symbolique ne se prête guère à l'affichage écran. Exit le triangle, le losage n'étant guère plus pratique, peut-être qu'un jour la mode sera aux fenêtres patatoïdes !

Les nouvelles interfaces homme / machine se situent-elles uniquement sur le plan esthétique ?

Encore une fois : Oui et non.

Oui car il est impossible pour une représentation d'échapper à la mode ambiante, ou celle à venir. Il en va de même en écriture par exemple.
On peut écrire des choses très nouvelles sur un sujet, mais il faudra bien se plier aux exigences de la langue de son pays, telle qu'elle est parlée au moment où l'on écrit.
On voit mal un philosophe contemporain ou même un simple romancier publier un ouvrage en latin ou en vieux français. Certains mots sont plus "à la mode" que d'autres, et s'il ne veut pas que sa prose "sente la naphtaline" il faudra qu'il emploie les mots, expressions et formes grammaticales de son temps.
Sinon il risque tout simplement de ne pas être lu/écouté, pire de ne pas être compris. Car la mode est un code culturel qui fait partie intégrante de la communication et donc de la compréhension entre l'émetteur et le récepteur d'une information. 
Il y a donc toujours une part d'allégeance à la mode en cours dans toute forme de communication. Cette mode pouvant même varier au sein d'une même société selon la cible visée (on ne s'adresse pas à la célèbre ménagère de moins de 50 ans des sondages comme à l'ado qui écrit en langage texto).
La mode, ainsi exprimée, s'intègre dans un corpus de règles sociales et morales plus large qu'on appelle les us et coutumes. Vouloir y échapper n'est pas forcément faire preuve d'originalité. Refuser la mode par simple réaction c'est aussi se couper de ses contemporains. Mais on peut aussi créer la prochaine mode...

Non car on assiste aujourd'hui à une cassure conceptuelle. Une rupture qui peut largement être minorée, voire ignorée, cachée qu'elle est, justement, derrière l'écran de fumée du simple phénomène de mode perçu comme seule modification esthétique.

Quelle est cette cassure conceptuelle ?

Elle est de taille ! Prenons un exemple concret : vous devez créer un logiciel de surveillance bancaire. Ici tout n'est que séries de chiffres, de pourcentages, de tendances à la hausse ou la baisse. Comment allez-vous créer l'interface d'un tel logiciel ?

La plupart des informaticiens se plongeront d'abord dans le code et poseront ensuite rapidement quelques grilles, ces horribles tableaux rectangulaires que tout éditeur de composants se doit d'avoir perfectionné à sa manière.

Va-t-il suffire de "templater" une DataGrid sous Blend en lui mettant des coins arrondis pour dire qu'on a utiliser correctement Silverlight ou WPF ?

Là, en revanche une seule réponse, claire et nette : Non !

Se servir du potentiel créatif de Silverlight et WPF ne consiste certainement pas à relooker les cases à cocher ni à "coller" un drop shadow à une boîte de dialogue ! Agir ainsi est un gâchis énorme, et surtout c'est ne pas avoir compris la cassure conceptuelle qu'impose ces outils.

Revenons à notre hypothétique application de surveillance. Supposons pour simplifier qu'elle permette à l'utilisateur d'avoir un oeil sur les actions de son portefeuille. La surveillance pouvant être activée ou désactivée pour chaque action.

La première tentation sera ainsi de représenter la liste des actions sous la forme d'une grille de données. On aura l'impression de profiter de toute la technologie en templetant la grille pour ajouter le logo de la société, des petites pastilles qui changent de couleur quand le logiciel teste une action, une autre quand l'action est à la hausse ou à la baisse, etc. On ira même jusqu'à ajouter quelques animations, c'est tellement "fun". L'utilisateur naviguera entre les pages qui coulisseront à l'écran de droite à gauche et réciproquement, etc. Là on aura eu l'impression de faire du neuf et d'exploiter à fond les possibilités de Silverlight/WPF !

Hélas, que nenni... En réalité ce qui aura été fait n'aura concerné que la seule apparence. Mettre du rond là où c'était habituellement carré ou l'inverse. C'est la mode dans son sens le plus négatif et le plus péjoratif qui soit : une lubie temporaire qui fait que si on n'a pas les dernières Nike en cour de récré on passe pour un ringard à qui plus personne ne veut parler. Angoisse permanente de l'ado moderne. C'est le côté agaçant, "fashion victim", la mode pour la mode, écervelée. Pourquoi ? Parce que la mode sans un vrai concept n'est rien.

La force du concept

Tout est concept, la réalisation n'est finalement que le passage obligé pour donner corps à un concept. Un compositeur quand il possède le concept, l'idée d'une nouvelle oeuvre, n'a pas besoin de savoir écrire des partitions ni même de savoir jouer d'un instrument. Le vrai acte de création est purement intellectuel. C'est un pur concept. Mais pour le communiquer à ses semblables il lui faudra passer par la réalisation. Souvent d'ailleurs un compositeur fera appel à un arrangeur pour tout ou partie de son oeuvre. Par exemple quelqu'un qui est spécialisé dans les parties de violons ou dans celles des cuivres. Tout le monde n'est pas Mozart, ce qui n'empêche pas des tas de compositeurs d'être connus et reconnus. Pour les films il en va de même. L'auteur n'est que rarement le réalisateur, et encore moins souvent le dialoguiste. Cela enlève-t-il de la valeur à son manuscrit sans qui le film n'existerait pas ?

Le passage au tout conceptuel est justement l'apanage de l'art contemporain. Certains y voient une fumisterie car ils n'ont pas compris qu'ici la cassure a eu lieu : la réalisation n'est que la partie visible de l'iceberg, l'essentiel de l'oeuvre se trouve dans le ... concept. C'est pourquoi le bonhomme à tête carré dessiné par votre fils de 5 ans n'a aucune valeur autre que sentimentale alors que celle d'un Picasso s'arrache à coup de millions de dollars (même si ici la spéculation purement financière vient gâcher toute la beauté de l'art, mais c'est encore un autre sujet!). Picasso n'est pas un handicapé moteur ne sachant pas faire mieux que des têtes carrées, il dessine à merveille, comme un Dali ou un Miro. Mais il a choisi de casser le moule, de s'exprimer autrement en échappant au carcan normatif, et pour cela il a beaucoup réfléchit ! Le changement est principalement et purement conceptuel, bien avant d'être dans le geste du pinceau sur la toile.

Une autre représentation du monde

Revenons à notre application bancaire. Que c'est triste comme sujet... Même relooké sous Blend, que cet étalage de chiffres sera rébarbatif. N'y-a-til pas moyen de casser le cadre, d'échapper au carcan normatif ? Ne peut-on pas ajouter quelques grammes de douceurs dans ce monde de brutes ? Un poil de poésie ?

Si, cela est possible. A condition de re-conceptualiser le rapport homme / machine, et donc les interfaces.

Un peu de poésie

Très honnêtement la bourse n'est pas un sujet qui m'inspire beaucoup de poésie mais faisons un effort !

Dans notre exemple chaque action se singularise par un nom, une quantité possédée, un cours et par un indicateur signalant si elle est surveillée ou non.

Transformons ces données en acteurs. Car le changement conceptuel est en partie là. Chaque action sera ici un acteur autonome. Ne nous reste plus qu'à choisir comment cet acteur sera représenté et dans quel univers on va le faire vivre.

Par contraste choisissons un cadre naïf à l'opposé du monde de la finance : une scène champêtre. Notre décor sera une clairière avec une forêt en arrière plan. La tendance du CAC40 ? Nous allons la représenter par le temps qu'il fait : ciel bleu neutre quand l'indice est stable, soleil caniculaire lorsque que l'indice dépasse un certain pourcentage de hausse par rapport à la veille, pluie voire tempête lorsque l'indice se casse la figure.

Voilà déjà une information conventionnelle et rébarbative représentée d'une autre façon, non conventionnelle. Imaginez-vous un écran géant, quelque part sur un mur du bureau. Un joli décor de campagne animé. Quelques nuages arrivent dans le ciel. L'oeil averti de l'utilisateur saura que le CAC40 est en baisse légère. Avec l'habitude, en comptant les nuages dans le ciel il saura même dire de combien de pourcent. Tout cela sans datagrid ni alignement de chiffres....

Mais poussons plus loin les choses et intégrons les actions à ce paysage.
Supposons que chaque action soit représentée par un animal qui va évoluer dans le décor.
Total, ce goinfre, sera peut-être representé par un sanglier fouillant le sol. Air France sera représenté par une libellule, les Ciments Lafarge par un castor, etc. Maintenant appliquons à ses animaux des comportements en fonction des données chiffrées. Le nom n'est plus une donnée à affichée, le caractère choisi pour chaque action est une identité. Une donnée de moins à afficher. La quantité d'action sera représentée par la position de l'animal : à l'avant-plan quand on possède beaucoup d'action de ce type, loin quand on en possède peu. Encore une colonne du data grid qui devient inutile. Le cours est-il à la hausse ou la baisse que l'animal aura un comportement joyeux, bondissant dans le décors, ou bien qu'il semblera mou, figé, voire couché sur le flanc au sol. Plus besoin de datagrid !

Et le caractère actif/inactif de la surveillance d'une action ? Imaginons un enclos dans le décor. Par simple Drag'drop (avec le doigt comme sur Surface) prenons un animal et posons-le dans l'enclos. Le logiciel interprètera cela comme l'exact effet d'une case à cocher "surveillance active" qui sera décochée. Reprendre l'animal et le sortir de l'enclos aura l'effet inverse.

Une idée folle ?

Fermez les yeux et imaginez ce tableau vivant un instant... Une scène de campagne avec des petits animaux qui se promènent, le temps qui change, ah, tiens, une éclaircie. Le pauvre castor a l'air bien malade se matin...

Bien entendu, certains voudront savoir ce que j'ai fumé aujourd'hui, c'est un risque que j'ai pris et que j'assume en écrivant ce billet :-)

Mais ce que nous venons de faire ici est de transformer une application rébarbative qui, dans le meilleur des cas aurait été rendu sous la forme de tableaux de chiffres aux coins arrondis servis par quelques boutons animés et une poignée de drop shadow, en une scène champêtre, charmante. Quelque chose qui donne envie de regarder le programme fonctionner juste pour le plaisir. Car les données sont devenues des acteurs, car le cadre du programme est devenu un univers auto-suffisant.

La cassure est là

Plus de cases à cocher, plus de colonnes de chiffres, plus rien de normatif ni conventionnel. Les données sont des acteurs autonomes qui racontent une histoire.

Est-ce si fou ?

Il est évident que l'exemple que j'ai pris des cours de la bourse et sa représentation gentillement niaise façon Walt Disney est un simple contrepied volontairement ironique, mais pas seulement. Imaginez-vous encore ce joli tableau dans le bureau d'un riche spéculateur... Ne pensez-vous pas que je pourrais vendre des installations complètes, très cher, et que cela marcherait ? Certainement que si. Alors que personne ne voudrait acheter le énième logiciel de gestion de portefeuille que je pourrais écrire, même relooké sous Blend ! Certains même parleraient alors de snobisme, de gadget. Ceux qui ne pourraient s'offrir mon système bien entendu. Mais pas les utilisateurs qui l'achèteraient et qui en seraient très contents ! La "mode" serait lancée !

Ce qu'il faut donc comprendre ici c'est que les "nouvelles interfaces utilisateurs" l'UX (User eXperience), ce nouveau paradigme dont je parle ici bien souvent et depuis un moment maintenant, n'est pas "qu'une mode", c'est un changement conceptuel, donc en profondeur, du rapport entre l'homme et la machine. C'est une nouvelle façon de penser les données non plus comme des informations passives mais comme des acteurs autonomes évoluant dans un univers vivant.

Et concrètement ?

Tout cela est bien gentil, mais certains se disent (les plus courageux, ceux qui sont arrivés jusqu'à cette ligne ! - merci au passage :-) ) que bon, ils ont un soft à faire pour hier et qu'ils voient mal comment tout ce gentil délire peut s'appliquer à une compatibilité analytique ou une facturation.

Je leur répondrais que si j'ai pu tranformer, même virtuellement dans ces lignes, une application de gestion portefeuille boursier en une scène de campagne tout peut être fait !
Pourquoi ne pas transformer les comptes clients en bulles de couleurs évoluant dans un aquarium, plus la bulle est grosse plus l'encours du client est important, ou bien pour les commerciaux, plus la bulle devient grosse plus il est temps d'appeler le client car il n'a pas passé de commande depuis longtemps. Quelques jolis écrans plats sur les murs du service commercial ou dans le bureau du patron permettraient immédiatement de suivre la vie de l'entreprise, sans chiffres, sans cases à cocher ni boutons radio, sans fenêtre aux coins ronds ou non...

Application exemple

Dans mon temps perdu (autant dire pas grand chose) je suis en train de faire une petite application Silverlight qui met en pratique ces concepts pour faire comprendre comment on passe de mes explications à un vrai logiciel qui fait quelque chose de réel. Le code C# de l'application est déjà écrit et testé, c'est bien entendu le look qui prend le plus de temps dans un tel cas. Des mock-up en 3D, du sketching sur des bouts de papier, des dessins sous Expression Design, il me reste à mettre tout cela en forme sous Blend.

Un autre exemple existe depuis quelques années, il n'est pas logiciel mais bien du domaine informatique tout de même : le lapin Nabaztag. Tiens, il baisse l'oreille gauche... le CAC 40 se casse la figure. Ah, il devient rouge, ma chérie a laissé un message sur mon répondeur... Le créateur du Nabaztag a tout compris de cette cassure conceptuelle et des nouvelles interfaces utilisateur...

Si le sujet vous intéresse, et pour voir prochainement une illustration de ce que je viens d'expliquer ici, alors une seule solution :

Stay Tuned !

Créer un arbre des répertoires avec XML (et l'interroger avec LINQ to XML)

Pour les besoins d'un prochain billet je voulais obtenir une structure arborescente de test sous la forme d'un fichier XML. Une telle chose peut se faire à la main mais cela est fastidieux et à force de copier/coller les données seront trop semblables et donc peu utilisables pour des tests et du debug, ce qui est dommage puisque tel était le but recherché...

Pour générer des données aléatoires mais réalistes je possède déjà un outil fantastique (puisque c'est moi qui l'est fait :-) ), DataGen, un logiciel puissant mais qui n'est pas étudié pour générer des données dont la strucuture est récursive. Restait donc à concevoir un utilitaire pour satisfaire mon besoin de l'instant.

Je n'aime pas développer "pour rien" donc il fallait que cet utilitaire en soit bien un. Tout disque dur de développeur contient une telle quantité de données que l'ensemble des répertoires forment une superbe structure arborescente ni trop petite ni trop gigantesque. Exactement ce qu'il faut pour des tests ! Ainsi, l'outil devra fabriquer un fichier XML à partir de n'importe quel niveau de répertoire, la structure étant hiérarchique.

Je m'empresse donc de vous faire partager ce petit bout de code qui vous sera utile un jour ou l'autre je pense.

using System;
using System.IO;
using System.Linq;
using System.Xml.Linq;
 
namespace Enaxos.Tools.Xml
{
    /// <summary>
    /// This class can generate an XML file from a folder hierarchy.
    /// </summary>
    public static class DirToXml
    {
        /// <summary>
        /// Builds the tree document.
        /// </summary>
        /// <param name="dirname">The name of the starting folder.</param>
        /// <returns>a LINQ to XML <c>XDocument</c></returns>
        public static XDocument BuildTreeDocument(string dirname)
        {
            return new XDocument(new XDeclaration("1.0", "utf-8", "yes"), 
                new XComment("Structure au "+DateTime.Now),new XElement("directories", BuildTree(dirname)));
        }
 
        /// <summary>
        /// Builds the tree (recursive method).
        /// </summary>
        /// <param name="dirName">Name of the starting folder.</param>
        /// <returns>a LINQ to XML <c>XElement</c> being the root (or 1st item) of the tree.</returns>
        public static XElement BuildTree(string dirName)
        {
            var di = new DirectoryInfo(dirName);
            var files = di.GetFiles();
            var dirsize = 0l;
            foreach (var file in files)
            {
                dirsize += file.Length;
            }
            var subdirs = di.GetDirectories();
            // each item is a "directory" having 5 attributes
            // name is the name of the folder
            // fullpath is the full path including the name of the folder
            // size is the size of all files in the folder (in bytes)
            // files is the number of files in the folder
            // subdirs is the count of possible sub directories in the folder
            var elem = new XElement("directory", 
                new XAttribute("name", di.Name), 
                new XAttribute("fullpath",dirName),
                new XAttribute("size", dirsize),
                new XAttribute("files",files.Count()),
                new XAttribute("subdirs",subdirs.Count()));
            foreach (var dinf in subdirs)
            {
                var elemDir = BuildTree(dirName + "\\" + dinf.Name);
                elem.Add(elemDir);
            }
 
            return elem;
        }
    }
}

Ce code peut être utilisé sans passer par un fichier disque puisqu'on récupère le document en mémoire. L'exemple ci-dessous montre comment appeler le code et comment interroger la structure via Linq To Xml pour connaître les répertoires vides (n'ayant ni fichier ni sous répertoire) :

   1:  var d = DirToXml.BuildTreeDocument(@"D:\WpfToolkit");
   2:  d.Save(@"d:\test.xml");
   3:  Console.WriteLine(d.ToString());
   4:  Console.WriteLine(new string('-',60));
   5:   
   6:  var q = from e in d.Descendants("directory")
   7:          where (int) e.Attribute("files") == 0
   8:               && (int)e.Attribute("subdirs") == 0
   9:               orderby (string) e.Attribute("fullpath")
  10:               select e.Attribute("fullpath");
  11:   
  12:  Console.WriteLine("Répertoires vides");
  13:  foreach (var element in q)
  14:    { Console.WriteLine(element); }
  15:  Console.WriteLine(string.Format("{0} répertoires vides",q.Count()));

 

A bientôt pour un prochain billet, so.. Stay Tuned !

Devoir de vacances

J'ai pris quelques jours de vacances bien mérités. Mais comme un geek ne part jamais sans son portable, forcément ça a été studieux !

Vous avez pu lire mes deux derniers billets, "Xaml l'ami des artistes" qui présente Enaxos Art, une petite vitrine Silverlight de travaux graphiques, ou bien hier l'annonce de la sortie de Silverlight 3 final et de Blend 3 RC avec Sketchflow.

Hélas les vacances se terminent. Mais comme je suis un filou et que mardi est férié, le retour ne se fera que Mercredi. Encore 48h de bonheur et de farniente à goûter aux joies des effets de perspectives 3D de Silverlight 3 et des nouveautés de Swift 3D de Electric Rain dont la V6 vient de sortir et avec laquelle je m'amuse bien !

Très vite la rentrée va approcher et avec elle les bonnes résolutions qu'on ne tient jamais. C'est tous les ans la même chose, alors en m'y prenant presque deux mois avant j'espère bien trouver cette année des résolutions tellement vagues qu'il ne sera pas vraiment possible de dire que je ne les ai pas tenues ! "Puisque ces mystères nous dépassent, feignons d'en être les instigateurs" disait sagement Cocteau !

Pour rester dans la sagesse populaire je vous prépare quelques tutors sur toutes ces nouveautés car comme le dit cette fois-ci le vieux romain qui sommeille en chaque auteur : Qui scribit bis legit ! (celui qui écrit lit deux fois !).

Ave ! Et bronzez bien à l'ombre de vos portables (le soleil c'est dangereux pour la peau, l'eau des plages est pleine de colibacilles fécaux et les rues sont bondées de touristes, mieux vaut donc rester au frais à développer et à se former !).

Stay tuned !

XML/XAML pretty printer gratuit

Il arrive souvent que du code XML soit produit "au kilomètre" sans mise en forme particulière. Même si Internet Explorer sait afficher un tel fichier en le mettant en forme automatiquement, on souhaite parfois disposer d'une version formatée lisible par un humain.

ODPrettyXml, un utilitaire console très simple qui ne fait que ça... Il traite les fichiers XML, mais aussi du XAML sans souci. Toutefois vous remarquerez que ODPrettyXml travaille toujours sur un fichier de sortie différent de l'original, certaines transformations pourraient avoir des effets non souhaités. L'utilitaire est donc avant tout conçu comme un "pretty printer" dont la vocation est de rendre le document plus lisible pour un humain. Les fichiers produits, même s'ils restent fonctionnels, n'ont pas vocation a être utilisé en programmation.

Pour le mode d'emploi, tapez ODPrettyXml sous console, l'aide sera affichée. Le programme ne demandant aucune saisie, il est possible de l'utiliser dans des fichiers de commandes (ou des batchs).

La syntaxe la plus habituelle est "ODPrettyXml <nom du fichier>" qui fabriquera automatique un fichier de sortie de même nom se terminant par "pretty" suivi de l'extension du fichier original (par exemple: toto.xml donnera toto.pretty.xml).

Si vous tapez "ODPrettyXml ?" vous obtiendrez la liste de tous les encoders connus et utilisables avec leur code page. C'est le nom qu'il faut utiliser en 3eme paramètre de ODPrettyXml. Par exemple pour utiliser unicode il faut taper "ODPrettyXml <source> <sortie> utf-16". Quand un encodeur est spécificé, il faut aussi saisir le nom du fichier de sortie (2d paramètre).

Dernière remarque, ODPrettyXml ne fait qu'encoder le fichier et le mettre en forme avec des indentations, notamment il ne contrôle pas si l'encodage demandé est conforme à celui déclaré dans le fichier source. Un fichier indiquant qu'il est codé en UTF-8 peut être encodé en UTF-16, son entête indiquera toujours UTF-8, le fichier n'est pas modifié par ODPrettyXml.

Téléchargement : odPrettyXml.exe (34,00 kb)
(exécutable .NET 3.5, mode console)
(projet VS 2008 complet. Le fichier de signature électronique est absent vous devrez en créer un autre).
Amusez-vous bien !
Et Stay Tuned pour d'autres nouvelles (notamment un gros article à venir les Splash screen sous Silverlight !)
(PS: l'aide du logiciel a quelques coquilles, à vous de les trouver et les corriger :-) )

F# et le "paradoxe de la secte"

F#, fils (ou frère ?) de OCaml, langage intégré à la prochaine version de Visual Studio, fait son buzz ...

Comme toute nouveauté, ne pas connaître c'est risquer de passer pour un idiot à la machine à café (voire à la cantine ou au chinois du coin le midi, l'effet est le même, juste qu'il est plus facile de quitter la machine à café en prétextant un truc urgent à faire que de se lever de table sans avoir fini son rouleau printemps).

De fait ne pas s'informer est en réalité un double crime : d'abord professionnel (rester au courant est un minimum syndical quand on est payé pour faire un job), ensuite social (passer pour un hasbeen est lourd à porter).

Heureusement je veille au grain et grâce à DotBlog vous ne commettrez pas ce double impair !

F# est un langage issu des labos de Microsoft. S'il est très proche de OCaml (au départ totalement compatible) il s'en éloigne par plusieurs points, ne serait-ce qu'en raison de sa parfaite intégration à l'édifice .NET.

Tout le problème avec un nouveau langage c'est qu'il place l'informaticien dans une situation embarassante. Car on attend d'un informaticien qu'il parle d'informatique et qu'il connaisse les outils propres à son métier. Jusqu'à là rien d'anormal. Mais concernant un langage on se retrouve vite devant ce que j'appelle le "paradoxe de la secte" : Soit vous n'y appartenez pas et toutes vos critiques et réserves seront balayées par ses partisans au principe que n'y appartenant pas vous n'en connaissez rien et que votre avis est totalement subjectif, soit vous y appartenez et le bien que vous en direz, tout comme le mal éventuellement, sera considéré comme sujet à caution par tous ceux qui n'appartiennent pas à la dite secte ...

Mais cela pose tout de même un sacré problème : peut-on dire du bien ou du mal d'un nouveau langage de programmation sans avoir écrit un vrai logiciel avec, ou doit-on forcément être capable de réécrire Excel en un week end avec un langage pour pouvoir prétendre donner son avis sur ce dernier ?

J'aime les paradoxes pour le jeu. Mais je n'aime pas l'inconfort intellectuel du "paradoxe de la secte" surtout appliqué à mon métier qui est en quelque sorte une apologie à la Logique et où le monde se règle à coups de If Then Else. Des If avec un Then mais sans Else c'est de la programmation risquée. Et d'ailleurs pour revenir au sujet, F# oblige l'utilisation de Else. Pour cette même raison (c'est risqué). Logique, mais peut-être casse pied à l'usage, il faut voir...

Souhaitant échapper au paradoxe de la secte, je ne vous donnerai pas un avis technique profond sur F#, mais je vous invite à lire une série de billets introduisant la syntaxe de F# pour vous faire vous-même une idée de la chose et je vous propose de venir laisser vos impressions en commentaires afin qu'on puisse en discuter. "Présentation de F#" par Laurent Le Brun

L'article est fait de petits billets, donc c'est facile à lire. En retour c'est un peu sommaire et pas forcément très expliqué, mais on ne peut pas tout avoir. En tout cas ça vous en dira suffisamment pour vous faire une idée, et surtout pour tester la syntaxe si vous téléchargez le langage (ce qui n'est pas nécessaire avec la bêta de VS2010, téléchargeable ici : http://www.microsoft.com/visualstudio/en-us/products/2010/default.mspx).

Je vous demandais plus haut de venir ajouter en commentaire votre avis sur F#, autant commencer par donner le mien penserez-vous. C'est oublier le "paradoxe de la secte" dans lequel cela me plongerait malheureux ! Mais comme c'est pour vous, j'ai testé un peu F#, échappant de justesse au paradoxe : ni je n'en connais rien, ni je n'en connais tout, en toute logique le paradoxe ne s'applique plus à mon cas :-) (c'est discutable, je sais, mais tout ce qui est discutable laisse chacun dans la possibilité de croire qu'il a raison !).

Bref, F# c'est jeune, c'est sympa, c'est de la "programmation fonctionnelle" (super classe et dans le vent), donc c'est bien. Peut-être. Ou peut-être pas. A petites doses, sous le couvert de LINQ, au d'extensions de C#, je ne dis pas. Exclusivement et en plat unique et principal, est-ce digeste ? J'ai un doute.

Si La syntaxe F# est "amusante" elle me semble peu lisible, peut-être par manque d'habitude. Toutefois quand on passe de C ou Java à C# on n'a pas cette impression, ni même de Delphi à Java ou réciproquement. Alors première "mauvaise impression" ou bien réalité ? Le problème c'est qu'il faudrait devenir bon en F# pour le comparer et savoir si on l'aime ou pas.. L'horrible et incontournable paradoxe de la secte qui revient ! Donc je suis obligé de rester au niveau subjectif et mon avis n'a rien de technique. De prime abord, je n'aime pas trop la syntaxe donc.

Par exemple il existe un mode "light" (devenant visiblement la "norme"). Dans ce mode la syntaxe devient plus "light" mais au prix que je trouve insensé de donner une valeur réelle à l'espace (le caractère espace, pas starwars hein..). C'est à dire que les blocs ne se déclarent plus avec des mots clés de début et de fin (ou les {} de C#), mais sont uniquement basés sur l'indentation du texte à l'espace près, les tabulations étant interdites.
Utiliser les espaces pour indenter c'est bien, ne pas pouvoir utiliser les tabulations c'est un peu embêtant, mais lorsque qu'on sait que ces espaces ont aussi un impact sur le code ça me dérange un peu. Que le nombre d'espaces devant une instruction puisse modifier son sens ou sa portée m'apparait un dangereux défaut. Mais ce n'est peut-être que par manque de pratique.

Quant à l'esprit du langage, dans la foulée des langages ML comme LISP, ce dernier m'a toujours paru trop abscons pour devenir populaire et jusqu'à lors, en 25 ans de métier aucun de ces langages n'a démenti cette impression et n'est devenu un blockbuster. F# sera-t-il celui qui me fera mentir ? Saura-t-il séduire les foules de développeurs en soif de nouveautés ? Ou bien restera-t-il juste un bel essai boudé par les mêmes informaticiens déjà gavés "jusqu'à là" de trucs nouveaux à apprendre sous .NET (et super géniaux comme Entity Framework, Silverlight, ASP.NET MVC, etc) ?

Wait and see dirais-je sagement pour ne pas trop me mouiller :-)

F# est plein de bonnes idées, mais sa syntaxe et son esprit me semblent difficilement compatible avec l'industrialisation du développement. Caml, OCaml, LISP et consors ne sont jamais sortis de leur cercle d'initiés. L'industrie du logiciel n'en a pas voulu. F# possède-t-il le petit "plus" qui lui permettra d'étendre son influence plus largement que ces prédécesseurs ? Nous verrons bien !

Alors j'attends vos avis et impressions !