2011. június 8., szerda

Merge cells in a TStringGrid


Is it possible to create an OnDrawCell event to draw the cell text in a way that it looks like in Excel? For example, I don't want to truncate the text if the right adjacent cell is empty.


You can do that but it is not quite as easy as it may look at first glance. The problem you may run into is that something may invalidate the right adjacent cell in your scenario but not the cell holding the text. So the OnDrawCell event would only fire for the empty cell, not for the one holding the text. So some work has to be done to make sure the cell holding the text is invalidated as well when one of the adjacent cells is invalidated.

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
  i, x, y: Integer;
  if gdFixed in State then
  if ARow > 1 then
  {Draw row 1 with text from cell 1,1 spanning all cells in the row}
  with sender as TStringGrid do
    {Extend rect to include grid line on right, if not last cell in row}
    if aCol < Pred(ColCount) then
      Rect.Right := Rect.Right + GridlineWidth;
    {Figure out where the text of the first cell would start relative to the
                        current cells rect}
    y := Rect.Top + 2;
    x := Rect.Left + 2;
    for i := 1 to aCol - 1 do
      x := x - ColWidths[i] - GridlineWidth;
    {Paint cell pale yellow}
    Canvas.Brush.Color := $7FFFFF;
    Canvas.Brush.Style := bsSolid;
    {Paint text of cell 1,1 clipped to current cell}
    Canvas.TextRect(Rect, x, y, Cells[1, 1]);

procedure TForm1.FormCreate(Sender: TObject);
  i, k: Integer;
  with StringGrid1 do
    cells[1, 1] := 'A rather long line which will span cells';
    for i := 1 to colcount - 1 do
      for k := 2 to rowcount - 1 do
        cells[i, k] := Format('Cell[%d, %d]', [i, k]);

Nincsenek megjegyzések:

Megjegyzés küldése