Delphi: Как сделать тексты ячеек в центре TStringGrid выровненными?

Кажется, что-то очевидно. Я хочу, чтобы тексты находились в центре ячеек, но по какой-то причине я не могу найти их в свойствах. Как я могу это сделать?

Ответ 1

Нет никакого свойства, чтобы центрировать текст в 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;

Код, который я отправил из здесь

UPDATE:

чтобы центрировать текст во время записи в ячейке, добавьте этот код в 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;

Ответ 2

Обратите внимание. Поскольку я не могу удалять сообщения (если администратор может удалять их, удалите их и удалите этот абзац), я пытаюсь их отредактировать, чтобы разрешить только этот. Это гораздо лучшее решение, которое у других и на них было ошибкой при процедурах TStringGrid.SetCellsAlignment и TStringGrid.SetCellsAlignment сравнение -1<Index было правильным, но then и else части были заменены... Правильный версия (эта) покажет, что, когда индекс больше -1, он перезапишет сохраненное значение, иначе он добавит новую запись, остальные будут делать только oposite, выводя список из индексного сообщения, спасибо за обнаружение такого.

Я также могу быть в другом разделенном блоке, так что вот он (надеюсь, теперь это правильно и спасибо за обнаружение таких ошибок):

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 add ,AlignedTStringGrid в конце раздела использования интерфейса.

Примечание. То же самое можно сделать для строк, но пока я не знаю, как смешивать оба (cols и rows) из-за того, как выбрать приоритет, если кто-то очень заинтересован в этом, дайте мне знать.

PD: та же идея может быть сделана для TEdit, просто выполните поиск на stackoverflow.com для TEdit.CreateParams или прочитайте сообщение Как установить выравнивание текста в элементе управления TEdit

Ответ 3

В Delphi я делаю это, перегружая тип TEdit следующим образом:

В разделе интерфейса перед объявлением TForm я поставлю:

type TStringGrid=class(Grids.TStringGrid)
   private
     FCellsAlignment:TStringList;
     function GetCellsAlignment(ACol,ARow:Integer):TAlignment;
     procedure SetCellsAlignment(ACol,ARow: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;
 end;

В разделе реализации я поставлю реализацию для таких:

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

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

procedure TStringGrid.SetCellsAlignment(ACol,ARow:Integer;const Alignment:TAlignment);
begin
     FCellsAlignment.AddObject(IntToStr(ACol)+'-'+IntToStr(ARow),TObject(Alignment));
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:=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;

Затем, чтобы установить выравнивание ячейки, я поставлю что-то вроде этого:

CellsAlignment[TheCellCol,TheCellRow]:=taLeftJustify;
CellsAlignment[TheCellCol,TheCellRow]:=taCenter;
CellsAlignment[TheCellCol,TheCellRow]:=taRightJustify;

Вот и все.

Pelase отмечает, что его можно значительно улучшить, это просто доказательство его добавления в TStingGrid, это не о создании нового класса (с другим именем), ни о создании нового компонента.

Надеюсь, это может быть полезно кому-то.

PD: та же идея может быть сделана для TEdit, просто выполните поиск в stackoverflow.com для TEdit.CreateParams или прочитайте сообщение Как установить выравнивание текста в элементе управления TEdit

Ответ 4

В Lazarus вы можете создать его из Object Inspector. Найдите столбцы свойств в TStringGrid, которые вы создали, и добавьте несколько элементов. Затем разверните свой TStringGrid в Обозревателе объектов, выберите сетку, которую вы хотите выровнять, и измените ее свойство Alignment.