Как вы можете изменить ориентацию текста в ячейках в фиксированных строках в Delphi TStringGrid

У меня есть стандартный TStringGrid на форме. У меня есть одна фиксированная строка в сетке, которая содержит несколько столбцов, которые все являются объектами TGridColumns. Я установил заголовки столбцов с помощью инспектора объектов, а ориентация по умолчанию — горизонтальная. Есть ли способ сделать ориентацию вертикальной (как в ячейках Excel)?


person user1174918    schedule 05.02.2012    source источник
comment
Здравствуйте, вы имели в виду что-то вроде this ? В любом случае, какую версию Delphi вы используете? У меня D2009 и у меня там нет класса TGridColumns.   -  person TLama    schedule 05.02.2012
comment
@TLama, коллекция TGridColumns - это класс FCL, в VCL аналогичный класс был введен позже для TDBGrid. ОП, уточните, пожалуйста, часть Excel.   -  person OnTheFly    schedule 06.02.2012
comment
lazarus-ccr.sourceforge.net/docs/lcl/grids/tgridcolumns. html   -  person OnTheFly    schedule 06.02.2012
comment
@TLama, я думаю, не будет проблем с рисованием этих ячеек заголовка просто в событии OnDrawCell (помимо вычислений прямоугольника, что довольно специально для повернутого шрифта) i.imgur.com/m9Ja0.png   -  person OnTheFly    schedule 06.02.2012
comment
@TLama, а, я понял! Да уж, заново изобретать живопись (в том числе и тематическую) нецелесообразно.   -  person OnTheFly    schedule 06.02.2012
comment
Проверьте первую часть моего ответа; если этот пост помог вам, не забудьте принять его. И, пожалуйста, очистите ваши комментарии отсюда. Я уже удалил свой, поэтому разговор здесь стал бессмысленным :) Спасибо   -  person TLama    schedule 13.02.2012


Ответы (1)


Вот как отобразить текст первой строки вертикально в Lazarus:

unit Unit1; 

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Grids,
  StdCtrls;

type
  TStringGrid = class(Grids.TStringGrid)
  protected
    procedure DrawCellText(ACol, ARow: Integer; ARect: TRect;
      AState: TGridDrawState; AText: String); override;
  end;

type
  TForm1 = class(TForm)
    Button1: TButton;
    StringGrid1: TStringGrid;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end; 

var
  Form1: TForm1; 

implementation

{$R *.lfm}

procedure TStringGrid.DrawCellText(ACol, ARow: Integer; ARect: TRect;
  AState: TGridDrawState; AText: String);
var
  TextPosition: TPoint;
begin
  if ARow = 0 then
  begin
    Canvas.Font.Orientation := 900;
    TextPosition.X := ARect.Left +
      ((ARect.Right - ARect.Left - Canvas.TextHeight(AText)) div 2);
    TextPosition.Y := ARect.Bottom -
      ((ARect.Bottom - ARect.Top - Canvas.TextWidth(AText)) div 2);
    Canvas.TextOut(TextPosition.X, TextPosition.Y, AText);
  end
  else
    inherited DrawCellText(ACol, ARow, ARect, AState, AText);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
  GridColumn: TGridColumn;
begin
  for I := 0 to 4 do
  begin
    GridColumn := StringGrid1.Columns.Add;
    GridColumn.Width := 24;
    GridColumn.Title.Font.Orientation := 900;
    GridColumn.Title.Layout := tlBottom;
    GridColumn.Title.Caption := 'Column no. ' + IntToStr(I);
  end;
  StringGrid1.RowHeights[0] := 80;
end;

end.

Вот как отобразить текст первой строки TStringGrid вертикально в Delphi:

Я бы предпочел использовать переопределенную процедуру DrawCell, поскольку она кажется меня как самый простой способ, потому что, если вы хотите отобразить текст просто в OnDrawCell событие, то вы должны рассмотреть:

  • если для параметра DefaultDrawing задано значение True, то текст уже будет отображаться, когда OnDrawCell запускается событие, поэтому здесь я бы рекомендовал, например хранить заголовки ячеек в отдельной переменной, а не в Cells свойство, поэтому текст не будет отображаться, и вы можете рисовать свои собственные сохраненные подписи вертикально
  • если для параметра DefaultDrawing задано значение False, тогда вам придется рисовать всю ячейку самостоятельно, включая трехмерную границу, что ИМХО, это не так уж круто, и лично я бы предпочел, чтобы элемент управления рисовал для нас фон

Вот код Delphi, в котором используется переопределенная процедура DrawCell. Текст центрируется внутри прямоугольника ячейки; обратите внимание, что я не использовал DrawTextEx< /a> для измерения размера текста, поскольку эта функция не учитывает измененную ориентацию шрифта.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Grids;

type
  TStringGrid = class(Grids.TStringGrid)
  protected
    procedure DrawCell(ACol, ARow: Longint; ARect: TRect;
      AState: TGridDrawState); override;
  end;

type
  TForm1 = class(TForm)
    Button1: TButton;
    StringGrid1: TStringGrid;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TStringGrid.DrawCell(ACol, ARow: Longint; ARect: TRect;
  AState: TGridDrawState);
var
  LogFont: TLogFont;
  TextPosition: TPoint;
  NewFontHandle: HFONT;
  OldFontHandle: HFONT;
begin
  if ARow = 0 then
  begin
    GetObject(Canvas.Font.Handle, SizeOf(LogFont), @LogFont);
    LogFont.lfEscapement := 900;
    LogFont.lfOrientation := LogFont.lfEscapement;
    NewFontHandle := CreateFontIndirect(LogFont);
    OldFontHandle := SelectObject(Canvas.Handle, NewFontHandle);
    TextPosition.X := ARect.Left +
      ((ARect.Right - ARect.Left - Canvas.TextHeight(Cells[ACol, ARow])) div 2);
    TextPosition.Y := ARect.Bottom -
      ((ARect.Bottom - ARect.Top - Canvas.TextWidth(Cells[ACol, ARow])) div 2);
    Canvas.TextRect(ARect, TextPosition.X, TextPosition.Y, Cells[ACol, ARow]);
    NewFontHandle := SelectObject(Canvas.Handle, OldFontHandle);
    DeleteObject(NewFontHandle);
  end
  else
    inherited DrawCell(ACol, ARow, ARect, AState);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to StringGrid1.ColCount - 1 do
  begin
    StringGrid1.ColWidths[I] := 24;
    StringGrid1.Cells[I, 0] := 'Column no. ' + IntToStr(I);
  end;
  StringGrid1.RowHeights[0] := 80;
end;

end.

И вот как это выглядит:

введите здесь описание изображения

person TLama    schedule 06.02.2012