Come mettere CR / LF in una cella TStringGrid?
-
08-10-2019 - |
Domanda
Voglio avere una riga fissa come intestazione, ma i testi sono piuttosto lungo, quindi mi piacerebbe aumentare l'altezza della riga e l'inserto CR / LF nel testo della cella.
googling spettacoli questo come una soluzione di (ed è la prima cosa che ho pensato fo prima googling), ma down't vedere al lavoro. Tutte le idee?
Grid.Cells[2,3] := 'This is a sample test' + #13#10 + 'This is the second line';
Quello che succede è che la cella contiene This is a sample testThis is the second line
(Delphi 7 se fa alcuna differenza)
[Bounty] "Il mio male. Io in realtà assegnato questa una risposta di due anni fa senza controllare e ora scoprire che la risposta non ha funzionato. Aplogies a chi è stato ingannato. Si tratta di una FABOWAQ (domande più frequenti, questione spesso erroneamente risposto ). GINYF".
Presumo che stiamo cercando di utilizzare OnDrawCell, ma immaginare che avremmo anche dovuto aumentare l'altezza della riga della griglia di stringa che contiene la cella.
I assegnerà la risposta sia per codice o un componente FOSS VCL.
[Aggiornamento] Il lavoro deve con l'edizione Delphi XE2 Starter
Soluzione
usi TStringGrid
Canvas.TextRect
, che utilizza ExtTextOut
, che a sua volta non supporta il disegno di testo su più righe.
È necessario disegnare questo se stessi in un gestore di eventi OnDrawCell
con WinAPI di DrawText
routine. Vedi ad esempio questa risposta su come utilizzare DrawText
per il testo su più righe, e questa recente risposta su come implementare il disegno personalizzato in OnDrawCell
:
type
TForm1 = class(TForm)
StringGrid1: TStringGrid;
procedure FormCreate(Sender: TObject);
procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
private
procedure FillWithRandomText(AGrid: TStringGrid);
procedure UpdateRowHeights(AGrid: TStringGrid);
end;
procedure TForm1.FillWithRandomText(AGrid: TStringGrid);
const
S = 'This is a sample'#13#10'text that contains'#13#10'multiple lines.';
var
X: Integer;
Y: Integer;
begin
for X := AGrid.FixedCols to AGrid.ColCount - 1 do
for Y := AGrid.FixedRows to AGrid.RowCount - 1 do
AGrid.Cells[X, Y] := Copy(S, 1, 8 + Random(Length(S) - 8));
UpdateRowHeights(AGrid);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FillWithRandomText(StringGrid1);
end;
procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
with TStringGrid(Sender) do
if Pos(#13#10, Cells[ACol, ARow]) > 0 then
begin
Canvas.FillRect(Rect);
Inc(Rect.Left, 2);
Inc(Rect.Top, 2);
DrawText(Canvas.Handle, PChar(Cells[ACol, ARow]), -1, Rect,
DT_NOPREFIX or DT_WORDBREAK);
end;
end;
procedure TForm1.UpdateRowHeights(AGrid: TStringGrid);
var
Y: Integer;
MaxHeight: Integer;
X: Integer;
R: TRect;
TxtHeight: Integer;
begin
for Y := AGrid.FixedRows to AGrid.RowCount - 1 do
begin
MaxHeight := AGrid.DefaultRowHeight - 4;
for X := AGrid.FixedCols to AGrid.ColCount - 1 do
begin
R := Rect(0, 0, AGrid.ColWidths[X] - 4, 0);
TxtHeight := DrawText(AGrid.Canvas.Handle, PChar(AGrid.Cells[X, Y]), -1,
R, DT_WORDBREAK or DT_CALCRECT);
if TxtHeight > MaxHeight then
MaxHeight := TxtHeight;
end;
AGrid.RowHeights[Y] := MaxHeight + 4;
end;
end;
Ci sono anche altri componenti StringGrid capaci di disegnare testo su più righe. Per esempio, questo uno che io stesso ho scritto (fonti per il download: < a href = "https://svn.apada.nl/svn/NLDelphi-opensource/walterheck/nldstringgrid/" rel = "nofollow noreferrer"> NLDStringGrid + NLDSparseList ) con possibile questo risultato:
var
R: TRect;
begin
NLDStringGrid1.Columns.Add;
NLDStringGrid1.Columns.Add;
NLDStringGrid1.Cells[1, 1] := 'Sample test'#13#10'Second line';
NLDStringGrid1.Columns[1].MultiLine := True;
NLDStringGrid1.AutoRowHeights := True;
SetRect(R, 2, 2, 3, 3);
NLDStringGrid1.MergeCells(TGridRect(R), True, True);
NLDStringGrid1.ColWidths[2] := 40;
NLDStringGrid1.Cells[2, 2] := 'Sample test'#13#10'Second line';
end;
Altri suggerimenti
di rendering di default del TStringGrid non supportano più righe. Impostando la TStringGrid in modalità OwnerDraw (invocando l'evento OnDrawCell) si può rendere ogni cella dal proprio piacimento.
Date un'occhiata al questo per un esempio che ha contribuito a un utente precedente.
codice di riferimento Linked inserito:
procedure DrawSGCell(Sender : TObject; C, R : integer; Rect : TRect;
Style : TFontStyles; Wrap : boolean; Just : TAlignment;
CanEdit : boolean);
{ draws formatted contents in string grid cell at col C, row R;
Style is a set of fsBold, fsItalic, fsUnderline and fsStrikeOut;
Wrap invokes word wrap for the cell's text; Just is taLeftJustify,
taRightJustify or taCenter; if CanEdit false, cell will be given
the background color of fixed cells; call this routine from
grid's DrawCell event }
var
S : string;
DrawRect : TRect;
begin
with (Sender as tStringGrid), Canvas do begin
{ erase earlier contents from default drawing }
if (R >= FixedRows) and (C >= FixedCols) and CanEdit then
Brush.Color:= Color
else
Brush.Color:= FixedColor;
FillRect(Rect);
{ get cell contents }
S:= Cells[C, R];
if length(S) > 0 then begin
case Just of
taLeftJustify : S:= ' ' + S;
taRightJustify : S:= S + ' ';
end;
{ set font style }
Font.Style:= Style;
{ copy of cell rectangle for text sizing }
DrawRect:= Rect;
if Wrap then begin
{ get size of text rectangle in DrawRect, with word wrap }
DrawText(Handle, PChar(S), length(S), DrawRect,
dt_calcrect or dt_wordbreak or dt_center);
if (DrawRect.Bottom - DrawRect.Top) > RowHeights[R] then begin
{ cell word-wraps; increase row height }
RowHeights[R]:= DrawRect.Bottom - DrawRect.Top;
SetGridHeight(Sender as tStringGrid);
end
else begin
{ cell doesn't word-wrap }
DrawRect.Right:= Rect.Right;
FillRect(DrawRect);
case Just of
taLeftJustify : DrawText(Handle, PChar(S), length(S), DrawRect,
dt_wordbreak or dt_left);
taCenter : DrawText(Handle, PChar(S), length(S), DrawRect,
dt_wordbreak or dt_center);
taRightJustify : DrawText(Handle, PChar(S), length(S), DrawRect,
dt_wordbreak or dt_right);
end;
end
end
else
{ no word wrap }
case Just of
taLeftJustify : DrawText(Handle, PChar(S), length(S), DrawRect,
dt_singleline or dt_vcenter or dt_left);
taCenter : DrawText(Handle, PChar(S), length(S), DrawRect,
dt_singleline or dt_vcenter or dt_center);
taRightJustify : DrawText(Handle, PChar(S), length(S), DrawRect,
dt_singleline or dt_vcenter or dt_right);
end;
{ restore no font styles }
Font.Style:= [];
end;
end;
end;
Credo che questo funziona bene per voi ...