[Delphi] ListView plus rapide/tableau avec zone clickable

ListView plus rapide/tableau avec zone clickable [Delphi] - Programmation

Marsh Posté le 15-04-2002 à 22:03:20    

Salut à tous,
j'avais demandé la semaine passée comment faire une espèce de stringgrid où l'on pourrait clicker sur un élément pour avoir plus d'ample détail.  Le problème était le suivant: j'affiche un tableau avec un numéro et un titre de BD et je voudrais clicker sur le numéro pour avoir le détail de la BD en question.
 
On m'a dit d'utiliser une ListView en mode rapport, ce qui solutionnait en effet mon problème.  Mais ce composant est très lent dès qu'on affiche beaucoup de ligne (j'en ai 3000 à afficher et sur mon P3, ça prend 5 secondes...  Le programme devant tourné sur un 166 mmx, j'ose même pas essayer)...
 
Merci de votra attention :)

Reply

Marsh Posté le 15-04-2002 à 22:03:20   

Reply

Marsh Posté le 15-04-2002 à 22:29:34    

Quand tu remplis ou vide la listview, tu dois lui dire qu'il doit pas la mettre à jour tout de suite:
 
with ListView1.Items do
begin
  BeginUpdate;
  ... ici tu ajoutes tous tes items ...
  EndUpdate;
end;
 
Même chose pour le Clear;


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 15-04-2002 à 22:40:49    

Bon, ma question risque de te parraître très conne, mais tu fais comment pour ajouter des Items.  En fait, j'ai trouvé dans l'aide de delphi un code comme ça:
 
var ListItem: TListItem;
 
...
bouclebegin
  ListItem := ListView1.Items.Add;
  ListItem.Caption := yap[i];
  ListItem.SubItems.Add(youp[i]);
bouclefin
...
 
Et bon, avec cette méthode, si je met le with ListView1 do avant la boucle, ça change rien au point de vue vitesse...

Reply

Marsh Posté le 15-04-2002 à 22:53:30    

with ListView1.Items do  
begin
  BeginUpdate;
  for i := 0 to 1000 do
  begin
    ListItem := Add;   // Ici comme on est dans le with on a pas besoin de refaire ListView1.Items
    ListItem.Caption := yap[i];
    ListItem.SubItems.Add(youp[i]);
  end;
  EndUpdate;
end;
 
 
Encore plus optimisé:
 
with ListView1.Items do  
begin
  BeginUpdate;
  for i := 0 to 1000 do
    with Add do
    begin
      Caption := yap[i];
      SubItems.Add(youp[i]);
    end;
  EndUpdate;
end;


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 15-04-2002 à 23:10:18    

Bon, j'ai compris.  En effet, ça marche (je vois qu'il ne rafraichit plus l'écran pendant que les éléments s'ajoutent), mais...  ça prend toujours le même temps :)  C'est pas très grave, la recherche sur tout les éléments de la base ne devant pas être fait très souvent...  mais c'est quand même bizarre.  Avec une StringGrid, l'affichage prenait environs une seconde, avec la ListView, ça en prend 5 (montre en main :) )...

Reply

Marsh Posté le 15-04-2002 à 23:14:22    

C'est bizarre que ça prenne toujours aussi longtemps... C'est peut-être la façon dont tu vas récupérer le contenu de chaque élément qui est lent alors ?
Ou lors tu as mis le begin/endupdate dans la boucle for :D


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 15-04-2002 à 23:17:19    

antp a écrit a écrit :

C'est bizarre que ça prenne toujours aussi longtemps... C'est peut-être la façon dont tu vas récupérer le contenu de chaque élément qui est lent alors ?
Ou lors tu as mis le begin/endupdate dans la boucle for :D  




 
Non, quand même, le begin/endupdate sont hors de la boucle...  j'avais quand même compris ton truc :)  Pour la manière de récupérer les éléments, c'est vrai qu'elle est dégueux (je suis obligé de travailler avec une base MySQL qui ne supporte pas les requêtes imbriquée, donc, je les fais à la main...) mais bon, ça n'explique pas qu'avec la StringGrid, ça marche à toute vitesse... (le code est le même, à la base, les requêtes n'ont pas été modifiée)...

Reply

Marsh Posté le 15-04-2002 à 23:49:40    

Si c'est un DBGrid c'est normal que ça aille vite, il affiche juste le contenu de la table...
Sinon faut faire une requête hors de la boucle, en une fois, et ensuite tout mettre dans la liste.


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 16-04-2002 à 08:48:34    

antp a écrit a écrit :

Si c'est un DBGrid c'est normal que ça aille vite, il affiche juste le contenu de la table...
Sinon faut faire une requête hors de la boucle, en une fois, et ensuite tout mettre dans la liste.  




Non, c'est une StringGrid (je me trompe parfois de mot) car j'utilise une librairie MySQL qui ne permet pas d'utiliser des DBgrid (en fait, la lib me sort un tableau à deux dimmensions de pointeurs).  Donc, j'ai en effet deux boucles pour afficher mon résultat:  
  for i = ... nbrdenregistrement
     for j = ... nbrdecolonne
et dans une StringGrid, l'affichage se fait très très vite, par contre, comme je l'ai déjà dit, quand j'utilise la ListView, c'est hyper lent...
 
Un copain m'a dit que c'était normal vu que la listview est composé d'objet listitem (<> stringgrid qui est simplement composée de string), que la création 3000 objets est assez complexe (il y a 7 subitems pour chaque items) et vu que la création des items se fait objet après objets (on ne peut pas (ou alors, j'ai pas trouver), allouer les 3000 objets d'un coup et les remplir par après) ben...
 
Et c'est pour ça que je cherchais éventuellement une autre solution, mais personne ne semble avoir d'idée... (est-ce que quelqu'un se sert vraiment de Delphi d'ailleurs :) )...  Parce qu'en on y pense, je veux juste une StrinGrid sur laquelle on peut cliquer sur chaque élément (en HTML, on ferait un bête tableau avec des liens hypertexte dans une des colonnes...  et ça, ben j'trouve pas :sweat: )

Reply

Marsh Posté le 16-04-2002 à 09:24:06    

Comme tu as déjà ta grille de pointeurs, ce que tu peux essayer c'est le TVirtualTree : http://www.lischke-online.de/VirtualTreeview/VT.html
C'est un peu difficile à prendre en main, mais c'est nettement plus léger que le TListView si tu as beaucoup d'élements.
Sinon il y a une solution entre les deux : TElTree. C'est un peu comme le TListView/TTreeView mais plus léger, surtout quand il y a beaucoup d'éléments dedans : http://www.eldos.org (J'arrive pas à me connecter au site, mais il fonctionnait il y a quelques jours. Il faut prendre TElTree Lite, il est gratuit).


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 16-04-2002 à 09:24:06   

Reply

Marsh Posté le 16-04-2002 à 10:22:12    

je ne vois pas où est ton problème avec la StringGrid, tu peux tout à fait connaitre la position de la cellule dans laquelle on clique via les propriétés col et row.
 
perso j'utilise le composant XStringGrid qui est une évolution et permet le support entre autre de fontes<>pour chaque colonne/entête, des éditeurs spécialisés (combo, spin, calendrier + éditeurs personnels)
 
il est gratuit, avec source, tu le trouveras à l'adresse http://www.eye.ch/~mduerig/prog/index.htm

Reply

Marsh Posté le 16-04-2002 à 11:00:27    

Le gros problème des stringgrid est qu'elles ne permettent pas de changer la zone clickable quand la souris passe dessus.  Il faut que, lorsque la souris pointe sur un élément, on remarque visuellement qu'on peut clicker dessus (style, l'élément devient bleu et souligné).  De plus, tous les éléments ne doivent pas être clickable.
 
La solution apportée par les ListView correspond exactement à ce que je recherche, mais bon... c'est lent.  Par contre, je vais jeter un coup d'oeil à ton composant...

Reply

Marsh Posté le 16-04-2002 à 11:22:13    

pour les trucs en plus j'imagine que cela ne doit pas etre trop dur à coder, tu peux utiliser la methode MouseToCell pour connaitre la colonne et la ligne située sous le curseur de ta souris

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed