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)
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 |
1 2 3 4 | procedure TFormTest.FormCreate(Sender: TObject); begin ControlList1.MultiSelect:=True; end; |
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 |
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; |
mais le résultat déçoit
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 |
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; |
Vous avez lu gratuitement 7 507 articles depuis plus d'un an.
Soutenez le club developpez.com en souscrivant un abonnement pour que nous puissions continuer à vous proposer des publications.
Soutenez le club developpez.com en souscrivant un abonnement pour que nous puissions continuer à vous proposer des publications.