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

Composants VCL Delphi Discussion :

Comment filtrer une TListBox ?


Sujet :

Composants VCL Delphi

  1. #1
    Membre averti
    Avatar de jmjmjm
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2005
    Messages
    760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2005
    Messages : 760
    Points : 439
    Points
    439
    Par défaut Comment filtrer une TListBox ?
    Je souhaiterai filtrer une listBox:
    J'ai une TEDit dans laquelle je rentre le debut d'un nom
    et je voudrai que le contenue de la listBox evolue en fonction de ce qui est tappé
    Exemple lorsque je tappe av :
    dans la listBox tout les mots commence par av : Avion,avec , ....

  2. #2
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Salut
    Un méthode consiste à mettre ta liste de mots dans une liste (TStringList par exemple) et une autre qui contient la liste filtrée... A chaque fois que le contenu du TEdit change tu fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
      for i:=0 to ListFiltre.Count-1 do
      begin
        if Copy(ListeFiltre.Strings[i],1,length(Edit1.Text))=Edit1.text then
        //Ajoute à la liste Filtrée
      end;
    Evidemment, il faudra que tu prennes en compte si le TEdit est vide
    Pedro
    Aucune réponse aux sollicitations techniques par MP

    Faut pas attendre d'en avoir besoin pour s'en servir... (Lucien Stéphane)

    Les pages Source C'est bon. Mangez-en!
    Le défi Delphi
    Règles du forum - FAQ Delphi - Pensez au chtit
    Aéroclub Bastia Saint-Exupéry

  3. #3
    Membre averti
    Avatar de jmjmjm
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2005
    Messages
    760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2005
    Messages : 760
    Points : 439
    Points
    439
    Par défaut
    merci pedro je test ca ce soir

  4. #4
    Membre averti
    Avatar de jmjmjm
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2005
    Messages
    760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2005
    Messages : 760
    Points : 439
    Points
    439
    Par défaut
    je n'arrive pas a faire marcher ta fonction peux tu me faire un exemple stp ! sa me met une erreur!

  5. #5
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Quelle erreur ? qu'il ne connait pas la fonction Copy ?

    As-tu bien mis le code de Pedro24 dans l'évènement OnChange de ton TEdit ???

    Exemple de code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    procedure TForm1.Edit1Change(Sender: TObject);
    var i:integer;
    begin
     ListBox1.clear;
     for i:=0 to ListFiltre.Count-1 do
      begin
        if Copy(ListeFiltre.Strings[i],1,length(Edit1.Text))=Edit1.text then
        ListBox1.Items.Add(ListeFiltre.Strings[i]);
      end; 
    end;
    Ailleurs dans ton code, initialises tu bien ListeFiltre ?
    Bidouilleuse Delphi

  6. #6
    Membre averti
    Avatar de jmjmjm
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2005
    Messages
    760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2005
    Messages : 760
    Points : 439
    Points
    439
    Par défaut
    Merci pour le code ca marche niquel c'est le ComboBox1.clear qui me manquait tout mes resultat se mettait a la suite et j'avais pas fait attention quoi qu'il en soit mon petit souci avec ce code est qu'il est extremement lent je gere 15000 entrées environ y a t'il moyen de l'accelerer

  7. #7
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Oui, il y a moyen :
    Dans ma fiche, j'ai mis :
    - 1 TEdit
    - 1 TListBox

    Voici le code :

    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
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
     
    type
      TForm1 = class(TForm)
        ListBox1: TListBox;
        Edit1: TEdit;
        procedure Edit1Change(Sender: TObject);
        procedure FormShow(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
        ListeFiltre:TStringList;
        function DebutMot(Index,Longueur:Integer):string;
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
    function TForm1.DebutMot(Index,Longueur:Integer):string;
    begin
      result:=Copy(ListeFiltre.Strings[Index],1,Longueur);
    end;
     
    procedure TForm1.Edit1Change(Sender: TObject);
    var i,ALength:integer;
        AText:string;
    begin
     ListBox1.clear;
     AText:=Edit1.Text;
     ALength:=length(AText);
     Form1.cursor:=crHourGlass;
     Application.ProcessMessages;
     if ALength=0 then 
     begin 
       //ListBox1.Items.AddStrings(ListeFiltre);  //<--ligne optionnelle
       Form1.cursor:=crDefault;
        Exit;
     end;
     
      i:=0;
     while ((i<ListeFiltre.Count-1) and (DebutMot(i,ALength)<AText)) do Inc(i);
     while ((i<ListeFiltre.Count-1) and (DebutMot(i,ALength)=AText)) do
     begin
       ListBox1.Items.Add(ListeFiltre.Strings[i]);
       Inc(i);
     end;
     Form1.cursor:=crDefault;  
    end;
     
    procedure TForm1.FormShow(Sender: TObject);
    begin
      ListeFiltre.LoadFromFile('mots.txt');
      ListeFiltre.Sort;
    end;
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      ListeFiltre:=TStringList.Create;
    end;
     
    procedure TForm1.FormDestroy(Sender: TObject);
    begin
      ListeFiltre.Free;
    end;
     
    end.
    C'est un poil plus rapide (ma liste de mots fait 336531 mots !, je l'ai eu ici : http://www.pallier.org/ressources/dicofr/dicofr.html)

    Tu as remarqué que j'ai zappé le remplissage de la liste quand le mot dans la TListBox est égal à '' (rien du tout). Donc, si tu n'as que 15000 mots tu peux tenter l'affichage de tous les mots en enlevant les marques de commentaire // devant la ligne optionnelle.

    Tiens nous au courant !
    A+
    Bidouilleuse Delphi

  8. #8
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Comme dans ma liste de mots, j'avais des accents, ça ne marchait pas nickel, voici qui est corrigé :
    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
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ComCtrls;
     
    type
      TForm1 = class(TForm)
        ListBox1: TListBox;
        Edit1: TEdit;
        procedure Edit1Change(Sender: TObject);
        procedure FormShow(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
        ListeFiltre:TStringList;
        function DebutMot(Index,Longueur:Integer):string;
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
    uses strutils;
     
    function EnleverAccents(S: string): string;
    const
      CHAINE_DEPART =  'àäâãçéèêëìïîôöòûüùÿÁÀÄÂÃÉÈÊËÍÎÌÔÖÒÓÕÜÛÙÚÝ';
      CHAINE_ARRIVEE = 'aaaaceeeeiiiooouuyyAAAAAEEEEIIIOOOOOUUUUY';
    var
      i, Position: Integer;
    begin
      for i:=1 to Length(S) do
      begin
        Position:=Pos(S[i],CHAINE_DEPART);
        if Position > 0 then    // Si c'est accentué ...
          S[i]:=CHAINE_ARRIVEE[Position]; // On met le carac correspondant non accentué.
      end;
      Result:=S;
    end;
     
    function TForm1.DebutMot(Index,Longueur:Integer):string;
    var UnMot:string;
    begin
      UnMot:=ListeFiltre.Strings[Index];
      result:=EnleverAccents(Copy(UnMot,1,Longueur));
    end;
     
    procedure TForm1.Edit1Change(Sender: TObject);
    var i,ALength:integer;
        AText:string;
    begin
     ListBox1.clear;
     RichEdit1.Clear;
     AText:=EnleverAccents(Edit1.Text);
     ALength:=length(AText);
     Form1.cursor:=crHourGlass;
     Application.ProcessMessages;
     if ALength=0 then
     begin
    //   ListBox1.Items.AddStrings(ListeFiltre);
       Form1.cursor:=crDefault;
       Exit;
     end;
     i:=0;
     while ((i<ListeFiltre.Count-1) and (DebutMot(i,ALength)<AText))
     do Inc(i);
     while ((i<ListeFiltre.Count-1) and (DebutMot(i,ALength)=AText)) do
     begin
       ListBox1.Items.Add(ListeFiltre.Strings[i]);
       Application.ProcessMessages;
       Inc(i);
     end;
     Form1.cursor:=crDefault;
      Application.ProcessMessages;
    end;
     
    procedure TForm1.FormShow(Sender: TObject);
    begin
      ListeFiltre.LoadFromFile('mots.txt');
    end;
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      ListeFiltre:=TStringList.Create;
    end;
     
    procedure TForm1.FormDestroy(Sender: TObject);
    begin
      ListeFiltre.Free;
    end;
     
    end.
    Bidouilleuse Delphi

  9. #9
    Membre averti
    Avatar de jmjmjm
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2005
    Messages
    760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2005
    Messages : 760
    Points : 439
    Points
    439
    Par défaut
    Merci c'est nikel

  10. #10
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    J'ai apporté quelques optimisations et corrections :
    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
    procedure TForm1.Edit1Change(Sender: TObject);
    var i,ALength:integer;
        AText:string;
    begin
     ListBox1.Items.BeginUpdate; //<--vachement plus rapide
     ListBox1.clear;
    //RichEdit1.Clear;  <-- à virer !
     AText:=EnleverAccents(Edit1.Text);
     ALength:=length(AText);
     Form1.cursor:=crHourGlass;
     //Application.ProcessMessages;  <-- à virer, si l'utilisateur tape trop vite
     if ALength=0 then
     begin
    //   ListBox1.Items.AddStrings(ListeFiltre);
      ListBox1.Items.EndUpdate;
       Form1.cursor:=crDefault;
       Exit;
     end;
     i:=0;
     while ((i<ListeFiltre.Count-1) and (DebutMot(i,ALength)<AText))
     do Inc(i);
     while ((i<ListeFiltre.Count-1) and (DebutMot(i,ALength)=AText)) do
     begin
       ListBox1.Items.Add(ListeFiltre.Strings[i]);
       //Application.ProcessMessages;  <-- à virer, si l'utilisateur tape trop vite
       Inc(i);
     end;
     Form1.cursor:=crDefault;
     ListBox1.Items.EndUpdate;
      Application.ProcessMessages;
    end;
    Bidouilleuse Delphi

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 04/05/2009, 12h12
  2. Comment filtrer une requete sous mysql (ODBC)
    Par samir44 dans le forum ASP.NET
    Réponses: 2
    Dernier message: 31/07/2007, 14h44
  3. Comment filtrer une DataGrideView (affichage)
    Par rdh123 dans le forum C#
    Réponses: 4
    Dernier message: 17/07/2007, 19h02
  4. Réponses: 4
    Dernier message: 25/05/2007, 17h04
  5. comment filtrer une table avec deux criteres càd 2 colonnes
    Par athmane2dz dans le forum Bases de données
    Réponses: 7
    Dernier message: 28/07/2004, 15h25

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