Как поместить CR / LF в ячейку TStringgrid?
Я хочу иметь одну фиксированную строку в качестве заголовка, но тексты довольно длинные, поэтому я хотел бы увеличить высоту строки и вставить CR/LF в текст ячейки.
Googling показывает это как решение (и это первое, что я подумал, прежде чем гуглить), но он не видит, чтобы работать. Есть идеи?
Grid.Cells[2,3] := 'This is a sample test' + #13#10 + 'This is the second line';
что происходит, так это то, что ячейка содержит This is a sample testThis is the second line
(Delphi 7, Если это имеет значение)
[щедрость] " мой плохой. Я на самом деле наградил это ответ два года назад без проверки и теперь выясняется, что ответ не сработал. Aplogies для тех, кто был введен в заблуждение. Это FABOWAQ (часто задаваемый, часто неправильно отвечаемый вопрос). GINYF".
Я предполагаю, что мы хотим использовать OnDrawCell, но представьте, что нам также придется увеличить высоту строки сетки, содержащей ячейку.
Я буду вручать ответ либо код или компонента VCL Фосс.
[Update] должен работать с Делфи XE2 в редакции Starter
2 ответов
TStringGrid
использует Canvas.TextRect
, который использует ExtTextOut
, что в свою очередь не поддерживает рисование многострочного текста.
вы должны нарисовать это сами в OnDrawCell
обработчик событий с WinAPI в DrawText
рутины. См., например,ответ как использовать DrawText
для многострочного текста, а этот недавний ответ о том, как реализовать пользовательский рисунок в 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;
есть также другие компоненты StringGrid, способные рисовать многострочный текст. Например, этот который я написал сам (скачать исходники: NLDStringGrid + NLDSparseList) С возможным результатом:
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;
средство визуализации TStringGrid по умолчанию не поддерживает несколько строк. Установив TStringGrid в режиме OwnerDraw (вызвав событие OnDrawCell), вы можете визуализировать каждую ячейку по своему вкусу.
посмотреть этой для примера, который помог предыдущий пользователь.
вставлен связанный ссылочный код:
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;
Я думаю, что это будет прекрасно работать для вас...