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
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
Wooooww ils n'ont pas peur les chinois mais on comprend rien a leur écriture !!
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
Code : Sélectionner tout - Visualiser dans une fenêtre à part while i<(GridDraftRead.ColCount - 1) do
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 :
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...).
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;
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
Je suis parti "croquer", à tout à l'heure
Bidouilleuse Delphi
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?
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
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.
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...
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.
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 :
Vérifie au debogueur la valeur des paramètres au moment où tu appelles DrawCell pour la cellule 0,0.
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;
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 :
En espérant être assez clair...
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;
*LeGEC*
*LeGEC*
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é:
sans résultat.
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;
Salut
Avec ACol = 0 cette condition sera toujours fausse.
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
[edit]
A mon avis
peut être simplifié en:
Code : Sélectionner tout - Visualiser dans une fenêtre à part ACol in [1,3,5,7,9,11]
@+
Code : Sélectionner tout - Visualiser dans une fenêtre à part Odd(ACol)
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.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager