IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Voir le flux RSS

Blog de Serge Girard (aka SergioMaster)

[Actualité] TControlList et sélection multiple

Note : 2 votes pour une moyenne de 3,00.
par , 11/11/2023 à 12h03 (4176 Affichages)
La version Delphi 11 a apporté la possibilité de faire une multiple sélection d'éléments avec les classiques manipulations de clavier (Ctrl+Click, Ctrl+Shift+Click). Si je n'avais rien publié à ce sujet, c'est parce que l'obtention des éléments sélectionnés me paraissait boguée (ce qui a d'ailleurs fait l'objet d'une demande sur le portail qualité RSP-40821). En effet, lorsque l'on tentait d'obtenir la liste des éléments sélectionnés, souvent le dernier élément était omis.

L'objectif de ce billet est de vous montrer le symptôme et surtout de proposer une solution.

Le design du programme est simple :
  • Un TControList, l'élément contiendra un TLabel pour afficher une valeur
  • Un TMemo.
  • Un TButton.
  • Et, pour ce qui est des données, un TProtypeBindSource pour obtenir une liste de contact.

Comme déjà montré dans mes billets sur ce composant, il faudra utiliser LiveBinding pour lier la liste à la source de données et au libellé (Label1)

Nom : Capture_listD.PNG
Affichages : 6518
Taille : 26,5 Ko

Cette fonctionnalité de multiple sélection doit être activée par code

Pour les besoins de mon test, je le fais dès la création de la forme.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
procedure TFormTest.FormCreate(Sender: TObject);
begin
ControlList1.MultiSelect:=True;
end;
La version 12 propose une propriété mutiselect accessible au design.

Pour obtenir la liste des éléments sélectionnés, il faut parcourir l'ensemble des éléments et tester si oui ou non, il l'est.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
procedure TFormTest.btnListeSelectionClick(Sender: TObject);
begin
Memo1.Lines.Clear; // efface l'ancien résultat
for var i:= 0 to ControlList1.ItemCount-1 do   // parcourir l'ensemble des élémnts
  if ControlList1.Selected[i] then                    // élément sélectionné ?
   begin
        ControlList1.ItemIndex:=i;                   // se positionner dessus pour accéder à label1 
        Memo1.Lines.Add(i.ToString+ ' - '
                                   +label1.caption); 
    end;
end;
À l'exécution, la sélection fonctionne
Nom : Capture_List1.PNG
Affichages : 2859
Taille : 14,5 Ko
mais le résultat déçoit
Nom : Capture_List2.PNG
Affichages : 2863
Taille : 17,0 Ko
Christine Jones, dernier nom sélectionné, n'est pas listé dans le mémo et n'apparait plus comme tel dans la TControlList
La faute en est très certainement au repositionnement pour accéder à label1.

P.S. Cet effet sera beaucoup plus visible si vous jouez avec les ItemSelectionOptions permettant de modifier couleurs et transparences
  • HotColor
  • SelectedColor
  • FocusedColor
  • HotColorAlpha
  • SelectedColorAlpha
  • FocusedColorAlpha


et même la couleur de fonte selon l'état
  • HotFontColor
  • SelectedFontColor
  • FocusedFontColor
  • UseFontColorForLabels



Maintenant, voici comment contourner ce problème
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
procedure TFormTest.btnListeSelectionClick(Sender: TObject);
var lastSelected : integer;
begin
Memo1.Lines.Clear;
// mémorise la position
LastSelected:=ControlList1.ItemIndex;
// au cas où l'élément ne ferait pas partie de la sélection
// ne devrait pas arriver
if not ControlList1.Selected[LastSelected] then LastSelected:=-1;
for var i:= 0 to ControlList1.ItemCount-1 do
  if ControlList1.Selected[i] OR (i=lastSelected)
  then
   begin
        ControlList1.ItemIndex:=i;
        Memo1.Lines.Add(i.ToString+
                        ' - '+label1.caption);
end;
// Se repositionner sur le dernier élément sélectionné
ControlList1.ItemIndex:=LastSelected;
// redessiner la liste
ControlList1.Invalidate;
end;
Nom : Capture_list3.PNG
Affichages : 2862
Taille : 16,5 Ko

Envoyer le billet « TControlList et sélection multiple » dans le blog Viadeo Envoyer le billet « TControlList et sélection multiple » dans le blog Twitter Envoyer le billet « TControlList et sélection multiple » dans le blog Google Envoyer le billet « TControlList et sélection multiple » dans le blog Facebook Envoyer le billet « TControlList et sélection multiple » dans le blog Digg Envoyer le billet « TControlList et sélection multiple » dans le blog Delicious Envoyer le billet « TControlList et sélection multiple » dans le blog MySpace Envoyer le billet « TControlList et sélection multiple » dans le blog Yahoo

Catégories
Programmation , Delphi

Commentaires

  1. Avatar de kStar
    • |
    • permalink
    La propriété Label1 doit me sembe-t-il être préfixée par la TList.
  2. Avatar de SergioMaster
    • |
    • permalink
    Absolument pas, label1 ne contient toujours qu'une seule et unique valeur. TcontrolList est un composant VCL avec d'étranges affinités FMX mais bien que l'ont ai l'impression que le label appartienne au composant ce n'est pas vraiment le cas