2010-12-11 20 views
7

Başlık olarak tek bir sabit satıra sahip olmak istiyorum, ancak metinler oldukça uzun, bu yüzden satır yüksekliğini arttırmak ve CR/LF'yi hücre metnine eklemek istiyorum.CR/LF bir TStringgrid hücresine nasıl yerleştirilir?

Googling bunu bir çözüm olarak gösterir (ve googling'ten önce düşündüğüm ilk şey), ama işe yaramaz. Herhangi bir fikir?

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

ne olur hücre This is a sample testThis is the second line

[Bounty] "Benim hatam. Aslında kontrol etmeden iki yıl önce bu bir cevap verilir (Delphi 7 herhangi bir fark yaparsa) içermesidir ve şimdi cevabın işe yaramadığını bulmuştum.Kullanıldıkları kişilere aplojiler: Bu bir FABOWAQ (sık sorulan, genellikle yanlış cevaplanmış bir soru) .GINYF ".

OnDrawCell'i kullanmayı düşündüğümüzü varsayalım, ancak hücreyi içeren dize ızgarası satırının yüksekliğini de arttırmamız gerektiğini düşünün.

Kodun ya da FOSS VCL bileşeninin cevabını vereceğim.

[Güncelleme] birden fazla satır desteklemeyen Delphi XE2 Starter sürümünde

+3

RowHeights [#] yardımcı olmaz? düzenleme: Bağlantılı koddaki AFAICS, cevapta RowHeights bu ölçüde kullanılır. –

cevap

20

TStringGrid sırayla satırlı çizimini desteklemez ExtTextOut, kullandığı, Canvas.TextRect kullanır Metin.

Kendinizi bir OnDrawCell olay işleyicisinde, WinAPI'nin DrawText rutini ile çizmek zorundasınız. nasıl OnDrawCell çizim özel uygulamak için üzerinde çok satırlı metin için DrawText ve this recent answer nasıl kullanılacağı hakkında örnek this answer için bakınız:

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


da satırlı metin çizim mümkün diğer StringGrid bileşeni vardır . muhtemelen bu sonuçla: Örneğin, this one I (+ NLDSparseListNLDStringGrid indir kaynakları): kendim yazdım hangi TStringGrid ait

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 D/L yapacak ve şimdi deneyeceğim. Kullanımdaki kısıtlamalar nelerdir? – Mawg

+0

Derleme başarısız - DesignEditors.dcu bulamıyor - muhtemelen XE2 Starter sürümünü kullanıyorum çünkü? – Mawg

+0

@Mawg Muhtemelen, ama bilmiyorum. Paket dosyasını XE2'ye dönüştürdünüz mü? 'DesignIde' satırını gerektirir! Aksi takdirde çalışma zamanı deneyin. – NGLN

5

TStringGrid varsayılan işleyici ile çalışmalıdır. TStringGrid'i OwnerDraw modunda ayarlayarak (OnDrawCell olayını çağırmak suretiyle) her bir hücreyi kendi beğeninize göre oluşturabilirsiniz.

Önceki bir kullanıcıya yardımcı olan bir örnek için this'a bakın.

sokulan Bağlantılı referans kodu: Bunun senin için iyi çalışacağını düşünüyorum

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; 
...

+0

+1 Güzel görünüyor. Bir deneyeceğim ve size geri döneceğim.Teşekkürler – Mawg

+3

Bu kod 'DrawCell' rutininde RowHeights []' ı ayarlar. Uglhh ... – NGLN

+1

@Mawg, kodu yazmamanız gereken bir örnektir (pek çok noktada) (NGLN'nin işaret ettiği şey hariç). Benim önerim, kullanmayın ... – TLama

İlgili konular