Je suis en train de construire ma première véritable application WPF (c'est-à-dire la première destinée à être utilisée par quelqu'un d'autre que moi), et je suis encore en train de m'habituer à la meilleure façon de faire les choses en WPF. C'est une application d'accès aux données assez simple utilisant l'Entity Framework encore assez récent, mais je n'ai pas pu trouver beaucoup de conseils en ligne sur la meilleure façon d'utiliser ces deux technologies (WPF et EF) ensemble. J'ai donc pensé présenter ma façon de procéder et voir si quelqu'un a de meilleures suggestions.
-
J'utilise l'Entity Framework avec SQL Server 2008. L'EF me semble à la fois beaucoup plus compliqué qu'il ne devrait l'être et pas encore mature, mais Linq-to-SQL semble mort, donc autant utiliser la technologie sur laquelle Microsoft semble se concentrer.
-
C'est une application simple, donc je n'ai pas (encore) jugé bon de construire une couche de données distincte autour d'elle. Quand je veux accéder aux données, j'utilise des requêtes Linq-to-Entity assez simples, généralement directement depuis mon code-behind, par exemple :
var families = from family in entities.Family.Include("Person") orderby family.PrimaryLastName, family.Tag select family;
-
Les requêtes Linq-to-Entity renvoient un résultat IOrderedQueryable, qui ne reflète pas automatiquement les changements dans les données sous-jacentes, par exemple, si j'ajoute un nouvel enregistrement via du code au modèle de données de l'entité, l'existence de ce nouvel enregistrement n'est pas automatiquement reflétée dans les divers contrôles référençant la requête Linq. Par conséquent, je place les résultats de ces requêtes dans une ObservableCollection pour capturer les changements des données sous-jacentes :
familyOC = new ObservableCollection(families.ToList());
-
Je mappe ensuite l'ObservableCollection sur un CollectionViewSource, afin de pouvoir effectuer des filtres, des tris, etc., sans avoir à retourner à la base de données.
familyCVS.Source = familyOC; familyCVS.View.Filter = new Predicate(ApplyFamilyFilter); familyCVS.View.SortDescriptions.Add(new System.ComponentModel.SortDescription("PrimaryLastName", System.ComponentModel.ListSortDirection.Ascending)); familyCVS.View.SortDescriptions.Add(new System.ComponentModel.SortDescription("Tag", System.ComponentModel.ListSortDirection.Ascending)); Je lie ensuite les divers contrôles et autres éléments à ce CollectionViewSource : Quand j'ai besoin d'ajouter ou de supprimer des enregistrements/objets, je le fais manuellement à la fois dans le modèle de données de l'entité et dans l'ObservableCollection : private void DeletePerson(Person person) { entities.DeleteObject(person); entities.SaveChanges(); personOC.Remove(person); } J'utilise généralement des contrôles StackPanel et DockPanel pour positionner les éléments. Parfois j'utilise un Grid, mais il semble difficile à maintenir : si vous voulez ajouter une nouvelle ligne en haut de votre grille, vous devez toucher directement chaque contrôle hébergé par la grille pour lui dire d'utiliser une nouvelle ligne. Argh. (Microsoft n'a jamais vraiment semblé comprendre le concept DRY.) Je n'utilise presque jamais le designer WPF de VS pour ajouter, modifier ou positionner des contrôles. Le designer WPF fourni avec VS est vaguement utile pour voir à quoi votre formulaire va ressembler, mais là encore, pas vraiment, surtout si vous utilisez des modèles de données qui ne sont pas liés à des données disponibles au moment de la conception. Si je dois modifier mon XAML, je l'accepte et je le fais manuellement. La plupart de mon vrai code est en C# plutôt qu'en XAML. Comme je l'ai mentionné ailleurs, indépendamment du fait que je n'aie pas encore l'habitude de "penser" en XAML, XAML me semble être un langage maladroit et laid, qui vient aussi avec un support du designer et de l'intellisense médiocres, et qui ne peut pas être débogué. Argh. Par conséquent, chaque fois que je peux voir clairement comment faire quelque chose en code-behind C# que je ne peux pas facilement voir comment faire en XAML, je le fais en C#, sans faire d'excuses. Il a été écrit à profusion qu'il était une bonne pratique de presque ne jamais utiliser le code-behind dans une page WPF (disons, pour la gestion d'événements), mais pour l'instant du moins, cela ne me semble pas du tout logique. Pourquoi devrais-je faire quelque chose dans un langage laid et maladroit avec une syntaxe affreuse, un éditeur étonnamment mauvais et pratiquement aucune sécurité de type, quand je peux utiliser un langage agréable et propre comme le C# qui a un éditeur de classe mondiale, un intellisense presque parfait et une sécurité de type inégalée ? Voilà où j'en suis. Des suggestions ? Est-ce que j'ai oublié des éléments importants ? Est-ce que je devrais vraiment penser à faire les choses différemment ?