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

Langage Delphi Discussion :

StringGrid : formater la ligne de la cellule sélectionnée et entourer des lignes avec un rectangle


Sujet :

Langage Delphi

  1. #1
    Membre habitué

    Homme Profil pro
    Direction financière et formateur en gestion et contrôle de gestion
    Inscrit en
    Mai 2003
    Messages
    199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Direction financière et formateur en gestion et contrôle de gestion
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2003
    Messages : 199
    Points : 129
    Points
    129
    Par défaut StringGrid : formater la ligne de la cellule sélectionnée et entourer des lignes avec un rectangle
    Bonjour à tous,
    Il me semblait avoir posté ce matin, mais je ne retrouve pas mon interrogation dans la liste ... donc je reposte.

    Aujourd'hui temps maussade ... alors je continue mes apprentissages.

    Ce matin j'ai eu 2 idées avec un TStringGrid :

    1) quand je clique sur une cellule, la cellule change de format (ça c'est ok) mais j'aimerai que la ligne entière se mette en gras par exemple.
    J'ai joué avec la partie OnDrawCell et le (gdFixed in State)
    Je me suis dit qu'il suffisait d'identifier la ligne et hop le tour est joué .... sans succès mis à part faire clignoter l'ensemble de la grille parce-que j'ai eu la mauvaise idée de faire un repaint dans le OnDrawCell ... comment faire ?

    2) La 2ème, mes lignes forment des groupes identifiés dans une colonne numérotée.
    Je souhaiterai, quand je clique dans une cellule, entourer les lignes du groupe par un cadre.
    J'ai vu un truc sur l'encadrement de la cellule en cours, que j'ai essayé d'adapter, mais sans succès ...

    ... help ?

  2. #2
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 268
    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 268
    Points : 41 671
    Points
    41 671
    Billets dans le blog
    64
    Par défaut
    Bonjour,
    Citation Envoyé par patrice@ Voir le message
    Il me semblait avoir posté ce matin, mais je ne retrouve pas mon interrogation dans la liste ... donc je reposte.
    Oui, cela m'arrive aussi de temps en temps, souvent à cause d'un perte de connexion temporaire du réseau

    Aujourd'hui temps maussade
    moi c'est l'humeur

    Ce matin j'ai eu 2 idées avec un TStringGrid :

    1) quand je clique sur une cellule, la cellule change de format (ça c'est ok) mais j'aimerai que la ligne entière se mette en gras par exemple.
    l'options goRowSelect ne suffirait pas ? (changement de couleur)

    J'ai joué avec la partie OnDrawCell et le (gdFixed in State)
    oui c'est généralement avec ça que l'on joue pour tout dessin un peu plus spécifique
    help ?
    FAQ https://delphi.developpez.com/faq/?p...un-TStringGrid devrait être le bon fil conducteur


    2) La 2ème, mes lignes forment des groupes identifiés dans une colonne numérotée.
    Là, c'est certainement plus compliqué, peut-être une solution avec les Range (option goRangeSelect) et l'état gdRowSelected de ce même évènement OnDrawCell AMHA le plus dur sera de définir quels sont les côtés à dessiner

  3. #3
    Membre habitué

    Homme Profil pro
    Direction financière et formateur en gestion et contrôle de gestion
    Inscrit en
    Mai 2003
    Messages
    199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Direction financière et formateur en gestion et contrôle de gestion
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2003
    Messages : 199
    Points : 129
    Points
    129
    Par défaut
    Bonjour Sergio Master,
    Je viens de coder pour mettre en gras : j'ai déclaré une variable globale qui récupère la ligne dans l'évènement MouseUp et un repaint. Dans l'évènement DrawCell, je mets en gras si Row = aRowSelect. Et le tour est joué.

    Mais effectivement, pour dessiner un cadre ... là je coince (bon en calcul et en analyse mais en dessin ... )

  4. #4
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 268
    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 268
    Points : 41 671
    Points
    41 671
    Billets dans le blog
    64
    Par défaut
    Re,
    Citation Envoyé par patrice@ Voir le message
    j'ai déclaré une variable globale qui récupère la ligne dans l'évènement MouseUp et un repaint.
    MouseUp j'aurais plutôt utilisé OnSelectCell mais je n'ai pas toutes les cartes en main.


    Mais effectivement, pour dessiner un cadre ... là je coince (bon en calcul et en analyse mais en dessin ... )
    Il n'y a pas que FillRect
    une piste : FrameRect. Il ne faut pas oublier que les dessins se font dans le canvas du stringgrid pas dans une cellule particulière même si l'événement est OnDrawcell. inconvénient pour chaque cellule
    ce frame sera redessiné (cela dit un helper sur repaint ...)
    sinon Lineto, ce sera alors un question de mémorisation des 4 lignes dessinées pour faire le job

    Toutefois, je suggère de lire la faq https://delphi.developpez.com/faq/?p...un-TStringGrid pour avoir l'équivalent d'un BeginUpdate/EndUpdate de FMX

  5. #5
    Membre habitué

    Homme Profil pro
    Direction financière et formateur en gestion et contrôle de gestion
    Inscrit en
    Mai 2003
    Messages
    199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Direction financière et formateur en gestion et contrôle de gestion
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2003
    Messages : 199
    Points : 129
    Points
    129
    Par défaut
    Je n'avais pas pensé au OnSelectCell,
    Tiens ... ça ne fonctionne pas
    J'ai mis ma variable globale aRowSelected := aRow; dans le SelectCell, et rien!
    J'ai rajoute repaint, au cas où, et ah super, ça fonctionne.
    C'est effectivement mieux, j'avais un petit effet de rebond qui n'existe plus.
    Merci Serge.

    Bon, maintenant reste plus qu'à régler mon carré qui entoure des lignes ... FrameRect ... ok, je regarde

  6. #6
    Membre actif
    Homme Profil pro
    libre
    Inscrit en
    Juin 2019
    Messages
    205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : libre

    Informations forums :
    Inscription : Juin 2019
    Messages : 205
    Points : 292
    Points
    292
    Par défaut
    Si ma mimoire est bonne tu peux savoir si la cellule est sélectionnée via le paramètre State dans la fonctionne onDrawCell

  7. #7
    Membre habitué

    Homme Profil pro
    Direction financière et formateur en gestion et contrôle de gestion
    Inscrit en
    Mai 2003
    Messages
    199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Direction financière et formateur en gestion et contrôle de gestion
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2003
    Messages : 199
    Points : 129
    Points
    129
    Par défaut
    Bonjour Wheel,
    La mise en forme est fonctionnelle,
    Maintenant je me bats pour mettre un rectangle autour de la ligne de la cellule sélectionnée.
    La bataille est rude et ne donne pour l'instant ... rien

    Vraiment, si quelqu'un à une idée je suis preneur.
    Je part sur l'idée de repérer la 1ere colonne visible (TStringGrid(Sender).LeftCol), puis la dernière (TStringGrid(Sender).VisibleColCount), de transformer tout ça en pixel ... là ça commence à merder. Il suffira (enfin je pense) de mettre un canvas.rectangle autour des coordonnées

    ça c'est ma théorie ...

  8. #8
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 268
    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 268
    Points : 41 671
    Points
    41 671
    Billets dans le blog
    64
    Par défaut
    Citation Envoyé par patrice@ Voir le message
    Il suffira (enfin je pense) de mettre un canvas.rectangle autour des coordonnées,
    ça c'est ma théorie ...
    un peu foireuse mais en approche.
    Il faut que tu calcules la taille du rectangle et si c'est un frame que tu dessines.
    Donc tu dois récupérer les coins en haut à gauche et en bas à droite de ton groupe et pour ça tu as CellRect(col,row) (enfin je crois, pas le temps de vérifier je dois aller chez mon kiné)

  9. #9
    Membre habitué

    Homme Profil pro
    Direction financière et formateur en gestion et contrôle de gestion
    Inscrit en
    Mai 2003
    Messages
    199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Direction financière et formateur en gestion et contrôle de gestion
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2003
    Messages : 199
    Points : 129
    Points
    129
    Par défaut
    J'ai essayé ça, mais ça ne fonctionne pas ...

    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 TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
    Var
       r : TRect;
    begin
       if (gdSelected in State)
       then begin
           // Coordonnées de la 1ere cellule visible haut/gauche
           r.Top := TStringGrid(Sender).CellRect(TStringGrid(Sender).LeftCol,ARow).Top;
           r.Left := TStringGrid(Sender).CellRect(TStringGrid(Sender).LeftCol,ARow).Left;
           // coordonnées de la dernière cellule visible bas/droite
           r.Right := TStringGrid(Sender).CellRect(TStringGrid(Sender).VisibleColCount,ARow).Right;
           r.Bottom := TStringGrid(Sender).CellRect(TStringGrid(Sender).VisibleColCount,ARow).Height-1;
           // dessin du rectangle
           TStringGrid(Sender).Canvas.Pen.Color := clRed;
           TStringGrid(Sender).Canvas.rectangle(r.Left+1 , r.top+1 , r.Right-2 , r.bottom-2 );
       end;
     
       TStringGrid(Sender).canvas.FillRect(rect);
       TStringGrid(Sender).canvas.font.style:=[];
       TStringGrid(Sender).canvas.font.color:=clBlack;
       TStringGrid(Sender).canvas.textout(rect.left+2,rect.top+2,TStringGrid(Sender).Cells[ACol,ARow]);
    end;

    "Dis, c'est loin l’Amérique?
    Tais toi et rame"

  10. #10
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 831
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 831
    Points : 13 579
    Points
    13 579
    Par défaut
    Le rectangle est mal calculé.

    En admettant que tu aies 10 colonnes dont 4 visibles à l'écran, LeftCol peut atteindre 6 (7ème colonne). VisibleColCount valant 4 (voire moins s'il y a des colonnes figées), la borne droite est inférieur à la gauche => rectangle invalide !

    Même chose sur la hauteur : ex. Top de la troisième ligne vaut 2* CellRect().Height. Bottom ne peut pas valoir CellRect().Height-1.

    Ensuite un canvas.FillRect après canvas.Rectangle. Rectangle est écrasé pour cette cellule-là.

    Et enfin DrawCell, comme son nom l'indique, est le dessin d'une cellule et non de la zone cliente complète. Essayer de dessiner dans d'autres cellules ne fonctionnera jamais bien.

    Tu dois ne t'occuper que de la cellule concernée et c'est par rapport à sa position dans la rangée que tu définis s'il y a besoin d'un trait à gauche, ou à droite, ou les deux (idem en hauteur).

  11. #11
    Membre habitué

    Homme Profil pro
    Direction financière et formateur en gestion et contrôle de gestion
    Inscrit en
    Mai 2003
    Messages
    199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Direction financière et formateur en gestion et contrôle de gestion
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2003
    Messages : 199
    Points : 129
    Points
    129
    Par défaut
    Bonsoir Andnotor,
    Ah la vache, c'est mon 1er essai de dessiner quelque chose (mis à par les mises en forme de texte).
    Du coup ... je ne sais même pas par quoi commencer !

  12. #12
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 268
    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 268
    Points : 41 671
    Points
    41 671
    Billets dans le blog
    64
    Par défaut
    Bonjour,

    comme l'écrit Andnotor, c'est avant tout un problème d'évènement, le onDrawCell s'effectuant sur une cellule ou plus exactement sur chaque cellules visibles de la grille.
    Continuer à utiliser cet événement implique l'utilisation de dessin de lignes et non de frame pour ce qui est du cadre.

    Maintenant, AMHA le moyen de dessiner un frame (dans le sens cadre) passe par le moment où la grille a fini d'être dessinée.

    un petit bout de code très simple pour montrer ça avec un bouton
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    procedure TForm12.Button1Click(Sender: TObject);
    var aRect : TRect;
    begin
    with StringGrid1 do
      begin
        ARect.TopLeft:=CellRect(1,1).Topleft;
        ARect.BottomRight:=CellRect(4,4).BottomRight;
        Canvas.Brush.Color:=clred;
        Canvas.Pen.Color:=clgreen;
        Canvas.Pen.Width:=2;
        Canvas.FrameRect(ARect);
      end;
    end;
    Nom : Capture_1.PNG
Affichages : 259
Taille : 4,5 Ko

    inconvénient ? ici j'ai fait une grille de 8 colonnes, 8 lignes, quand je déplace le curseur vers la gauche ok, vers le bas mais quand je revient à l'origine
    Nom : Capture.PNG
Affichages : 229
Taille : 4,1 Ko
    logique mais

    Comment faire ? utiliser OntopLeftChanged me semble une piste intéressante.

    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
    type
      THStringGrid = class helper for TStringGrid  // uniquement pour me faciliter la codification
        procedure _paint(ct,lt,cb,lb : integer);    // dessin groupe, ct : colonne top, lt : ligne top, cb : colonne bas, lb : ligne bas
      end;
     
    uses System.math;
     
    procedure TForm12.Button1Click(Sender: TObject);
    begin
    stringgrid1._paint(2,2,4,4);
    end;
     
    procedure TForm12.StringGrid1TopLeftChanged(Sender: TObject);
    begin
    StringGrid1._paint(2,2,4,4);
    end;
     
    { THStringGrid } // uniquement pour me faciliter la codification 
     
    procedure THStringGrid._paint(ct,lt,cb,lb : integer);
    var aRect : TRect;
    begin
    // pas sûr à 100% de ma logique
      ARect.TopLeft:=CellRect(Max(ct,LeftCol),Max(lt,toprow)).Topleft;                                  
      ARect.BottomRight:=CellRect(Min(cb,VisibleColCount),min(lb,VisibleRowCount)).BottomRight;
     
    // dessin cadre
      Canvas.Brush.Color:=clred;
      Canvas.Pen.Color:=clgreen;
      Canvas.Pen.Width:=2;
      Canvas.FrameRect(ARect);
    end;
    ce n'est pas encore ça mais ça semble s'en approcher, il faut effacer l'ancien dessin (cadre) avant.

  13. #13
    Membre habitué

    Homme Profil pro
    Direction financière et formateur en gestion et contrôle de gestion
    Inscrit en
    Mai 2003
    Messages
    199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Direction financière et formateur en gestion et contrôle de gestion
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2003
    Messages : 199
    Points : 129
    Points
    129
    Par défaut
    Je ne pensais pas qu'un simple rectangle demandait autant ... et béh! J'ai du boulot moi!

  14. #14
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 268
    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 268
    Points : 41 671
    Points
    41 671
    Billets dans le blog
    64
    Par défaut
    Bon, attention, c'est ma vision en utilisant un Canvas.Frame, cela ne veut pas dire que c'est la bonne solution, c'en est juste une pour montrer qu'avec Canvas.frame c'est faisable.
    Cela étant je n'ai pas vérifié si cela ce faisait après les OnDrawcell ou avant.

  15. #15
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 268
    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 268
    Points : 41 671
    Points
    41 671
    Billets dans le blog
    64
    Par défaut avec lineto et drawcell
    Voilà qui va mieux
    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
     
     private
        { Déclarations privées }
        groupe : TRect;  // cellules du groupe
      public
        { Déclarations publiques }
      end;
     
    var
      Form12: TForm12;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm12.Button1Click(Sender: TObject);
    begin
    if Groupe=TRect.Empty then Groupe:=TRect.Create(2,2,4,4);
    StringGrid1.Repaint;
    end;
     
     
    procedure TForm12.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
    begin
    if Groupe=Trect.Empty then exit;
    // cadre
    StringGrid1.Canvas.Pen.Color:=clRed;
    StringGrid1.Canvas.Pen.Width:=2;
    if (ACol=Groupe.Left) AND (ARow>=Groupe.Top) AND (ARow<=Groupe.Bottom)    then
     begin
       StringGrid1.Canvas.MoveTo(Rect.Left,Rect.Top);
       StringGrid1.Canvas.LineTo(Rect.Left,Rect.Bottom);
     end;
    if (ACol=Groupe.Right) AND (ARow>=Groupe.top) AND (ARow<=Groupe.Bottom)  then
     begin
       StringGrid1.Canvas.MoveTo(Rect.Right,Rect.Top);
       StringGrid1.Canvas.LineTo(Rect.Right,Rect.Bottom);
     end;
    if (ARow=Groupe.Top) AND (ACol>=Groupe.Left) AND (ACol<=Groupe.Right)
    then
     begin
       StringGrid1.Canvas.MoveTo(Rect.Left,Rect.Top);
       StringGrid1.Canvas.LineTo(Rect.Right,Rect.Top);
     end;
    if (ARow=Groupe.Bottom) AND (ACol>=Groupe.Left) AND (ACol<=Groupe.Right)  then
     begin
       StringGrid1.Canvas.MoveTo(Rect.Left,Rect.Bottom);
       StringGrid1.Canvas.LineTo(Rect.Right,Rect.Bottom);
     end;
    end;
    YAPLUKA définir le groupe en fonction des besoins

  16. #16
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 831
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 831
    Points : 13 579
    Points
    13 579
    Par défaut
    Il ne faut vraiment réfléchir que sur la cellule actuellement repeinte et oui il faut effectivement traiter l'événement TopLeftChanged puisque la grille doit toujours être invalidée dans son ensemble.

    Voici un exemple qui se base sur la valeur d'une colonne (IdCol). Ici j'ai fait le choix de toujours dessiner le rectangle complet (même si la cellule est tronquée) mais modifie le style de ligne si le groupe n'est pas complètement visible. Les colonnes figées ne font pas partie du groupe.
    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
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    unit Unit1;
     
    interface
     
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids;
     
    type
      TForm1 = class(TForm)
        StringGrid1: TStringGrid;
        procedure FormCreate(Sender: TObject);
        procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
        procedure StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean);
        procedure StringGrid1TopLeftChanged(Sender: TObject);
     
      private const
        IdCol = 1;       // Colonne de référence
     
      private
        CurId :string;   // Référence actuelle
     
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      // Remplissage quelconque pour test
      var Id := 1;
     
      for var i := 1 to StringGrid1.RowCount -1 do
      begin
        StringGrid1.Cells[IdCol, i] := Id.ToString;
     
        if i mod 3 = 0 then
          inc(Id);
      end;
    end;
     
    procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
     
      //--------------------------------------------------------------------------------------------------
      procedure DrawLine(aCanvas :TCanvas; X1, Y1, X2, Y2 :integer);
      begin
        aCanvas.MoveTo(X1, Y1);
        aCanvas.LineTo(X2, Y2);
      end;
      //--------------------------------------------------------------------------------------------------
      procedure SelectPenStyle(aCanvas :TCanvas; aVisible, aReal :integer);
      begin
        if aVisible < aReal
        then aCanvas.Pen.Style := psDot
        else aCanvas.Pen.Style := psSolid;
      end;
     
    begin
      with StringGrid1 do
      begin
        var Id := Cells[IdCol, aRow];
     
        Canvas.Brush.Color := clWhite;
        Canvas.Pen.Color   := clRed;
        Canvas.Pen.Style   := psSolid;
     
        Canvas.FillRect(Rect);
     
        var s := Cells[aCol, aRow];
        Canvas.TextRect(Rect, s, [tfCenter, TfVerticalCenter, tfSingleLine]);
     
        // Groupe sélectionné ?
        if (aRow >= FixedRows) and (aCol >= FixedCols) and (Id = CurId) then
        begin
          // Dessine toujours le rectangle complet même si les cellules sont tronquées
          var R := TRect.Intersect(ClientRect, Rect);
     
          // Ligne à gauche (1ère colonne visible non figée)
          if aCol = LeftCol then
            DrawLine(Canvas, R.Left, R.Top, R.Left, R.Bottom);
     
          // Ligne en haut (1ère ligne visible non figée)
          if (aRow = TopRow) or (Cells[IdCol, aRow-1] <> Id) then
            DrawLine(Canvas, R.Left, R.Top, R.Right, R.Top);
     
          // Ligne à droite (La colonne peut être partiellement visible)
          if (aCol = ColCount -1) or (R.Right = ClientWidth) then
          begin
            SelectPenStyle(Canvas, R.Right, Rect.Right);
            DrawLine(Canvas, R.Right-1, R.Top, R.Right-1, R.Bottom);
          end;
     
          // Ligne en bas (La ligne peut être partiellement visible)
          if (aRow = RowCount -1) or (Cells[IdCol, aRow+1] <> Id) or (R.Bottom = ClientHeight) then
          begin
            SelectPenStyle(Canvas, R.Bottom, Rect.Bottom);
            DrawLine(Canvas, R.Left, R.Bottom-1, R.Right, R.Bottom-1);
          end;
        end;
      end;
    end;
     
    procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean);
    begin
      CurId := StringGrid1.Cells[IdCol, aRow];
      StringGrid1.Invalidate;
    end;
     
    procedure TForm1.StringGrid1TopLeftChanged(Sender: TObject);
    begin
      StringGrid1.Invalidate;
    end;
     
    end.

  17. #17
    Membre habitué

    Homme Profil pro
    Direction financière et formateur en gestion et contrôle de gestion
    Inscrit en
    Mai 2003
    Messages
    199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Direction financière et formateur en gestion et contrôle de gestion
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2003
    Messages : 199
    Points : 129
    Points
    129
    Par défaut
    Râââââ les mecs, vous êtes super fort!
    Je suis impressionné par votre connaissance de l'outil et j'apprends plein de chose, moi, l'autodidacte ...
    Bon, je vais regarder ça de plus prêt.

    Tiens je note le .invalidate pour raffraichir la StringGrid. Je fais Repaint (qui contient le invalidate). Il y a un truc à savoir là dessus ?

  18. #18
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 268
    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 268
    Points : 41 671
    Points
    41 671
    Billets dans le blog
    64
    Par défaut
    Un genre de YAPLUKA cité plus haut : sélection des cellules autour de la cellule sélectionnée

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    procedure TForm12.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
      var CanSelect: Boolean);
    begin
    Groupe.Create(Max(Acol-1,1),Max(ARow-1,1),
                  Min(ACol+1,StringGrid1.ColCount-1),Min(ARow+1,StringGrid1.Rowcount-1));
    memo1.Lines.Add(format('cellule %d,%d, groupe %d,%d,%d,%d',[ACol,Arow,Groupe.Left,groupe.Top,groupe.right,groupe.bottom]) );
    StringGrid1.Invalidate;
    end;
    Tiens je note le .invalidate
    je l'oublie toujours, heureusement Andnotor le rappelle

  19. #19
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 831
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 831
    Points : 13 579
    Points
    13 579
    Par défaut
    Citation Envoyé par patrice@ Voir le message
    Tiens je note le .invalidate pour raffraichir la StringGrid. Je fais Repaint (qui contient le invalidate). Il y a un truc à savoir là dessus ?
    Invalidate définit une zone devant être rafraîchie sans pour autant forcer le rafraîchissement immédiat. Ce n'est qu'au prochain message WM_PAINT (asynchrone) que les modifications seront visibles.

    A contrario, Repaint force immédiatement WM_PAINT (synchrone). La zone à rafraîchir doit, elle, de toute façon être définie.

    On utilise en général Invalidate. Les messages de repeinture n'étant pas prioritaire, ils sont concaténés en un seul message et ne surviennent que lorsque la pile de messages est vide. On utilisera plutôt Repaint lors d'une procédure longue si on veut afficher des informations en cours d'exécution.

  20. #20
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 446
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 446
    Points : 5 867
    Points
    5 867
    Par défaut
    salut


    peut etre que ceci te donnera des idée

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [Lazarus] Stringgrid et plusieurs lignes dans une même cellule
    Par dav999 dans le forum Lazarus
    Réponses: 2
    Dernier message: 12/11/2010, 23h53
  2. Réponses: 4
    Dernier message: 10/10/2010, 12h46
  3. Colorier la cellule sélectionnée d'un StringGrid
    Par Flyingmax dans le forum Débuter
    Réponses: 11
    Dernier message: 13/12/2009, 22h23
  4. [XL-2003] Numéro de ligne de la cellule sélectionnée
    Par Coralye dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 11/11/2009, 18h43
  5. Réponses: 5
    Dernier message: 22/03/2007, 13h52

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