Bonjour,

Je souhaite dans mon application pouvoir filtrer une collection selon une entrée utilisateur. J'utilise actuellement une CollectionViewSource comme source de donnée d'un ListView. A cette CollectionViewSource est lié une ObservableCollection<Song> où Song est une classe que j'ai crée. J'ai vu qu'il n'était pas possible de filtrer les données avec le CollectionViewSource, cependant j'ai pu voir sur MSDN qu'il existe une ListCollectionView avec une propriété Filter. C'est bien mais cela ne résout pas tous mes problèmes.

En effet je souhaite pouvoir récupérer des informations sur ce qui a été filtrer. La collection contient en effet des objet de type Song, et je souhaite pouvoir par exemple compter le nombre d'artiste concerné par le filtrage de ma collection de Song, le nombre d'album que cela représente. Et malheureusement je ne vois pas de propriété qui permettent de récupérer la liste filtrer afin que par la suite justement je puisse faire les traitements appropriés pour avoir les résultat. De plus je ne souhaite pas me limiter à ces opérations, par exemple, je souhaite que quand un utilisateur lance une chanson (en double cliquant sur une des chansons de la liste) ce n'est que la collection filtrer qui soit lu. Donc mon besoin de filtrer n'est pas que visuel, il faut que par la suite je puisse récupérer cette liste filtrée puis la distribuer à mes différents models qui en auront besoin.

Donc pour le moment je me suis limité à faire le filtre moi même, en utilisant LINQ, je commence d'abord par faire un where(). Je me retrouve alors avec une collection filtrée, ensuite pour connaitre les différentes count nécessaire, je fais par exemple un regroupement suivi d'un count (par exemple pour connaitre le nombre d'artiste dans le collection filtrée: GroupyBy(c => c.Artist).Count()). Et cela deux fois, une fois pour le nombre d'artiste et une autre pour le nombre d'album. Je me retrouve alors avec les informations que je souhaite, et une collection que je peux manipuler et transmettre. Ensuite ce que je fait, c'est que je crée une nouvelle ObservableCollection qui reçoit en paramètre pour son constructeur ma liste filtrée, et cette Observable va être assigné à la source de ma CollectionView. Donc au final ça fait quand même beaucoup de bouclage sur mes collections.

Maintenant ma contrainte est que pour filtrer j'attends une entrée utilisateur, pour cela j'ai mis une TextBox et c'est tout. Le filtrage doit pouvoir se faire en "temps réel". Pour cela j'ai par exemple dans mon ViewModel associé une propriété string "CurrentFilter" à la propriété Text du TextBox, donc dès que Text change CurrentFilter aussi puis j'enclenche ma fonction de filtrage juste derrière. Maintenant ce qui se passe c'est quand je souhaite entrer très rapidement quelque chose dedans, ou encore effacer beaucoup de lettre en maintenant appuyé la touche retour, ça "rame" pas mal. J'ai fait des test sur une collection ne contenant que 3000 éléments, mais il se pourrait qu'il y en ai bien plus et alors le résultat serait encore plus dramatique. J'ai tenté de trouver des petites astuces, d'abord activer la Virtualisation sur ma ListView. Puis si le texte entré contient juste une lettre de plus (par exemple: Abb devient Abba), je réutilise la précédente liste filtré pour ne pas consulter toute la collection de chanson entière.

Pour ce projet personnel, je tente de "recopier" une autre application existante, et sur cette application cette fonctionnalité est très fluide. Après c'est très certainement pas le même langage, pas le même Framework, pas la même logique derrière. Mais ce serait dommage que je ne puisse réussir a obtenir le même résultat avec du C# et .NET. Donc je me retrouve à ne pas vraiment savoir d'où le problème de performance peut venir, est-ce ma machine (un vieux Athlon 64 3000+), mon code qui filtre qui est mal pensé, le langage ou les Control qui ne permettent pas d'avoir une exécution suffisamment rapide. Je ne savais pas dans quelle section poster cela, et je me suis dit que WPF serait pas mal vu que mon appli est faite là dessus.

Je suis désolé de ne pas pouvoir poster de code, je suis au bureau et je n'ai pas le projet sous la main. Je sais que ça va pas forcement aider à m'aider, mais je me dit qu'en exposant déjà mon problème, peut être avez-vous déjà des idées, astuces, conseils à donner, comme ça en rentrant ce soir je pourrais éventuellement tester quelque chose. J'espère avoir été claire dans mes explications.

Je vous remercie d'avance pour votre aide.