L'Evento drawcell della StringGrid continua a mettermi in difficoltà, per me insormontabili.
Durante compilazione di una stringGrid, vorrei evidenziare un tipo particolare, impostando lo style fsbold. Ho pensato di farlo sfrtuttando l'evento onDrawCell, ma riesco ad applicare lo fsbold soltanto all cella indirizzata dalla coordinate, ma nemmeno bene.
Riporto sia il codice che il risultato pratico della prova:
procedure TForm8.GridPreAmmortDrawCell(Sender: TObject; aCol, aRow: Integer;
aRect: TRect; aState: TGridDrawState);
var
lun, p, totRg: Integer;
cellaSel: String;
allin : TTextStyle; // tipo di allineamento
begin
if (aRow <> 0) then
begin
cellaSel:= Form8.GridPreAmmort.Cells[aCol, aRow]; // punta alla casella selezionata
if (Form8.GridPreAmmort.Cells[8, aRow] = 'X') and (Length(Form8.GridPreAmmort.Cells[7, aRow]) > 0) then
begin
bla, bla, bla
end
else begin
p:= pos( 'Totali', cellaSel); // <--- individuo ogni cella che contiene la sottostringa
if (p > 0) then
begin
GridPreAmmort.Canvas.Font.Style:= [fsBold];
lun:= Form8.GridPreAmmort.Canvas.TextWidth(cellaSel);
allin:= Canvas.TextStyle;
case Form8.GridPreAmmort.Canvas.TextStyle.Alignment of // rileva il tipo di allineamento dichiarato per la casella
taLeftJustify:
begin
if (aCol = 0) then
begin
Form8.GridPreAmmort.Canvas.TextOut(aRect.Right - lun - 1, aRect.Top + 2, CellaSel);
end
else begin
Form8.GridPreAmmort.Canvas.TextOut(aRect.Left + 2, aRect.Top + 2, CellaSel);
end;
end;
taRightJustify:
begin
Form8.GridPreAmmort.Canvas.TextOut(aRect.Right - lun - 2, aRect.Top + 2, CellaSel);
end;
taCenter:
begin
Form8.GridPreAmmort.Canvas.TextOut(aRect.Left + ((lun div 2) - 7), aRect.Top + 2, CellaSel);
end;
end;
end;
end;
end;
end;
Così facendo però riesco solo ad impostare ilo stile fsbold alla cella contetente la sottostringa "Totali", ma nemmeno bene, come si può vedere benissimo nell'allegato.
Ho scoperto poi che l'evento onDrawCell viene schedulato 2 volte, ... ma perchè?
Andando per gradi, la pima difficoltà da superare, per rispettare il titolo della discusione, credo che sia quella di capire come applicare il carattere fsbold a tutta la riga a cui appartiene la cella con la sottostringa "Totali", anche sporca come appare nell'allegato.
:-\
Peggio di così non può andare.
Ho impostato a False la proprietà DefaultDrawing della StringGrid e da quel momento qualsiasi azione svolta sulle singole celle , NON produce più la visibilità del loro contenuto, perciò la StringGrid si mostra completamente vuota.
Riporto il codice interno alla procedura-evento GridPreAmmortDrawCell.
procedure TForm8.GridPreAmmortDrawCell(Sender: TObject; aCol, aRow: Integer;
aRect: TRect; aState: TGridDrawState);
var
swStylFsBold: Boolean = False;
i, lun, p, totRg, ixCol, ixRg : Integer;
cellaSel: String;
allin : TTextStyle; // tipo di allineamento
begin
cellaSel:= GridPreAmmort.Cells[aCol, aRow]; // punta alla casella selezionata
if (aRow = 0) then
begin
GridPreAmmort.Canvas.Font.Style:= [fsBold];
allin:= Canvas.TextStyle;
end;
if (aCol = 0) and (aRow > 0) then
begin
GridPreAmmort.Canvas.Font.Style:= [fsBold];
lun:= Form8.GridPreAmmort.Canvas.TextWidth(cellaSel);
Dec(ARect.Right, varCellPadding);
Dec(ARect.Right, 1);
allin:= Canvas.TextStyle;
allin.Alignment:= taRightJustify;
end;
if (aCol > 0) and (aRow > 0) then
begin
p:= pos( 'Totali', cellaSel);
if (p > 0) then
begin
swStylFsBold:= True;
GridPreAmmort.Canvas.Font.Style:= [fsBold];
GridPreAmmort.Canvas.Rectangle(aRect);
end
else begin
if swStylFsBold then
begin
GridPreAmmort.Canvas.Font.Style:= [fsBold];
end
else begin
GridPreAmmort.Canvas.Font.Style:= [];
end;
end;
case Form8.GridPreAmmort.Canvas.TextStyle.Alignment of // rileva il tipo di allineamento dichiarato per la casella
taLeftJustify:
begin
Form8.GridPreAmmort.Canvas.TextOut(aRect.Left - lun - 1, aRect.Top, CellaSel);
end;
taRightJustify:
begin
Form8.GridPreAmmort.Canvas.TextOut(aRect.Right - lun - 2, aRect.Top, CellaSel);
end;
taCenter:
begin
Form8.GridPreAmmort.Canvas.TextOut(aRect.Left + ((lun div 2) - 7), aRect.Top, CellaSel);
end;
end;
end;
end;
Non capisco assolutamente dove sbaglio, ma può anche essere che: dovrei eseguire qualcosa e non lo faccio.
Pare che ho risolto.
Ho reimpostato la proprietà DefaultDrawing = True ed ho scritto le mie istruzioni di evidenziazione dentro la prtocedura legata all'Evento OnPrepareCanvas:
procedure TForm8.GridPreAmmortPrepareCanvas(Sender: TObject; aCol,
aRow: Integer; aState: TGridDrawState);
var
ts: TTextStyle;
p: Integer;
ixRg: Integer = (-1);
begin
if (aCol = 0) then
begin
With GridPreAmmort.Canvas.Font do
begin
Name:= 'Noto Sans TJK TC';
Size:= 9;
Style := [fsBold]; // Stile Grassetto per la riga di testa
end;
ts := GridPreAmmort.Canvas.TextStyle;
ts.Alignment := taRightJustify;
GridPreAmmort.Canvas.TextStyle := ts;
end;
if (aCol = 3) and (aRow > 0) then
begin
p:= pos( 'Totali', GridPreAmmort.Cells[aCol, aRow]);
if (p > 0) then
begin
GridPreAmmort.Canvas.Font.Style:= [fsBold];
ixRg:= aRow;
end;
if (Length(GridPreAmmort.Cells[aCol, aRow]) > 0) and (aRow = iXRg) then
begin
GridPreAmmort.Canvas.Font.Style:= [fsBold];
end;
end;
end;
Ecco il risultato
A questo punto l'Evento OnDrawCell non m'interessa più.