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

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Delphi Discussion :

[CheckListBox] avec un seul item coché ?


Sujet :

Delphi

  1. #1
    Membre Expert
    Avatar de Droïde Système7
    Homme Profil pro
    Inscrit en
    Septembre 2003
    Messages
    2 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 2 288
    Par défaut [CheckListBox] avec un seul item coché ?
    Bonjour

    Je bute devant un problème tout bête...

    Je cherche la méthode afin d'obtenir dans une CheckListBox qu'un seul item coché possible, oui un seul = celui coché tout simplement.

    J'ai cherché un peu partout, même en compos spécifiques et choux-blanc...

    Je peux très bien bricoler un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    ...
         if CheckListBox1.Checked[0] = true then
      begin
         (tous les autres items décochés)
     
         if CheckListBox1.Checked[1] = true then
      begin
    (tous les autres items décochés, etc.)
    ...
    Mais je ne peux savoir quel sera le nombre d'items d'avance...

    Merci de vos idées !

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    633
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 633
    Par défaut
    Bonjour,

    Ce que tu cherches à faire n'est pas le rôle des checkbox, mais celui des Radiobutton.

  3. #3
    Membre éprouvé
    Avatar de Sunchaser
    Homme Profil pro
    OPNI (Objet Programmant Non Identifié)
    Inscrit en
    Décembre 2004
    Messages
    2 059
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : OPNI (Objet Programmant Non Identifié)
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 059
    Par défaut
    Bonsoir,
    C'est tout de même faisable, si il veut garder le coté 'case a cocher' de la chose.
    Un exemple de code, avec le 'cousin' CBuilder, donc a adapter :
    dans l'évènement OnClickCheck...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    void __fastcall TForm::CheckListBoxClickCheck(TObject *Sender)
    {
    for (int i = 0; i < CLB->Items->Count; i ++)
    {
            if ( i != CLB->ItemIndex && CLB->Checked[i] == true )
            {
                    CLB->Checked[i] = false;
            }
    }        
    }
    En espérant t'être utile,
    @ +

  4. #4
    Membre Expert
    Avatar de Droïde Système7
    Homme Profil pro
    Inscrit en
    Septembre 2003
    Messages
    2 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 2 288
    Par défaut Petit à petit... ;-)
    Bonjour,

    Je viens de trouver une solution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    procedure TForm1.CheckListBox1ClickCheck(Sender: TObject);
      var
         i: integer;
      begin
     
    //------------------
    for i := 0 to N do
    CheckListBox1.Checked[i] := false;
     
    CheckListBox1.Checked[C] := true;
    //ShowMessage(IntToStr(C));
    //------------------
    end;
    Je précise que la variable N représente le nombre total d'items et C, celui cliqué.

    Mais faut encore peaufiner, car cela ne fonctionne que dans un sens

    Merci de vos messages et aide !

    PS : Sunchaser, j'ai tenté la conversion du cousin, mais pas tiré grand-chose, mais c'est tout de même sympa de ta part

  5. #5
    Membre Expert Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Par défaut
    Citation Envoyé par thewho
    Bonjour,

    Ce que tu cherches à faire n'est pas le rôle des checkbox, mais celui des Radiobutton.
    c'est a peut prés vrait; mais si il ajoute tros d'element , le checkbox a un assenceur:
    je prpose:
    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
     
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, CheckLst;
     
    type
      TForm1 = class(TForm)
        Box1: TCheckListBox;
        procedure Box1ClickCheck(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
    var  PoseCheck:integer=-1;
     
    procedure TForm1.Box1ClickCheck(Sender: TObject);
    var  i,j,p:integer;
    begin
         j:=0;
         for i:=0 to box1.Count-1 do
           if (box1.Checked[i]) then
              begin
               inc(j);
               if (i<>PoseCheck) then p:=i;
              end;
         if j>2 then exit;//normalement etat impossible
         if j=0 then
           begin
             Box1.Checked[PoseCheck]:=true;//car il faut au moins une case coché
             exit;// traitement déjà fait
           end;
         if j>1 then Box1.Checked[PoseCheck]:=false;//si c'est pas la premiére coche
         PoseCheck:=p;
         //....
         //traitement
         //....
    end;
     
    end.

  6. #6
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    633
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 633
    Par défaut
    Bonjour,
    Citation Envoyé par J-P
    Bonjour,

    Je viens de trouver une solution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    procedure TForm1.CheckListBox1ClickCheck(Sender: TObject);
      var
         i: integer;
      begin
    
    //------------------
    for i := 0 to N do
    CheckListBox1.Checked[i] := false;
    
    CheckListBox1.Checked[C] := true;
    //ShowMessage(IntToStr(C));
    //------------------
    end;
    Je précise que la variable N représente le nombre total d'items et C, celui cliqué.

    Mais faut encore peaufiner, car cela ne fonctionne que dans un sens
    Alors ta blucle n'est pas bonne et devrait être
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for i := 0 to N-1 do
    CheckListBox1.Checked[i] := false;
    Et j'ajoute que je ne comprends pas cette volonté d'utiliser un composant hors de sa destination normale, car je vois au moins trois raisons s'opposant à ta démarche , la troisième étant une conséquence des 2 premières:

    1 - Voir des CheckBox réagir comme des RadioButton va contre les habitudes des utilisateurs.

    2 - Utiliser les standards va dans le sens de la facilité de prise en main d'un nouveau logiciel.

    3 - Compte tenu des 2 raisons précédentes, au lieu de développer ce qui est vraiment utile à ton programme, tu passes du temps à faire quelque chose qui par ailleurs fonctionne parfaitement.

    Si malgré cela tu persistes dans cette voie, je pense qu'il serait plus simple de dériver un RadioButton, en personnalisant sa représentation, plutôt que d'essayer de forcer une exclusivité pour un type de composant non prévu pour, au contraire.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 60
    Par défaut
    Je propose deux autres solutions, afin de ne pas faire de for a chaque clique.

    Socker l'index de la dernière checkbox dans une variable global ou la proriété Tag de la CheckListBox, ainsi, à chaque clique, on décoche l'ancien index, et on coche le nouveau.

    Mais sinon, le TCustomListBox qui est la classe parente de TCheckListBox contient une propriété MultiSelect qu'il suffit de mettre à False.

  8. #8
    Membre Expert Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Par défaut
    Citation Envoyé par moechofe
    Je propose deux autres solutions, afin de ne pas faire de for a chaque clique.

    Socker l'index de la dernière checkbox dans une variable global ou la proriété Tag de la CheckListBox, ainsi, à chaque clique, on décoche l'ancien index, et on coche le nouveau.
    .
    ,, je me fait emporte par le code de synchaser
    voila le code:
    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
    implementation
     
    {$R *.dfm}
    var  PoseCheck:integer=-1;
     
    procedure TForm1.Box1ClickCheck(Sender: TObject);
    var  j:integer;
    begin
         j:=box1.ItemIndex;
         if (j=PoseCheck) and (not Box1.Checked[j]) then
           begin
            Box1.Checked[PoseCheck]:=true;
            exit;
           end;
         if PoseCheck>=0 then Box1.Checked[PoseCheck]:=false;
         PoseCheck:=j;
         //....
         //traitement
         //....
    end;

  9. #9
    Membre Expert
    Avatar de Droïde Système7
    Homme Profil pro
    Inscrit en
    Septembre 2003
    Messages
    2 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 2 288
    Par défaut Bingo !


    Affaire résolue gràce à toutes vos remarques et à la superbe conclusion codale d'edam :

    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
    ...
    procedure TForm1.Box1ClickCheck(Sender: TObject);
    var  j:integer;
    begin
         j:=box1.ItemIndex;
         if (j=PoseCheck) and (not Box1.Checked[j]) then
           begin
            Box1.Checked[PoseCheck]:=true;
            exit;
           end;
         if PoseCheck>=0 then Box1.Checked[PoseCheck]:=false;
         PoseCheck:=j;
         //....
         //traitement
         //....
    end;
    Je précise que cette utilisation d'une CheckListBox est indispensable en mon cas, car au niveau de la "logique intuitive" à certain niveau, l'utilisateur lambda est sensible à ses réflexes et non à la non-logique de tel ou tel habitude de compos.

    Mon utilisation est de cocher/choisir/mémoriser une imprimante hors celle par défaut qui sera ensuite "relâchée" par défaut lors du "quitter" de ce programme.

    Encore

  10. #10
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    633
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 633
    Par défaut
    Bonjour,
    Citation Envoyé par J-P

    Je précise que cette utilisation d'une CheckListBox est indispensable en mon cas, car au niveau de la "logique intuitive" à certain niveau, l'utilisateur lambda est sensible à ses réflexes et non à la non-logique de tel ou tel habitude de compos.

    Mon utilisation est de cocher/choisir/mémoriser une imprimante hors celle par défaut qui sera ensuite "relâchée" par défaut lors du "quitter" de ce programme.
    Désolé, mais je vais te contredire encore.

    La force de l'habitude étant, le réflexe de l'utilisateur "lambda", comme tu dis, est de s'attendre à un choix unique avec des RadioButton, et des options non exclusives avec des CheckBox.

    C'est ainsi depuis que les applications fenêtrées existent, et même un utilisateur débutant, ayant au plus 1 jour d'utilisation d'un ordinateur, sait déjà cela (ou alors sa formation est mal faite).

    Et je ne vois pas en quoi
    Je précise que cette utilisation d'une CheckListBox est indispensable
    Quelle que soit la suite de ton programme, répétons ensemble :

    Les CheckBox sont destinées à des choix multiples, chaque option pouvant être choisie indépendamment,
    les RadioButton à un choix unique parmi les différentes possibilités.


    Depuis pas mal d'années que je bricole en info (j'ai commencé bien avant l'arrivée des système fenêtrés, c'est vieux...), je n'ai jamais vu un programme utilisant une liste de CheckBox pour un choix unique.

  11. #11
    Membre Expert
    Avatar de Droïde Système7
    Homme Profil pro
    Inscrit en
    Septembre 2003
    Messages
    2 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 2 288
    Par défaut Conservateur...
    Bonjour,

    thewho écrivait :
    [...]
    Depuis pas mal d'années que je bricole en info (j'ai commencé bien avant l'arrivée des système fenêtrés, c'est vieux...), je n'ai jamais vu un programme utilisant une liste de CheckBox pour un choix unique.
    Certes... idem, je bricole en info depuis quelques années, c'est d'ailleurs la première fois que j'utilise une CheckListBox, je peux te dire que pendant longtemps j'ai cherché la propriété qui me permette de ne laisser coché qu'un seul item, ôhhhhhh honte à moââ

    Permets-moi le moment voulu, de te donner le lien de cette appli, tu verras alors par toi-même que je ne suis pas si original et loup-phoque, heuuu loufoque dis-je et si saugrenu que ça.

    "C'est seulement en brisant ses habitudes que l'homme s'adapte."

    Alors mon appli sera unique au monde, en ce fait qu'elle seule possédera une CheckListBox monocheckable

    Amicalement

  12. #12
    Membre éprouvé
    Avatar de Sunchaser
    Homme Profil pro
    OPNI (Objet Programmant Non Identifié)
    Inscrit en
    Décembre 2004
    Messages
    2 059
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : OPNI (Objet Programmant Non Identifié)
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 059
    Par défaut
    Citation Envoyé par J-P
    Alors mon appli sera unique au monde, en ce fait qu'elle seule possédera une CheckListBox monocheckable
    Trop tard....j't'ai grillé...j'ai utilisé ce truc il y a 2 ans, désolé

    Dérivé un RadioButton, afin d'obtenir une présentation 'en coche' au lieu du 'point' habituel, est forcement plus 'pur' que cette bidouille que j'avais fait et je cromprends thewho.
    Néanmoins, c'est surement un peu plus complexe que le bout de code 'bidouillou' qui règle vite le problème de J - P.

    Après chacun est libre de ses choix...

    @ +

  13. #13
    Membre Expert
    Avatar de Droïde Système7
    Homme Profil pro
    Inscrit en
    Septembre 2003
    Messages
    2 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 2 288
    Par défaut
    Bonjour,

    Sunchaser écrivait :
    Trop tard....j't'ai grillé...j'ai utilisé ce truc il y a 2 ans, désolé
    Ouinnnnn ! moi qui pensais faire passer ce détournement en scoop mondial

    @+

  14. #14
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 3
    Par défaut Plus court
    Voici un example plus court. Je l'ai dans la methode 'CheckListBox1Click' et non 'CheckListBox1ClickCheck' ce qui me permet de cliquer simplement sur la ligne pour l'activer. Voici le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    procedure TMainForm.CheckListBox1Click(Sender: TObject);
    var
      int1: integer;
    begin
      For int1 := 0 to CheckListBox1.Items.Count - 1 do
      begin
        CheckListBox1.Checked[int1] := false;
      end;
      CheckListBox1.Checked[CheckListBox1.ItemIndex] := true;
    end;
    Dans prémiere exemple il y a toujours 1 case coché. Dans deuxieme ci joint, soit 1, soit 0 case :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    procedure TMainForm.CheckListBox1Click(Sender: TObject);
    var
      int1: integer;
    begin
      For int1 := 0 to CheckListBox1.Items.Count - 1 do
      begin
        If int1 <> CheckListBox1.ItemIndex then CheckListBox1.Checked[int1] := false;
      end;
      CheckListBox1.Checked[CheckListBox1.ItemIndex] := CheckListBox1.Checked[CheckListBox1.ItemIndex] = false;
    end;

  15. #15
    Membre Expert
    Avatar de Droïde Système7
    Homme Profil pro
    Inscrit en
    Septembre 2003
    Messages
    2 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 2 288
    Par défaut


    Merci David de ce complément

    Le premier exemple est super plus court en code grâce à sa boucle.

    Par contre curieusement ton second exemple fonctionne de manière erratique.

    Je m'explique (sous Win98se et Delphi7) :
    - Si click direct sur les cases à cocher, ça ne se coche pas au premier coup, ou alors faut faire ça très très doucement (lol ce compo est féminin )
    - Par contre, si je click sur les labels à droite de ces cases, là ça se coche impec.

    Ceci dit, avec ton premier code, en recliquant doucement avec précision sur la case cochée, cette dernière se décochait.

    @+
    J-P

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 05/07/2006, 18h29
  2. comment remplir 2 champs avec une seule listbox
    Par Didi17 dans le forum Access
    Réponses: 3
    Dernier message: 19/10/2005, 10h42
  3. plusieurs tables avec un seul DBnavigator et DBGRID
    Par warrior dans le forum Bases de données
    Réponses: 8
    Dernier message: 07/06/2005, 09h12
  4. Plusieurs commandes avec 1 seule R-commande
    Par pouldo dans le forum Shell et commandes GNU
    Réponses: 6
    Dernier message: 01/04/2005, 19h44
  5. [MFC] MDI avec 1 seul document à la fois
    Par bigquick dans le forum MFC
    Réponses: 21
    Dernier message: 03/03/2005, 15h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo