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 :

StringGrid fusion des cellules


Sujet :

Delphi

  1. #21
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    ho pwo pwo ! Je pressens le truc...
    Laisses moi le temps d'y jeter un oeil

    En attendant, jette le tien ici, les chinois ont été plus courageux que moi :
    http://images.google.fr/imgres?imgur...%3D1%26hl%3Dfr

    Bidouilleuse Delphi

  2. #22
    Membre du Club
    Inscrit en
    Août 2008
    Messages
    117
    Détails du profil
    Informations forums :
    Inscription : Août 2008
    Messages : 117
    Points : 50
    Points
    50
    Par défaut
    Wooooww ils n'ont pas peur les chinois mais on comprend rien a leur écriture !!

  3. #23
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while i<(GridDraftRead.ColCount - 1) do
    Pourquoi parcoures tu et crées tu tes zones fusionnées pendant l'évènement qui est censé dessiner les cellules ? il faut impérativement mettre ça ailleurs

    Regarge mon code exemple :
    1) la création des zone fusionnées est faites dans le OnCreate de la Fiche (ça pourrait être dans le OnClick d'un bouton)

    2) La variable de type TZoneFusionnee est une variable globale

    3) Et pour le dessin, il ne faut pas que tu t'amuses à reparcourrir tout le stringgrid dans le OnDrawCell, Delphi est déjà en train de le faire pour toi.
    Quand ton code OnDrawCell est appelé, delphi est déjà en train d'effectuer cette boucle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    for ARow:=0 to GridDraftRead.RowCount - 1 do
        for ACol:=0 to GridDraftRead.ColCount - 1 do
             Appel_de_ton_Code_contenu_dans_le_OnDrawCell;
    Toi, ce que tu as juste à faire, c'est de t'occuper de dessiner la cellule qu'il te propose (et tu n'as pas le droit de modifier leur contenu à ce moment là ! Sinon, ça clignote, forcément...).
    Delphi te dis à quelle cellule c'est le tour d'être dessiné (ACol,ARow), son état, etc...

    Tiout ce qu'on fait avec cette "bidouille" c'est de dire :
    - si finalement on dessine la cellule normalement à ce moment là,
    - si on prend de l'avance sur les cellules que va nous proposer delphi en dessinant la première cellule d'une zone fusionnée et les autres cellules qui y sont rattachées d'un seul coup d'un seul.
    - ou si on s'abstient de dessiner une cellule (puisqu'on la déjà dessiné avec la première cellule d'une zone fusionnée)

    tu vois la chose un peu mieux ?
    Bidouilleuse Delphi

  4. #24
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Je suis parti "croquer", à tout à l'heure
    Bidouilleuse Delphi

  5. #25
    Membre du Club
    Inscrit en
    Août 2008
    Messages
    117
    Détails du profil
    Informations forums :
    Inscription : Août 2008
    Messages : 117
    Points : 50
    Points
    50
    Par défaut
    Yes je comprend j'ai viré tous ça d'ailleurs.
    Je fais cela plus proprement. Etant donné que mon tableau ne fera pas plus de 13 colonnes et 12 lignes je vais faire directement un tableau de zones de fusion ce n'est pas plus compliqué.
    Le soucis c'est que avec la fonction dessinezone il faut déterminer le texte à dessiner et moi je veux reprendre le texte qui est écrit dans la grille.
    Certaines cases contiennent des nombres calculés et ils changent en fonction de la valeur dans les autres cases.
    Donc à chaque fois que je redessine le grid je doit reprendre ce texte.
    Est-ce possible?

  6. #26
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Citation Envoyé par cbegood Voir le message
    Certaines cases contiennent des nombres calculés et ils changent en fonction de la valeur dans les autres cases.
    Donc à chaque fois que je redessine le grid je doit reprendre ce texte.
    Est-ce possible?
    1) Tant que tu es dans le code du OnDrawCell, tu es assuré que la valeur des cellules ne change pas.
    2) Tu peux sans aucun problême lire le contenu de n'importe quelle cellule du Stringgrid.
    3) La zone fusionnée déssinera le contenu de la case du coin supérieure gauche de ta fusion. (que tu peux modifier hors OnDrawCell)
    Bidouilleuse Delphi

  7. #27
    Membre du Club
    Inscrit en
    Août 2008
    Messages
    117
    Détails du profil
    Informations forums :
    Inscription : Août 2008
    Messages : 117
    Points : 50
    Points
    50
    Par défaut
    Oki merci beaucoup pour tout ça m'as beaucoup aidé.
    Malheureusement je n'ai plus beaucoup de temps pour travailler la dessus aujourd'hui. Je m'y remettrai un autre jour et je te tiens au courant.

    Merci encore très sympa.

  8. #28
    Membre éprouvé
    Avatar de CapJack
    Homme Profil pro
    Prof, développeur amateur vaguement éclairé...
    Inscrit en
    Mars 2004
    Messages
    624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Prof, développeur amateur vaguement éclairé...
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 624
    Points : 988
    Points
    988
    Par défaut
    Euh... il me semble que j'avais bossé sur ce problème il y a de cela quelque temps déjà, à la fin on avait résolu tous les problèmes, y compris celui du défilement. Un fil que je ne retrouve plus...

  9. #29
    Membre du Club
    Inscrit en
    Août 2008
    Messages
    117
    Détails du profil
    Informations forums :
    Inscription : Août 2008
    Messages : 117
    Points : 50
    Points
    50
    Par défaut
    Alors me revoilà j'ai un peu avancé enfin.

    Voilà à quoi ressemble mon tableau maintenant.



    1) Je ne sais pas pourquoi la case 0,0 n'est pas écrite comme les autres (text centré)
    2) Comme l'utilisateur peut clicker sur les deux cases qui sont fusionnée j'aimerais que lorsqu'il click sur une case de gauche (ex 1,1) il soit directement envoyé à la case juste a droite (ex 1,2).
    Je pensais que ce serait simple qu'il suffirait de faire StringGrid.OnSelectCell(self,ACol+1,ARow,True) dans l'événement SelectCell, mais cela ne fonctionne pas. ???

    je poste l'unité si cela peut vous aider.

    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
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, Grids, StdCtrls, ExtCtrls, Spin,UnitFusionStringGrid;
     
    type
      TForm1 = class(TForm)
        GridDraftRead: TStringGrid;
        Panel1: TPanel;
        SpinEdtNbrDraftRead: TSpinEdit;
        procedure GridDraftReadSelectCell(Sender: TObject; ACol, ARow: Integer;
          var CanSelect: Boolean);
        procedure GridDraftReadDrawCell(Sender: TObject; ACol, ARow: Integer;
          Rect: TRect; State: TGridDrawState);
        procedure SpinEdtNbrDraftReadChange(Sender: TObject);
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
        procedure FillGrid;
        procedure CreateZoneFusion;
      public
        { Public declarations }
        Zones:array[0..9] of array[0..5] of TZoneFusionnee;
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.SpinEdtNbrDraftReadChange(Sender: TObject);
    begin
      GridDraftRead.ColCount:=StrToInt(SpinEdtNbrDraftRead.Text)+1;
      FillGrid;
      CreateZoneFusion;
    end;
     
    procedure TForm1.CreateZoneFusion;
    var i,j:integer;
    begin
      for j := 0 to 11 do
      begin
        for i := 0 to Trunc((GridDraftRead.ColCount-1)/2) do
        begin
          if not (j in [6..8]) then
          begin
            Zones[j,i]:=SetZoneFusionnee(GridDraftRead,GridDraftRead.Cells[(i*2)+1,j],(i*2)+1,j,(i*2)+2,j,alHCenter,alVCenter,JustCenter);
          end;
        end;
      end;
    end;
     
    procedure TForm1.FillGrid;
    var i:integer;
    begin
    i:=1;
    while i<(GridDraftRead.ColCount - 1) do
    begin
      if GridDraftRead.Cells[i,0]=''then GridDraftRead.Cells[i,0]:='Click';
      GridDraftRead.Cells[i,6]:='PS';
      GridDraftRead.Cells[i+1,6]:='SB';
      i:=i+2;
    end;
    end;
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
     
      with GridDraftRead do
      begin
        Cells[0,0]:='Type of reading';
        Cells[0,1]:='Measured at';
        Cells[0,2]:='Longitudinal location to origin [m]';
        Cells[0,3]:='Distance from baseline [m]';
        Cells[0,4]:='Distance from center line [m]';
        Cells[0,5]:='Priority factor [0-10]';
        Cells[0,6]:='Side';
        Cells[0,7]:='Distance from water line [m]';
        Cells[0,8]:='Draft [m]';
        Cells[0,9]:='Draft average [m]';
        Cells[0,10]:='Heel [m]';
        Cells[0,11]:='Heel [°]';
        ColWidths[0]:=length(GridDraftRead.Cells[0,4])*8;
      end;
     
      SpinEdtNbrDraftRead.OnChange(self);
      GridDraftRead.Col:=2;
      GridDraftRead.Row:=1;
     
    end;
     
    procedure TForm1.GridDraftReadDrawCell(Sender: TObject; ACol, ARow: Integer;Rect: TRect; State: TGridDrawState);
    var i,j:integer;
        DesParametres:TParametresOnDrawCell;
        OnADessineDansUneZone:Boolean;
    begin
    //On récupère les Paramêtres de OnDrawCell
      DesParametres.ACol:=ACol;
      DesParametres.ARow:=ARow;
      DesParametres.Rect:=Rect;
      DesParametres.State:=State;
    //Quel est le StringGrid qui déclenche l'évènement ?
      DesParametres.LeStringGrid:=(sender as TStringGrid);
     
        //J'utilise un tableau a 2 dimensions pour créer mes zones fusionnées.
        OnADessineDansUneZone:=False;
        i:=0;
        while ((i<Trunc((GridDraftRead.ColCount-1)/2)) and (not OnADessineDansUneZone)) do
        begin
          j:=0;
          while ((j<=11) and (not OnADessineDansUneZone)) do
          begin
            OnADessineDansUneZone:=DessineZone(DesParametres,Zones[j,i]);
            j:=j+1;
          end;
          i:=i+1;
        end;
        if not OnADessineDansUneZone then
        begin //puis si on a pas une cellule fusionnée on la dessine normalement
          DessineCellule(DesParametres,alHCenter,alVCenter,JustCenter);
        end;
     
     
    end;
     
    procedure TForm1.GridDraftReadSelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean);
    begin
    //Changement Draft/Freeboard
    if ((GridDraftRead.Cells[ACol,ARow]='Click') or (GridDraftRead.Cells[ACol,ARow]='Freeboard')) then
    begin
      GridDraftRead.Cells[ACol,ARow]:='Draft';
      GridDraftRead.Repaint;
    end
    else if(GridDraftRead.Cells[ACol,ARow]='Draft')then
    begin
      GridDraftRead.Cells[ACol,ARow]:='Freeboard';
      GridDraftRead.Repaint;
    end;
     
    //Changement de selection
    if ((not(ARow in [6..8]))and(ACol in [1,3,5,7,9,11])) then
      begin
      GridDraftRead.OnSelectCell(Self,ACol+1,ARow,CanSelect);
      end;
     
    //Specification des cases editable
    if ((ARow=7)or((ARow in [1..5]) and (ACol in [2,4,6,8,10,12]))) then
    begin
      GridDraftRead.Options:=GridDraftRead.Options+[goEditing];
      GridDraftRead.Options:=GridDraftRead.Options+[goAlwaysShowEditor];
    end
    else
    begin
      GridDraftRead.Options:=GridDraftRead.Options-[goEditing];
      GridDraftRead.Options:=GridDraftRead.Options-[goAlwaysShowEditor];
    end;
     
    end;
     
    end.

  10. #30
    Membre habitué
    Profil pro
    Inscrit en
    Février 2008
    Messages
    141
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 141
    Points : 142
    Points
    142
    Par défaut
    Salut,

    Pour le 1), à partir du code que tu as montré je ne vois pas le bug. La case 0,0 n'est pas une case fusionnée, c'est ça? Elle devrait être dessinnée par la partie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        if not OnADessineDansUneZone then
        begin //puis si on a pas une cellule fusionnée on la dessine normalement
          DessineCellule(DesParametres,alHCenter,alVCenter,JustCenter);
        end;
    Vérifie au debogueur la valeur des paramètres au moment où tu appelles DrawCell pour la cellule 0,0.


    Pour le 2) : il ne faut pas confondre l'évènement et la callback.
    Le fait de sélectionner une cellule déclenche un appel à OnSelectCell, mais le fait d'appeler la fonction OnSelectCell ne déclenche pas de changement de sélection sur la grille.
    Pour effectivement changer la sélection de la grille, regarde plutôt du côté des propriétés "Col", "Row" et "Selection" de la classe mère TCustomGrid. La documentation de ma version de Delphi (bds 2006) est on ne peut plus floue sur le type TStringGrid (la page de TStringGrid ne liste pas toutes les méthodes et propriétés héritées de ses classes mères! ), je te laisse te débrouiller avec la tienne...

    Ceci dit, il est un peu dangereux, dans le OnSelectCell, de déclencher un nouvel évènement "Sélection" (qui appellera à nouveau un OnSelectCell, qui risque de déclencher un évt "Sélection", qui appellera à nouveau.... ). Tu peux le faire si tu es sûr de casser la boucle d'appels à un moment, mais si tu comptes redévelopper ta grille plus tard, tu risques de tomber sur des bugs assez surprenants.

    Je te conseillerais plutôt d'écrire une autre fonction, par exemple "OnSelectMergedCell", avec la même signature, et de transformer ton OnSelectCell en :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    procedure TForm1.GridDraftReadSelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean);
      var
        MergedCol, MergedRow : integer;
    begin
      MergedCol := GetMergedCol( ACol, ARow );
      MergedRow := GetMergedRow( ACol, ARow );
      OnSelectMergedCell( Sender, MergedCol, MergedRow, CanSelect );
    end;
    En espérant être assez clair...

    *LeGEC*
    *LeGEC*

  11. #31
    Membre du Club
    Inscrit en
    Août 2008
    Messages
    117
    Détails du profil
    Informations forums :
    Inscription : Août 2008
    Messages : 117
    Points : 50
    Points
    50
    Par défaut
    Voilà ce que m'affiche le debugger:

    Unit1.TForm1.GridDraftReadDrawCell($B300F0,0,0,(0, 0, 232, 24, (0, 0), (232, 24)),[gdFixed])

    Je ne vois pas de soucis.
    Seulement j'ai placé un showmessage dans la partie ou il devrait dessiner cette case et le programme ne passe pas par cette partie pour la case 0,0. Mais je ne comprend pas du tout pourquoi j'ai revérifié mes Zones de fusion la case 0,0 n'y est pas reprise.

    Pour l'astuce de la procédure StringGrid.selection, je cherche toujours je n'arrive pas a sélectionner la case adjacente.

    Voilà ce que j'ai essayé:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    if ((not(ARow in [6..8]))and(ACol in [1,3,5,7,9,11])) then
      begin
      //GridDraftRead.Col:=ACol+1;
      GridRect.Left:=GridDraftRead.CellRect(ACol+1,ARow).Left;
      GridRect.Top:=GridDraftRead.CellRect(ACol+1,ARow).Top;
      GridRect.Bottom:=GridDraftRead.CellRect(ACol+1,ARow).Bottom;
      GridRect.Right:=GridDraftRead.CellRect(ACol+1,ARow).Right;
      GridDraftRead.Selection:=GridRect;
      end;
    sans résultat.

  12. #32
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Salut

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if ((not(ARow in [6..8]))and(ACol in [1,3,5,7,9,11])) then
    Avec ACol = 0 cette condition sera toujours fausse.

    [edit]
    A mon avis
    peut être simplifié en:
    @+

  13. #33
    Membre du Club
    Inscrit en
    Août 2008
    Messages
    117
    Détails du profil
    Informations forums :
    Inscription : Août 2008
    Messages : 117
    Points : 50
    Points
    50
    Par défaut
    Merci pour la simplification je ne connaissait pas cette fonction Odd(integer).

    Par contre ta première remarque est vraie mais je ne vois pas quel problème cela pose que cette condition soit toujours fausse avec ACol=0 c'est le but.

Discussions similaires

  1. [HTML] Tableau pbl bordure et fusion des cellules
    Par Epistoliere dans le forum Balisage (X)HTML et validation W3C
    Réponses: 5
    Dernier message: 03/08/2006, 16h42
  2. [JSF] Fusion des cellules
    Par Shivan dans le forum JSF
    Réponses: 3
    Dernier message: 11/04/2006, 10h21
  3. [Swing][JTable]Fusion des cellules d'un tableau
    Par LordBlaize dans le forum Composants
    Réponses: 1
    Dernier message: 23/03/2006, 18h48
  4. [VB6] Problème MsFlexgrid et Fusion des cellules
    Par dubidon dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 07/02/2006, 09h00
  5. [StringGrid]Alignement des Cellules
    Par touhami dans le forum Composants VCL
    Réponses: 3
    Dernier message: 06/11/2005, 19h38

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