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

Composants VCL Delphi Discussion :

[D10.2] DBGrid et CheckBox


Sujet :

Composants VCL Delphi

  1. #1
    Membre émérite
    Avatar de free07
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardèche (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 941
    Par défaut [D10.2] DBGrid et CheckBox
    Bonjour,

    Je souhaite gérer une CheckBox dans une colonne de ma DBGRid, pour cela j'utilise DrawFrameControl mais malheureusement il affiche parfois 'vrai' ou faux' lorsque l'on clic sur la CheckBox.

    J'ai mis dgEditing à True dans les options de ma DBGRid, DefaultDrawing à True et j'utilise l'évènement OnDrawColumnCell comme ceci :

    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
     
    procedure TMaFrame.CRDBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer;
      Column: TColumn; State: TGridDrawState);
     
    const
          IsChecked : array[Boolean] of Integer = (DFCS_BUTTONCHECK, DFCS_BUTTONCHECK or DFCS_CHECKED);
     var
          DrawState: Integer;
     
    begin
        if (Column.Field.FieldName = 'MaColonne') then
        begin
          DrawState := ISChecked[Column.Field.AsBoolean];
          TCRDBGrid(Sender).Canvas.FillRect(Rect);
          DrawFrameControl(TCRDBGrid(Sender).Canvas.Handle, Rect, DFC_BUTTON, DrawState);
        end;
    end;
    J'ai fait beaucoup d'essais infructueux, je n'arrive pas à trouver comment éviter l'affichage de ce texte 'vrai ou faux' ?

    EDIT : j'ai supprimé la variable DrawRect erreur de copié collé

  2. #2
    Membre Expert
    Avatar de pprem
    Homme Profil pro
    MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Inscrit en
    Juin 2013
    Messages
    1 876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 876
    Par défaut
    Un peu sous forme de devinette je dirais que si la case est associée à un élément de base de données, le texte provient du texte fourni par le record. Peut-être devrais-tu tenter de bidouiller le GetText au niveau de ton dataset.

  3. #3
    Membre émérite
    Avatar de free07
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardèche (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 941
    Par défaut
    Citation Envoyé par pprem Voir le message
    Un peu sous forme de devinette je dirais que si la case est associée à un élément de base de données, le texte provient du texte fourni par le record. Peut-être devrais-tu tenter de bidouiller le GetText au niveau de ton dataset.
    Merci pprem pour ta réponse, le dataset associé est en fait un TVirtualTable ( c'est un composant de Devart ), devrais je regarder du côté de AfterEdit ou OnUpdateRecord ?

  4. #4
    Membre expérimenté
    Homme Profil pro
    Consultant fonctionnel
    Inscrit en
    Décembre 2014
    Messages
    109
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Consultant fonctionnel

    Informations forums :
    Inscription : Décembre 2014
    Messages : 109
    Par défaut
    Bonjour à tous,

    Il y a très longtemps (D6) j'avais fait qq'chose qui ressemblait à çà:
    https://www.greelane.com/fr/science-...bgrid-4077440/
    et çà marchait très bien.

    solilog

  5. #5
    Membre Expert
    Avatar de pprem
    Homme Profil pro
    MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Inscrit en
    Juin 2013
    Messages
    1 876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 876
    Par défaut
    Citation Envoyé par solilog Voir le message
    çà marchait très bien.
    avant ou après la traduction en français du texte avec les codes sources ?

  6. #6
    Membre expérimenté
    Homme Profil pro
    Consultant fonctionnel
    Inscrit en
    Décembre 2014
    Messages
    109
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Consultant fonctionnel

    Informations forums :
    Inscription : Décembre 2014
    Messages : 109
    Par défaut
    Oups, pardon, erreur sur le lien, c'est vrai je deviens vieux et j'ai répondu un peu vite (quoique le principe est correct).
    En fait c'est là.
    https://stackoverflow.com/questions/...-dbgrid-themed

    solilog

  7. #7
    Membre émérite
    Avatar de free07
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardèche (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 941
    Par défaut
    Merci pour vos réponses, j'avais aussi trouvé ce lien avec mes recherches, mais bon comme le client était pressé, j'ai changé de méthode et j'ai utilisé un combo box sur la cellule ( avec deux items oui/non ), il est satisfait et c'est quelque chose que je maîtrise mieux : ça fonctionne.

    Par contre, quand j'aurais un peu de temps, je me pencherai plus en détail sur ce problème de checBox, si quelqu'un a la solution, qu'il n'hésites pas

  8. #8
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 569
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 569
    Billets dans le blog
    65
    Par défaut
    Bonjour, j'ai toujours utilisé le DrawFrameControl sans souci
    voir mes réponses
    https://www.developpez.net/forums/d1...x/#post6644294
    https://www.developpez.net/forums/d2.../#post11923805

    par contre, il faut que DefaultDrawing soit à False

    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
    procedure TMaFrame.CRDBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer;
      Column: TColumn; State: TGridDrawState);
    var
     r : Trect;
    begin
    if SameText(Column.FieldName,'MaColonne') then
     begin
      r.Top:=Rect.Top+1;
      r.Bottom:=Rect.Bottom-1;
      r.Left:=Rect.Left+1;
      r.Right:=Rect.Right-1;
      (Sender as TDBGrid).Canvas.FillRect(r); // pour effacer tout texte mais pas les bords
      DrawFrameControl((Sender as TDBGrid).Canvas.Handle,r,DFC_BUTTON,
       IfThen( <condition> 
                 ,DFCS_CHECKED,DFCS_BUTTONCHECK));
     end
    else DBGrid1.DefaultDrawColumnCell(Rect,DataCol,Column,State);
    end;

  9. #9
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 982
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 982
    Par défaut
    TCRDBGrid de Core Lab Devart, si la colonne est Boolean, ce n'est pas automatique ?
    Par exemple avec MyDac et un TINYINT(1) ... ah non, c'est vrai cela ne le gérait pas, voir : Gestion CheckBox TCRDBGrid

    Songe que le TCRDBGrid est abandonné, tu peux donc modifier le composant en interne au lieu des events.


    Pas avec TVirtualTable mais avec TClientDataSet

    DefaultDrawing, je ne le change pas donc pas de DefaultDrawColumnCell
    C'est à ajuster cela ce qu'on fait
    En mettant la case à cocher au centre et en mettant 0 et 1 comme valeur de DisplayText du Boolean, cela fera une superposition mais oblige la colonne en lecture seule

    Sinon, avec le InplaceEditor, cela viendra dessiner le champ de saisie de la valeur (j'avoue ne pas savoir si DefaultDrawing à False évite d'avoir le InplaceEditor)

    Je triche avec RowSelect pour ma part énormément, la TDBGrid était à chier pour saisir de la donnée
    dgEditing à True, complique énormément la chose


    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //---------------------------------------------------------------------------
    void __fastcall TDBManipForm::DBGridCDSBasicsDrawDataCell(TObject *Sender,
          const TRect &Rect, TField *Field, TGridDrawState State)
    {
        if (Field->DataType == ftBoolean)
          if (Sender->InheritsFrom(__classid(TDBGrid)))
          {
            ((TDBGrid*)Sender)->Canvas->FillRect(Rect);
            DrawFrameControl(((TDBGrid*)Sender)->Canvas->Handle, (RECT*)&Rect, DFC_BUTTON, DFCS_BUTTONCHECK | (Field->AsBoolean ? DFCS_CHECKED : 0));
          }
    }

    Avec l'éditeur actif du DBGrid, tu auras des surprises, met la colonne en lecture seule visuellement et gère le click ...

    Code c++ : 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
    //---------------------------------------------------------------------------
    void __fastcall TDBManipForm::DBGridCDSBasicsDblClick(TObject *Sender)
    {
      if (Sender->InheritsFrom(__classid(TDBGrid)))
      {
        TPoint CursorPos = Mouse->CursorPos;
        TDBGrid* Grid = ((TDBGrid*)Sender);
        CursorPos = Grid->ScreenToClient(CursorPos);
        TGridCoord Coord = Grid->MouseCoord(CursorPos.x, CursorPos.y);
        TField *Field = Grid->Columns->Items[Coord.X - (Grid->Options.Contains(dgIndicator) ? 1 : 0)]->Field;
     
        if (Field->DataType == ftBoolean)
        {
          TDataSetState KeepState = Field->DataSet->State;
          if ((KeepState != dsEdit) && (KeepState != dsInsert))
            Field->DataSet->Edit();
          Field->AsBoolean = ! Field->AsBoolean;
          if ((KeepState != dsEdit) && (KeepState != dsInsert))
            Field->DataSet->Post();
        }
      }
    }




    Depuis, j'ai "standardisé" ça pour Delphi : DBGrid avec checbox avec un TDBGridHelper qui utilise un vieux TDBGridSLTAssistant issu de D7 modernisé en XE2 pour les thèmes :

    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
    52
    53
    54
    55
    56
    57
    58
    59
    60
    //------------------------------------------------------------------------------
    procedure TDBGridSLTAssistant.DrawCheckBox(const ARect: TRect; AChecked: Boolean; AEnabled: Boolean = True);
    var
      uState: UINT;
      tbState: TThemedButton;
      Details: TThemedElementDetails;
      StyleColor: TColor;
      Buffer: Vcl.Graphics.TBitmap;
      BufferRect: TRect;
    begin
      if StyleServices.Enabled then
      begin
        // Un bug sur DrawElement d'un TThemedButton dans un DBGrid provoque sur les thèmes foncés une perte de la couleur de fond !
        // En attendant une meilleure solution, j'utilise un Buffer temporaire pour dessiner le ThemedButton CheckBox
        Buffer := Vcl.Graphics.TBitmap.Create();
        try
          BufferRect := Rect(0, 0, ARect.Width, ARect.Height);
          Buffer.SetSize(BufferRect.Width, BufferRect.Height);
     
          Details := StyleServices.GetElementDetails(tgCellNormal);
          StyleServices.GetElementColor(Details, ecFillColor, StyleColor);
     
          // Force un fond opaque pour cacher le texte !
          Buffer.Canvas.Brush.Color := StyleColor;
          Buffer.Canvas.Brush.Style := bsSolid;
          Buffer.Canvas.FillRect(BufferRect);
     
          tbState := tbCheckBoxUncheckedNormal;
          if AChecked then
            tbState := tbCheckBoxCheckedNormal;
     
          if not AEnabled then
          begin
            if AChecked then
              tbState := tbCheckBoxCheckedDisabled
            else
              tbState := tbCheckBoxUncheckedDisabled;
          end;
     
          Details := StyleServices.GetElementDetails(tbState);
          StyleServices.DrawElement(Buffer.Canvas.Handle, Details, BufferRect, BufferRect);
          // Dessin final
          DBGrid.Canvas.Draw(ARect.Left, ARect.Top, Buffer);
        finally
          Buffer.Free();
        end;
      end
      else
      begin
        uState := DFCS_BUTTONCHECK;
        if AChecked then
          uState := uState or DFCS_CHECKED;
     
        if not AEnabled then
          uState := uState or DFCS_INACTIVE;
     
        DBGrid.Canvas.FillRect(ARect);
        DrawFrameControl(DBGrid.Canvas.Handle, ARect, DFC_BUTTON, uState);
      end;
    end;
    à utiliser ainsi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    procedure TForm.DBGridDrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);
    begin
      if Assigned(Column.Field) and (Column.Field.DataType = ftBoolean) then
        TDBGrid(Sender).DrawCheckBox(Rect, Column.Field.AsBoolean);
    end;
    je laisse True pour DefaulfDrawing car mes grilles en lecture seule le permettent (j'utilise des ... pour les champs modifiables)
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  10. #10
    Membre émérite
    Avatar de free07
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardèche (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 941
    Par défaut
    Ok merci à vous tous, je regarderai cela de plus près dès que j'ai un peu de temps...

Discussions similaires

  1. DBgrid et checkBox
    Par Klemsy78 dans le forum Delphi
    Réponses: 2
    Dernier message: 27/10/2006, 08h13
  2. CheckBox dans DbGrid
    Par louiwahl dans le forum Composants VCL
    Réponses: 3
    Dernier message: 11/01/2006, 10h59
  3. Sélection automatique de tous les checkbox d'un dbgrid
    Par bertrand_declerck dans le forum Bases de données
    Réponses: 3
    Dernier message: 19/08/2005, 09h55
  4. Cochage des checkbox d'un dbgrid
    Par kose dans le forum Bases de données
    Réponses: 1
    Dernier message: 25/01/2005, 16h26

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