2010-02-19 8 views
2

En Delphi, j'ai une classe qui est basée sur TList. C'est TPetList. Chaque instance de TPetList peut avoir certains éléments de la classe TPet. L'instance de TPetList est affichée dans un composant TListView à l'aide d'une boucle for.Delphi 7: Sélectionnez certains éléments d'un TList

TPet est basé sur TObject et a les champs suivants:

  • ville
  • âge
  • race

Maintenant, j'ai une liste de cases à cocher où l'utilisateur peut cocher les races il veut voir. Donc, s'il veut seulement voir des animaux de race XYZ, je veux montrer seulement les entrées qui ont la valeur de "race" définie sur "XYZ" tandis que l'ordre dans TPetList et TListView doit rester le même.

Comment est-ce que je peux faire ceci?

Si je supprime les éléments dans TPetList et affiche le reste dans TListView, tout va bien jusqu'à ce que l'utilisateur veuille voir une autre race. Cette race a été supprimée avant et ne peut être montrée.

Répondre

3

Au lieu de supprimer, essayez de sélectionner une nouvelle liste. Quelque chose comme ça:

function TPetList.Filter(criteria: TPetCriteria): TPetList; 
var 
    i: integer; 
begin 
    result := TPetList.Create; 
    for i := 0 to self.Count - 1 do 
    if criteria.matches(self[i]) then 
     result.add(self[i]); 
end; 

La façon dont vous implémentez les critères dépend de vous, mais c'est l'idée générale. Rappelez-vous que la liste renvoyée est une sous-vue et que ne possède pas les éléments qu'il contient, ne les libérez donc pas lorsque vous libérez la liste filtrée.

+0

Oh, c'était si simple: D Merci beaucoup, cela fonctionne très bien. – caw

1

Vous pouvez stocker vos objets dans un ensemble de données. (Vous pouvez utiliser des jeux de données de mémoire comme TClientDataSet, TjvMemoryData de JVCL ou tout autre descendant de TDataSet y compris SGBDR entière)

De cette façon, vous avez résolu les problèmes suivants:

  • persistance (stockage) - SGBDR sera prends soin de ça. Dans le cas des jeux de données de mémoire que vous avez des méthodes telles que la charge/SaveToFile
  • Trier - Il existe des méthodes simples pour le faire ou si vous choisissez un backend SQL un 'SELECT * FROM PETS ORDER BY NAME' simples faire votre travail
  • Filter - vous pouvez faire tout réversible Filtrage sur n'importe quel champ avec n'importe quel opérateur que vous aimez. Dans le cas de jeux de données de mémoire définissant la propriété Filter à Breed = "foo" et la propriété Filtered à "True" est suffisant. Dans le cas de RDBMS, vous pouvez l'obtenir de la même manière et/ou en utilisant un SQL standard: 'SELECT * FROM PETS WHERE BREED='foo' ORDER BY NAME. Aussi, vous pouvez utiliser l'événement OnFilterRecord pour cela. Vous pouvez effacer le filtre, en inversant l'action: Définir la propriété Filter sur 'False' - ou - émettre un SQL comme: 'SELECT * FROM PETS' (sans la clause WHERE), etc.
  • Édition - vous avez des contrôles dédiés pour chaque type de données (y compris les grilles pour l'entrée multi-rangée). Par exemple. pour le champ 'Age', l'entrée est limitée aux nombres seulement. Et, bien sûr, vous avez l'événement OnValidate où vous pouvez faire un test si 'Age' est entre 0 et 33 (par exemple).

Vous avez tout le mécanisme en place. Peut-être vaut-il mieux suivre cette voie plutôt que de réinventer la roue.

+0

Merci, mais mon Delphi 7 ne connaît pas TDataSet, je ne sais pas pourquoi. – caw

+0

@ marco92w: Essayez de regarder dans l'unité DB. –

+0

@ marco92w: TDataSet est une classe 'cachée'. Le grand-père de tous. Vous ne pouvez pas le voir. C'est pourquoi j'ai dit TDataSet ** descendant **. Recherchez TClientDataSet (si vous avez la version Architect (? IIRC ...)) ou Google pour 'JEDI JVCL', installez-le et recherchez TjvMemoryData (sur la page Jv Data Access). De plus, si vous voulez utiliser un moteur de base de données complet, allez à l'aide de Delphi 7 et recherchez 'Building database applications' (ou similaire). –