Delphi:如何使TStringGrid中心的单元格文本对齐?

时间:2010-08-22 07:29:16

标签: delphi

看起来很明显。我希望文本位于单元格的中心,但由于某种原因,我无法在属性中找到它。我怎么能这样做?

2 个答案:

答案 0 :(得分:17)

在TStringGrid中没有将文本居中的属性,但您可以在DrawCell事件中执行此操作:

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
  S: string;
  SavedAlign: word;
begin
  if ACol = 1 then begin  // ACol is zero based
    S := StringGrid1.Cells[ACol, ARow]; // cell contents
    SavedAlign := SetTextAlign(StringGrid1.Canvas.Handle, TA_CENTER);
    StringGrid1.Canvas.TextRect(Rect,
      Rect.Left + (Rect.Right - Rect.Left) div 2, Rect.Top + 2, S);
    SetTextAlign(StringGrid1.Canvas.Handle, SavedAlign);
  end;
end;

我从here

发布的代码

<强>更新

在单元格中写入时将文本居中,将此代码添加到GetEditText事件:

procedure TForm1.StringGrid1GetEditText(Sender: TObject; ACol, ARow: Integer;
  var Value: string);
var
  S : String;
  I: Integer;
  IE : TInplaceEdit ;
begin
  for I := 0 to StringGrid1.ControlCount - 1 do
    if StringGrid1.Controls[i].ClassName = 'TInplaceEdit' then
    begin
      IE := TInplaceEdit(StringGrid1.Controls[i]);
      ie.Alignment := taCenter
    end;
end;

答案 1 :(得分:4)

这个是一个更好的解决方案,其他人和他们在程序TStringGrid.SetCellsAlignmentTStringGrid.SetCellsAlignment上的错误类型(-1 < Index)比较是正确的,但是thenelse部分被交换...正确的版本(这一个)将显示当index大于-1时它将覆盖存储的值,否则它将添加一个新条目,其他人将只执行相反的列出索引消息,谢谢你检测这样的消息。

我也能够成为另一个独立单位的所有人,所以在这里(现在希望它是正确的,并且感谢您检测出这样的错误):

unit AlignedTStringGrid;

interface

uses Windows,SysUtils,Classes,Grids;

type 
  TStringGrid=class(Grids.TStringGrid)
  private
    FCellsAlignment:TStringList;
    FColsDefaultAlignment:TStringList;
    function GetCellsAlignment(ACol,ARow:Integer):TAlignment;
    procedure SetCellsAlignment(ACol,ARow:Integer;const Alignment:TAlignment);
    function GetColsDefaultAlignment(ACol:Integer):TAlignment;
    procedure SetColsDefaultAlignment(ACol:Integer;const Alignment:TAlignment);
  protected
    procedure DrawCell(ACol,ARow:Longint;ARect:TRect;AState:TGridDrawState);override;
  public
    constructor Create(AOwner:TComponent);override;
    destructor Destroy;override;
    property CellsAlignment[ACol,ARow:Integer]:TAlignment read GetCellsAlignment write SetCellsAlignment;
    property ColsDefaultAlignment[ACol:Integer]:TAlignment read GetColsDefaultAlignment write SetColsDefaultAlignment;
  end;

implementation

constructor TStringGrid.Create(AOwner:TComponent);
begin
  inherited Create(AOwner);
  FCellsAlignment:=TStringList.Create;
  FCellsAlignment.CaseSensitive:=True;
  FCellsAlignment.Sorted:=True;
  FCellsAlignment.Duplicates:=dupIgnore;
  FColsDefaultAlignment:=TStringList.Create;
  FColsDefaultAlignment.CaseSensitive:=True;
  FColsDefaultAlignment.Sorted:=True;
  FColsDefaultAlignment.Duplicates:=dupIgnore;
end;

destructor TStringGrid.Destroy;
begin
  FCellsAlignment.Free;
  FColsDefaultAlignment.Free;
  inherited Destroy;
end;

procedure TStringGrid.SetCellsAlignment(ACol,ARow: Integer; const Alignment: TAlignment);
var
  Index:Integer;
begin
  if (-1 < Index) then begin
    FCellsAlignment.Objects[Index]:= TObject(Alignment);
  end else begin
    FCellsAlignment.AddObject(IntToStr(ACol) + '-' + IntToStr(ARow), TObject(Alignment));
  end;
end;

function TStringGrid.GetCellsAlignment(ACol,ARow: Integer): TAlignment;
var
  Index:Integer;
begin
  Index:= FCellsAlignment.IndexOf(IntToStr(ACol)+'-'+IntToStr(ARow));
  if (-1 < Index) then begin
    GetCellsAlignment:= TAlignment(FCellsAlignment.Objects[Index]);
  end else begin
    GetCellsAlignment:= ColsDefaultAlignment[ACol];
  end;
end;

procedure TStringGrid.SetColsDefaultAlignment(ACol: Integer; const Alignment: TAlignment);
var
  Index:Integer;
begin
  Index:= FColsDefaultAlignment.IndexOf(IntToStr(ACol));
  if (-1 < Index) then begin
    FColsDefaultAlignment.Objects[Index]:= TObject(Alignment);
  end else begin
    FColsDefaultAlignment.AddObject(IntToStr(ACol), TObject(Alignment));
  end;
end;

function TStringGrid.GetColsDefaultAlignment(ACol:Integer):TAlignment;
var
  Index:Integer;
begin
  Index:= FColsDefaultAlignment.IndexOf(IntToStr(ACol));
  if (-1 < Index) then begin
    GetColsDefaultAlignment:= TAlignment(FColsDefaultAlignment.Objects[Index]);
  end else begin
    GetColsDefaultAlignment:=taLeftJustify;
  end;
end;

procedure TStringGrid.DrawCell(ACol,ARow:Longint;ARect:TRect;AState:TGridDrawState);
var
  Old_DefaultDrawing:Boolean;
begin
  if DefaultDrawing then begin
    case CellsAlignment[ACol,ARow] of
      taLeftJustify: begin
        Canvas.TextRect(ARect,ARect.Left+2,ARect.Top+2,Cells[ACol,ARow]);
      end;
      taRightJustify: begin
        Canvas.TextRect(ARect,ARect.Right -2 -Canvas.TextWidth(Cells[ACol,ARow]), ARect.Top+2,Cells[ACol,ARow]);
      end;
      taCenter: begin
        Canvas.TextRect(ARect,(ARect.Left+ARect.Right-Canvas.TextWidth(Cells[ACol,ARow]))div 2,ARect.Top+2,Cells[ACol,ARow]);
      end;
    end;
  end;
  Old_DefaultDrawing:= DefaultDrawing;
  DefaultDrawing:=False;
  inherited DrawCell(ACol,ARow,ARect,AState);
  DefaultDrawing:= Old_DefaultDrawing;
end;

end.

这是一个整体,将其保存到名为AlignedTStringGrid.pas的文件中。

然后在任何表单上,您在接口使用子句的末尾添加TStringGrid ,AlignedTStringGrid

注意:对于行也可以这样做,但是现在我不知道如何混合两者(cols和rows)因为如何选择优先级,如果有人对它非常感兴趣,请告诉我。

P.D。:可以为TEdit做同样的想法,只需在stackoverflow.com上搜索TEdit.CreateParams或阅读帖子How to set textalignment in TEdit control