IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Presentation Foundation Discussion :

Problème de filtre dans une ListView


Sujet :

Windows Presentation Foundation

  1. #1
    Membre habitué Avatar de Thrud
    Profil pro
    Développeur .NET
    Inscrit en
    Avril 2008
    Messages
    170
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Avril 2008
    Messages : 170
    Points : 183
    Points
    183
    Par défaut Problème de filtre dans une ListView
    Bonjour,

    j'essaie d'ajouter des items un par un dans une listview suivant un filtre. J'utilise la méthode PassesFilter() pour savoir si l'élément considéré peut être ajouté. Le problème est que le premier item est TOUJOURS inséré dans la liste la première fois.

    Voici un exemple dans lequel j'insère des chaines de caractères que 'One' à 'Five', en éliminant les chaines de moins de 4 caractères.
    Pourquoi est-ce que 'One' se retrouve dans la liste ?

    ------ window1.xaml -------
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    <Window x:Class="TestListviewFilter.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TestListviewFilter"
    Title="Window1" Height="300" Width="300">
     
    <StackPanel>
    <Button Click="Button_Click">Add to List</Button>
    <local:FilteredListView x:Name="TheList" />
    </StackPanel>
    </Window>
    ------ window1.xaml.cs -------

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
     
    namespace TestListviewFilter
    {
        /// <summary>
        /// Logique d'interaction pour Window1.xaml
        /// </summary>
     
        public partial class Window1 : Window
        {
            public Window1()
            {
                InitializeComponent();
            }
     
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                System.Collections.Generic.List<String> oObjects = new List<string>();
                oObjects.Add("One");
                oObjects.Add("Two");
                oObjects.Add("Three");
                oObjects.Add("Four");
                oObjects.Add("Five");
                foreach (object obj in oObjects)
                {
                    if (TheList.Items.PassesFilter(obj))
                        TheList.Items.Add(obj);
                }
            }
        }
    }
    -------------- FilteredListView.cs -------------------
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
     
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows.Controls;
     
    namespace TestListviewFilter
    {
     
        public class FilteredListView : ListView
        {
            public FilteredListView()
            :base()
            {
                if (Items.CanFilter)
                {
                    Items.Filter += new Predicate<object>(ApplyFilter);
                }
            }
     
            private bool ApplyFilter(object obj)
            {
                return (obj.ToString().Length > 4);
            }
        }
    }

  2. #2
    Membre expert
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    2 210
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 210
    Points : 3 015
    Points
    3 015
    Par défaut
    Pour savoir, PassesFilter (cf. 2eme code) = ApplyFilter (cf. 3eme code) ?

    ou

    PassesFilter est une autre fonction que tu as oublié de nous montrer ?

    [EDIT] Autant pour moi je ne connaissais pas cette méthode du ListView ou plutôt de ItemCollection

  3. #3
    Membre habitué Avatar de Thrud
    Profil pro
    Développeur .NET
    Inscrit en
    Avril 2008
    Messages
    170
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Avril 2008
    Messages : 170
    Points : 183
    Points
    183
    Par défaut
    PassesFilter() est une méthode de la classe ItemCollection, le type de l'attribut 'Items' dans la ListView.
    Elle est censée appeler les Predicats (en l'occurrence ici, la méthode ApplyFilter) enregistrés dans l'attribut 'Filter' des Items.

  4. #4
    Membre expert
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    2 210
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 210
    Points : 3 015
    Points
    3 015
    Par défaut
    Si tu remplaces ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
                foreach (object obj in oObjects)
                {
                    if (TheList.Items.PassesFilter(obj))
                        TheList.Items.Add(obj);
                }
    par

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TheList.ItemsSource = oObjects;
    Ca marche.

    Je pense que PassesFilter est à utilisé dans des cas particuliers... pour vérifié qu'un item de la liste a bien sa raison d'y être

  5. #5
    Membre expert
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    2 210
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 210
    Points : 3 015
    Points
    3 015
    Par défaut
    Si tu veux vraiment ajouter des items un par un...

    Tu peux toujours faire un truc bourrin comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
          TheList.Items.Add( "toto" );
          TheList.Items.Remove( "toto" );
    au tout début.

    Parce que apparemment le premier item n'est jamais testé...

  6. #6
    Membre habitué Avatar de Thrud
    Profil pro
    Développeur .NET
    Inscrit en
    Avril 2008
    Messages
    170
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Avril 2008
    Messages : 170
    Points : 183
    Points
    183
    Par défaut
    Merci, en effet, j'ai vu que ça fonctionne si j'utilise ItemsSource.

    Mon problème est que je ne voulais pas utiliser ItemsSource, j'ai besoin de manipuler les Items, l'exemple ici n'est qu'un cas simpliste pour reproduire le problème.
    En fait, les items sont apportés dans la liste par Drag'n' drop, et je voulais utiliser PassesFilter pour savoir si j'ai le droit de les dropper dans la liste.

  7. #7
    Membre habitué Avatar de Thrud
    Profil pro
    Développeur .NET
    Inscrit en
    Avril 2008
    Messages
    170
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Avril 2008
    Messages : 170
    Points : 183
    Points
    183
    Par défaut
    Citation Envoyé par binoo Voir le message

    Parce que apparemment le premier item n'est jamais testé...
    Oui, en suivant en debug, je ne passe pas par le Predicat pour le premier item, c'est assez étrange.

  8. #8
    Membre habitué Avatar de Thrud
    Profil pro
    Développeur .NET
    Inscrit en
    Avril 2008
    Messages
    170
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Avril 2008
    Messages : 170
    Points : 183
    Points
    183
    Par défaut
    Ok, je vais prendre la solution bourrin pour le moment, parce que ça ressemble quand même à un bug, le comportement ne me semble pas très normal...
    J'ai posé la question chez Microsoft aussi.

    Merci

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Débutant] Problème de tri dans une listview
    Par Jean-Luc80 dans le forum VB.NET
    Réponses: 10
    Dernier message: 08/09/2013, 18h43
  2. Problème de sélection dans une ListView
    Par Sake_reflex dans le forum Composants graphiques
    Réponses: 1
    Dernier message: 29/10/2012, 13h44
  3. Problème de caractères dans une ListView
    Par MegaNoob dans le forum Débuter
    Réponses: 3
    Dernier message: 02/06/2012, 17h06
  4. Problème d'affichage dans une ListView
    Par tabbabi dans le forum Composants graphiques
    Réponses: 2
    Dernier message: 10/08/2011, 12h58
  5. Problème de filtre dans une requetes
    Par vlksoft dans le forum Requêtes et SQL.
    Réponses: 10
    Dernier message: 09/12/2008, 14h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo