如何将CR / LF放入TStringgrid单元格?

时间:2010-12-11 02:26:25

标签: delphi delphi-xe2

我希望有一个固定的行作为标题,但文本相当长,所以我想增加行高并将CR / LF插入单元格文本。

谷歌搜索显示这是一个解决方案(这是我在谷歌搜索之前想到的第一件事),但它没有看到工作。有什么想法吗?

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

(德尔福7,如果它有任何区别)

[Bounty]“我的不好。两年前我实际上没有检查就给了这个答案,现在发现答案没有用。对被误导的人说话。这是一个FABOWAQ(经常被问到,经常被错误回答的问题) ).GINYF“。

我认为我们正在寻找使用OnDrawCell,但想象我们还必须增加包含单元格的字符串网格行的高度。

我将为代码或FOSS VCL组件授予答案。

[更新]必须与D​​elphi XE2 Starter edition一起使用

2 个答案:

答案 0 :(得分:20)

TStringGrid使用Canvas.TextRectOnDrawCell使用ExtTextOut,而后者又不支持绘制多行文字。

您必须使用WinAPI的DrawText例程在DrawText事件处理程序中自行绘制。请参阅this answer,了解如何使用OnDrawCell进行多行文字,this recent answer了解如何在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; 中实施自定义绘图:

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;

Default StringGrid


还有其他能够绘制多行文本的StringGrid组件。例如,我自己编写的this one(下载来源:NLDStringGrid + NLDSparseList)可能会产生以下结果:

NLDStringGrid

{{1}}

答案 1 :(得分:5)

TStringGrid的默认渲染器不支持多行。通过在OwnerDraw模式下设置TStringGrid(通过调用OnDrawCell事件),您可以根据自己的喜好渲染每个单元格。

请查看this以获取帮助前一位用户的示例。

已插入链接参考代码:

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;

我认为这对你很好......