2010-12-11 30 views
7

Tôi muốn có một hàng cố định làm tiêu đề, nhưng văn bản khá dài, vì vậy tôi muốn tăng chiều cao hàng và chèn CR/LF vào văn bản ô.Làm thế nào để đưa CR/LF vào một ô TStringgrid?

Googling cho thấy đây là giải pháp (và đó là điều đầu tiên tôi nghĩ trước khi googling), nhưng nó không thấy hoạt động. Bất kỳ ý tưởng?

Grid.Cells[2,3] := 'This is a sample test' + #13#10 + 'This is the second line'; 

gì xảy ra là các tế bào chứa This is a sample testThis is the second line

(Delphi 7 nếu nó làm cho bất kỳ sự khác biệt)

[Bounty] "My xấu. Tôi thực sự trao này một câu trả lời hai năm trước đây mà không kiểm tra và bây giờ thấy rằng câu trả lời không có tác dụng. Xin lỗi cho bất cứ ai bị lừa. Đây là câu hỏi thường gặp (câu hỏi thường gặp, thường được trả lời sai) GINYF.

Tôi đoán rằng chúng tôi đang tìm cách sử dụng OnDrawCell, nhưng hãy tưởng tượng rằng chúng tôi cũng sẽ phải tăng chiều cao của hàng lưới ô có chứa ô.

Tôi sẽ trao giải đáp cho mã hoặc thành phần VCL FOSS.

[Cập nhật] phải hoạt động với Delphi XE2 Phiên bản Starter

+3

RowHeights [#] của TStringGrid sẽ không giúp đỡ? chỉnh sửa: AFAICS trong mã được liên kết trong câu trả lời, RowHeights được sử dụng ở mức độ đó. –

Trả lời

20

TStringGrid sử dụng Canvas.TextRect, trong đó sử dụng ExtTextOut, do đó không hỗ trợ bản vẽ của multiline bản văn.

Bạn phải tự vẽ điều này trong trình xử lý sự kiện OnDrawCell với thói quen DrawText của WinAPI. Xem ví dụ this answer về cách sử dụng DrawText cho văn bản nhiều dòng, và this recent answer về cách thực hiện vẽ trong OnDrawCell tùy chỉnh:

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; 

Default StringGrid


Ngoài ra còn có các thành phần StringGrid khác có thể vẽ text multiline . Ví dụ, this one mà tôi đã viết bản thân mình (nguồn download: NLDStringGrid + NLDSparseList) với khả năng kết quả này:

NLDStringGrid

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; 
+0

+1 @NGLN Tôi sẽ D/L và dùng thử ngay bây giờ. Bất kỳ hạn chế nào về việc sử dụng? – Mawg

+0

Biên dịch không thành công - không thể tìm thấy DesignEditors.dcu - có lẽ vì tôi đang sử dụng phiên bản XE2 Starter? – Mawg

+0

@Mawg Có thể, nhưng tôi không biết. Bạn đã chuyển đổi các gói tập tin để XE2? Lưu ý dòng 'require DesignIde'! Hãy thử thời gian chạy khác. – NGLN

5

Trình kết xuất mặc định của TStringGrid không hỗ trợ nhiều dòng. Bằng cách thiết lập TStringGrid trong chế độ OwnerDraw (bằng cách gọi sự kiện OnDrawCell), bạn có thể hiển thị từng ô theo ý thích của riêng bạn.

Hãy xem this để biết ví dụ giúp người dùng trước đó.

mã tham chiếu liên kết chèn vào:

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; 

Tôi nghĩ rằng điều này sẽ làm việc tốt cho bạn ...

+0

+1 Điều đó có vẻ tốt. Tôi sẽ cung cấp cho nó một thử & lấy lại cho bạn.Cảm ơn – Mawg

+3

Mã đó đặt 'RowHeights []' trong thường trình 'DrawCell'. Uglhh ... – NGLN

+1

@Mawg, đó là một ví dụ (trong nhiều điểm) về cách bạn không nên viết mã (ngoại trừ việc nó làm những gì NGLN chỉ ra). Đề nghị của tôi, không sử dụng nó ... – TLama

Các vấn đề liên quan