Display multiple lines in a single cell of a TStringGrid (Views: 28)
Problem/Question/Abstract: How to display multiple lines in a single cell of a TStringGrid Answer: Solve 1: It is fairly easy to draw such text in an OnDrawCell handler. However the standard inplace editor of a grid is not well prepared to handle cells higher than one line. procedure TForm1.StringGrid1DrawCell(Sender: TObject; Col, Row: Integer; Rect: TRect; State: TGridDrawState); var S: string; drawrect: TRect; begin S := (Sender as TStringGrid).Cells[Col, Row]; if Length(S) > 0 then begin drawrect := rect; DrawText((Sender as TStringGrid).canvas.handle, Pchar(S), Length(S), drawrect, DT_CALCRECT or DT_WORDBREAK or DT_LEFT); if (drawrect.bottom - drawrect.top) > (Sender as TStringGrid).RowHeights[row] then (Sender as TStringGrid).RowHeights[row] := (drawrect.bottom - drawrect.top) else begin drawrect.Right := rect.right; (Sender as TStringGrid).canvas.fillrect(drawrect); DrawText((Sender as TStringGrid).canvas.handle, Pchar(S), Length(S), drawrect, DT_WORDBREAK or DT_LEFT); end; end; end; It will automatically adjust the row height to larger values if needed. The main problem is that it will not automatically decrease the row height if the text would fit into a smaller row. It cannot do that since there may be other cells in the row that need a taller row. You could fix that problem by setting the rowheigh back to the defaultrowheight when you change the cell data for a row, that would trigger a redraw and that in turn would adjust the rowheight to what is needed. It would cause some flicker, though. Solve 2: This is a unit that enables word-wrap in a cell of a TStringGrid: unit Unit1; interface uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, Grids; type TForm1 = class(TForm) StringGrid1: TStringGrid; Panel1: TPanel; procedure StringGrid1DrawCell(Sender: TObject; Col, Row: Longint; Rect: TRect; State: TGridDrawState); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.StringGrid1DrawCell(Sender: TObject; Col, Row: Longint; Rect: TRect; State: TGridDrawState); var A: array[0..255] of char; drawrect: TRect; begin StrPCopy(A, (Sender as TStringgrid).Cells[Col, Row]); if StrLen(A) > 0 then with (Sender as TStringgrid) do begin drawrect := rect; {Note that the first DrawText uses the DT_CALCRECT flag to calculate a new value for drawrect. This value is used to set the RowHeights parameter if necessary.} DrawText(canvas.handle, A, -1, drawrect, DT_CALCRECT or DT_WORDBREAK or DT_LEFT); if (drawrect.bottom - drawrect.top) > RowHeights[Row] then RowHeights[row] := (drawrect.bottom - drawrect.top) else begin drawrect.right := rect.right; canvas.fillrect(drawrect); DrawText(canvas.handle, A, -1, drawrect, DT_WORDBREAK or DT_LEFT); end; end; end; end. |