Question

Ainsi, WPF ne prend pas en charge le comportement de tri ou de filtrage standard pour les vues de CompositeCollections, alors quelle serait la meilleure pratique pour résoudre ce problème.

Il existe au moins deux collections d'objets de types différents.Vous souhaitez les combiner en une seule collection triable et filtrable (sans devoir implémenter manuellement le tri ou le filtre).

L'une des approches que j'ai envisagées consiste à créer une nouvelle collection d'objets avec seulement quelques propriétés principales, y compris celles sur lesquelles je souhaite que la collection soit triée, et une instance d'objet de chaque type.

class MyCompositeObject
{
    enum           ObjectType;
    DateTime       CreatedDate;
    string         SomeAttribute;
    myObjectType1  Obj1;
    myObjectType2  Obj2;
{
class MyCompositeObjects : List<MyCompositeObject> { }

Et puis parcourez mes deux collections d'objets pour créer la nouvelle collection composite.Évidemment, c’est un peu une méthode de force brute, mais cela fonctionnerait.J'obtiendrais tout le comportement de tri et de filtrage des vues par défaut sur ma nouvelle collection d'objets composites, et je pourrais y mettre un modèle de données pour afficher correctement les éléments de ma liste en fonction du type réellement stocké dans cet élément composite.

Quelles sont les suggestions pour procéder de manière plus élégante ?

Était-ce utile?

La solution 3

Mise à jour:J'ai trouvé une solution beaucoup plus élégante :

class MyCompositeObject
{
    DateTime    CreatedDate;
    string      SomeAttribute;
    Object      Obj1;
{
class MyCompositeObjects : List<MyCompositeObject> { }

J'ai trouvé qu'en raison de la réflexion, le type spécifique stocké dans Obj1 est résolu au moment de l'exécution et le DataTemplate spécifique au type est appliqué comme prévu !

Autres conseils

Je ne connais pas encore très bien WPF mais je vois cela comme une question de tri et de filtrage List<T> collections.

(sans devoir implémenter manuellement un tri ou un filtre)

Reconsidéreriez-vous la mise en œuvre de vos propres fonctions de tri ou de filtrage ?D'après mon expérience, il est facile à utiliser.Les exemples ci-dessous utilisent un délégué anonyme mais vous pouvez facilement définir votre propre méthode ou une classe pour implémenter un tri ou un filtre complexe.Une telle classe pourrait même avoir des propriétés permettant de configurer et de modifier dynamiquement le tri et le filtre.

Utiliser List<T>.Sort(Comparison<T> comparison) avec votre fonction de comparaison personnalisée :

// Sort according to the value of SomeAttribute
List<MyCompositeObject> myList = ...;
myList.Sort(delegate(MyCompositeObject a, MyCompositeObject b) 
{
    // return -1 if a < b
    // return 0 if a == b
    // return 1 if a > b
    return a.SomeAttribute.CompareTo(b.SomeAttribute);
};

Une approche similaire pour obtenir une sous-collection d’éléments de la liste.

Utiliser List<T>.FindAll(Predicate<T> match) avec votre fonction de filtre personnalisée :

// Select all objects where myObjectType1 and myObjectType2 are not null
myList.FindAll(delegate(MyCompositeObject a)
{
    // return true to include 'a' in the sub-collection
    return (a.myObjectType1 != null) && (a.myObjectType2 != null);
}

La méthode "force brute" que vous mentionnez est en fait la solution idéale.Attention, tous les objets sont dans la RAM, il n'y a pas de goulot d'étranglement d'E/S, vous pouvez donc trier et filtrer des millions d'objets en moins d'une seconde sur n'importe quel ordinateur moderne.

La manière la plus élégante de travailler avec les collections est l'espace de noms System.Linq dans .NET 3.5

Merci - j'ai également considéré Linq aux objets, mais ma préoccupation il y a une perte de flexibilité pour les modèles de données typés, dont j'ai besoin d'afficher les objets de ma liste.

Si vous ne pouvez pas prédire à l'heure actuelle comment les gens trieront et filtreront votre collection d'objets, alors vous devriez regarder System.Linq.Expressions espace de noms pour créer vos expressions lambda à la demande pendant l'exécution (vous laissez d'abord l'utilisateur créer l'expression, puis compilez, exécutez et à la fin vous utilisez l'espace de noms de réflexion pour énumérer les résultats).Il est plus difficile de comprendre cela, mais c'est une fonctionnalité inestimable, probablement (pour moi définitivement) une fonctionnalité encore plus révolutionnaire que LINQ lui-même.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top