Entity Framework est d’une grande puissance mais c’est parfois une machine délicate. Le cas de Inlcude avec une jointure en est un exemple vivant, l’Include semble ne pas fonctionner… Mais il y a une solution…More...
Quand on utilise Wcf Ria Services on utilise souvent côté serveur Linq To Entities. Et quand on utilise Linq on aime bien tester ses requêtes avec l’outil LinqPad. Voici un ménage à trois qui nous réserve parfois des surprises, des bonnes et des moins bonnes...More...
Linq et ses merveilles... Linq et ses jointures... Parlons-en des jointures : savez-vous comment faire une jointure sur plusieurs champs à la fois ?More...
WCF Ria Services est une mécanique de précision. En démo tout est toujours simple et évident, dans la réalité on rencontre toujours quelques cas plus retors et pas forcément dans des features ultra sophistiquées... Par exemple le chargement d’entités associées réclame de connaitre la double astuce que je vais vous présenter.More...
Les Parallel Extensions, connues jusqu’à lors sous le nom de Parallel Framework Extensions (ou PFX) forment une librairie permettant de faciliter la construction d’algorithmes parallèles (multi-thread) tirant partie des machines multi-cœur. Je vous en avais déjà parlé, ainsi que de P-Linq les extensions parallèles pour LINQ. Deux choses importantes à savoir aujourd’hui : les Parallel Extensions font partie de .NET 4 (VS 2010, Silverlight…) et une nouvelle librairie arrive, les Reactive Extensions !More...
Vous possédez un OS récent, comme Windows 7, vous développez avec les outils les plus modernes (disons VS 2010 au hasard) et, bien entendu votre base de données installée en local est SQL Server 2008. D’une part parce que c’est une bonne version, mais surtout parce que vous n’avez pas trop le choix… Vous créez une application pour un client qui utilise SQL Server 2005 et là, pof! dès qu’il exécute votre logiciel il y a une exception du genre “The version of SQL Server in use does not support datatype 'datetime2”… More...
Promis dans mon dernier billet, le voici enfin ! Ce nouvel article dédié au binding Xaml pèse 77 pages (le record était tenu jusqu’à lors par mon article M-V-VM avec Silverlight avec 70 pages) et se présente sous la forme d’un PDF et de 9 projets exemples.
Le binding cet inconnu … J’en parlais dans mon billet Le retour du spaghetti vengeur, le binding avec sa syntaxe pleine d’accolades et de chaînes de caractères non contrôlées à la compilation est un piège à bugs et la porte ouverte au code spaghetti.
Plutôt que de me lamenter et vous laisser vous embourber dans la sauce de ces spaghetti là, j’ai pris ma plume, et voici le résultat : 77 pages sur le binding Xaml, son fonctionnement, ses différentes syntaxes le tout illustré par des exemples clairs. L’article aborde aussi le débogue du binding assez délicat puisque Xaml échappe au débogueur de Visual Studio, et que le binding n’est que partiellement couvert par Intellisense.
Des conseils, du vécu, beaucoup d’exemples, voilà ce que vous trouverez dans cet article à télécharger en suivant le lien suivant :
Le Binding Xaml – Maîtriser sa syntaxe et éviter ses pièges (WPF/Silverlight)
(Attention, avant de cliquer sur le bouton “télécharger” attendez que la fiche détail de l’article soit bien affichée, sinon le site pensera que vous tentez un accès à une ressource non publique et vous demandera un login… Je reçois tous les jours des demandes d’ouverture de compte provenant de lecteurs trop impatients qui cliquent trop vite sur le bouton ! La prochaine version du site en Silverlight est en préparation et corrigera ce petit problème, mais d’ici là : slow down cowboy !).
Pour vous aider à vous faire une idée du contenu de l’article voici son sommaire :
Sommaire
- Références 5
- Code Source 6
- Préambule 7
- Le Binding Xaml : Ange ou Démon ? 7
- Le Binding 8
- Définition 8
- Utilisations 9
- Schéma du principe 9
- Déclaration 10
- Les modes de binding 13
- Le mode OneTime 13
- Le mode OneWay 13
- Le mode TwoWay 14
- Le mode Default 16
- Le mode OneWayToSource 16
- Hiérarchie de valeur 18
- La notion de DataContext 20
- Les convertisseurs de valeur 21
- Définition 21
- Scénario 21
- Implémentation 22
- Utilisation 23
- Instanciation 23
- Invocation 23
- Bonnes pratiques 24
- Pour résumer 26
- Les dangers du Binding 27
- Des chaînes non contrôlées 27
- Un langage dans le langage 28
- On fait quoi ? 28
- Déboguer le Binding 28
- Vigilance 28
- Une code Xaml court 29
- Refactoring sous contrôle 29
- Utiliser des outils intelligents 29
- Utiliser Expression Blend 29
- Vérifier les erreurs de binding dans la fenêtre de sortie 30
- Créer un fichier des erreurs de Binding 30
- La feinte du convertisseur inutile 32
- Quelques outils supplémentaires 33
- Spy++ 33
- ManagedSpy 33
- Snoop 34
- Mole 34
- Reflector 34
- Vos neurones 34
- Les syntaxes du Binding 34
- Le binding simple 34
- Binding direct 35
- Binding sur une propriété 35
- Binding sur une sous-propriété du contexte 36
- L’Element Binding 37
- Convertisseurs de valeur 37
- Paramètres de conversion 38
- StringFormat 40
- Injection de culture 41
- Le ContentStringFormat 42
- Gérer les nuls 43
- Le Binding Multiple 44
- La classe Personne 44
- Le code du multi convertisseur 45
- Le code Xaml 46
- Le Binding XML 47
- Binding sur une source Web 47
- Binding sur une source XML en ressource 48
- Binding sur une requête Linq To XML 49
- Le Binding Relatif 52
- Binding to Self 52
- Le TemplatedParent Binding 53
- Le Binding sur recherche d’ancêtre 54
- Le Binding PreviousData 56
- La source de données 58
- La visibilité des flèches : la magie de PreviousData et du Binding Multiple 58
- Le contenu des textes 61
- Le Template binding 61
- Le Collection Binding 67
- Le Priority Binding 69
- Les propriétés de tous les bindings 74
- Conclusion 76
Avril est froid et pluvieux mais les soirées rallongent, c’est le printemps même si cela n’y ressemble pas encore beaucoup, grâce à moi vous savez maintenant comment occuper vos soirées et vos weekend au lieu de faire l’idiot dans les embouteillages des vacances : Lisez cet article !
Et Stay Tuned !
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 !
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 !
Dans la jungle des technologies .NET il est intéressant de savoir ce que vous utilisez déjà en production et ce que vous prévoyez d'utiliser dans ce contexte. Je parle bien de production, pas des essais que nous faisons tous et qui remplissent nos machines, non, uniquement ce qui est installé chez des clients (ou utilisateurs) ou en cours de développement.
Comme je ne vais pas vous demander de laisser un message à ce billet et puis faire le tri après, pour faire plus simple j'ai mis en place un petit sondage. D'ici quelques temps je "relèverai les compteurs" et je les publierai ici. Répondre à ce sondage est ainsi un moyen simple pour que nous sachions les uns les autres ce qui est utilisé (ou en prévision d'utilisation).
Merci d'avance de prendre une minute pour réponse au sondage qui se trouve ici :
Cliquez ici pour lancer le sondage.
Stay Tuned pour les résultats (et pour bien d'autres news entre temps...) !