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

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Delphi 11 : TControlList et sélection multiple
Un billet blog de SergioMaster

Le , par SergioMaster

0PARTAGES

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;

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
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

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;

Une erreur dans cette actualité ? Signalez-nous-la !