Firemonkey Grid Control - выравнивание столбца справа
Я использую элемент управления FireMonkey Grid, но у меня есть постоянная проблема при попытке выровнять столбец вправо. Из сообщений других пользователей мне удалось создать новый тип TColumn, применить стиль к нему (текст как HorzAlign=taTrailing) и теоретически - подумал, что это будет решением. Значения предоставляются функцией OnGetValue для элемента управления Grid.
Проблема, однако, заключается в том, что, хотя вначале все выглядит хорошо, если вы прокручиваете колесо / колесо мыши и т. Д., Новый столбец типа TColumn не отображается для правильного обновления с использованием метода / кода ниже. Это может быть ошибка / особенность Grid (или как я это делаю). Я пробовал.ReAlign и т.д...; но безрезультатно. Единственный способ вернуть сетку в соответствие - это, например, изменить размер столбца - что тогда правильно перерисовывается?
Приведенный ниже код показывает, что это простой TGrid с 2 столбцами, 1 со стандартным StringColumn и 1 моим новым StringColNum (без выравнивания по правому краю). - Любая помощь, оцениваемая как эта, является основным требованием любой работы по сетке.
unit Unit1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.Objects, FMX.Grid,
FMX.Layouts, FMX.Edit;
type
TForm1 = class(TForm)
Grid1: TGrid;
Button1: TButton;
StyleBook1: TStyleBook;
procedure Grid1GetValue(Sender: TObject; const Col, Row: Integer;
var Value: Variant);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TStringColNum = class(TStringColumn)
private
function CreateCellControl: TStyledControl; override;
public
constructor Create(AOwner: TComponent); override;
published
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
constructor TStringColNum.Create(AOwner: TComponent);
begin
inherited;
end;
function TStringColNum.CreateCellControl: TStyledControl;
var
t:TEdit;
begin
Result:=TStringColNum.Create(Self);
Result.StyleLookup := 'textrightalign';
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Grid1.AddObject(TStringColumn.Create(Self));
Grid1.AddObject(TStringColNum.Create(Self)); // Right Aligned column?
Grid1.RowCount:=5000;
Grid1.ShowScrollBars:=True;
end;
procedure TForm1.Grid1GetValue(Sender: TObject; const Col, Row: Integer;
var Value: Variant);
var
cell: TStyledControl;
t: TText;
begin
if Col=0 then
Value:='Row '+IntToStr(Row);;
if Col=1 then
begin
cell := Grid1.Columns[Col].CellControlByRow(Row);
if Assigned(cell) then
begin
t := (Cell.FindStyleResource('text') as TText);
if Assigned(t) then
t.Text:='Row '+IntToStr(Row);
end;
end;
end;
end.
С уважением. Ян.
6 ответов
Все это напоминает мне, что я до сих пор не написал в своем блоге об этом.
В любом случае, ячейка сетки может быть любым потомком TStyledControl (практически любого элемента управления). По умолчанию для текстовой ячейки используется TTextCell, который является просто TEdit. Быть TEdit означает, что изменить выравнивание очень просто: просто измените свойство TextAlign. Не нужно возиться со стилями (если вы действительно не хотите).
Ваш столбец должен создать ваши ячейки в методе CreateCellControl. Вы фактически создаете экземпляр своей колонки, которая является вашей главной проблемой.
Вам не нужен метод Create для вашего столбца (он ничего не делает), поэтому удалите его (если он вам не нужен для чего-то другого) и измените ваш CreateCellControl.
function TStringColNum.CreateCellControl: TStyledControl;
begin
Result:=inherited;
TTextCell(Result).TextAlign := taTrailing;
end;
Наконец, ваш обработчик события GetValue не должен делать ничего, кроме как возвращать значение:
procedure TForm1.Grid1GetValue(Sender: TObject; const Col, Row: Integer;
var Value: Variant);
begin
if Col=0 then
Value:='Row '+IntToStr(Row);
if Col=1 then
Value := 'Row '+IntToStr(Row);
end;
Я думаю, что это лень Embarcadero.
добавление / изменение 3 строк в FMX.Grid.pas решает эту проблему.
вместо модификации оригинального FMX.Grid pas, я рекомендую скопировать оригинальный FMX.Grid pas в ваш каталог Project, в том числе в вашем Project (добавить в Project) и добавить / изменить следующие строки.
TColumn = class(TStyledControl)
private const
HorzTextMargin = 2;
VertTextMargin = 1;
private
FReadOnly: Boolean;
FHorizontalAlign:TTextAlign;//Add this Line *********
FEditMode: Integer;
FApplyImmediately: boolean;
...
...
procedure UpdateCell(ARow: Integer);
published
property HorizontalAlign: TTextAlign read FHorizontalAlign write FHorizontalAlign;//add this line *******
property Align;
property ClipChildren default False;
procedure TColumn.DefaultDrawCell(const Canvas: TCanvas; const Bounds: TRectF; const Row: Integer;
const Value: TValue; const State: TGridDrawStates);
var
R: TRectF;
Layout: TTextLayout;
LocalRow: Integer;
begin
if FDrawable <> nil then
FDrawable.DrawCell(Canvas, Bounds, Row, Value, State)
else
...
...
Layout.Opacity := AbsoluteOpacity;
(*remark this line *****************
Layout.HorizontalAlign := Grid.TextSettingsControl.ResultingTextSettings.HorzAlign;
*)
Layout.HorizontalAlign := HorizontalAlign;//add this line *****
наконец, вы можете установить новое свойство в вашем проекте. например:
MyColumn.HorizontalAlign: = TTextAlign.taCenter;
Другое решение:
Grid1.ApplyStyleLookup();
MyCol1.DefaultTextSettings.HorzAlign:=TTextAlign.taCenter;
Решение "Suat DMK" работает нормально, вы должны recompile Fmx.Bind.DBLinks.pas and Fmx.Bind.Editors.pas
если вы собираетесь использовать ссылки на БД.
После этого вы просто помещаете событие OnPainting:
SGrid1.ColumnByIndex(1).HorizontalAlign := TTextAlign.Leading;
Нисходящие столбцы не очень хорошо работают с живыми привязками, так как администратор привязок создает столбцы, поэтому вам придется возиться с этим по убыванию. Ни элегантный, ни практичный, на мой взгляд.
Просто выровняйте ваши ячейки в событии OnPainting сетки.
I := Col;
for J := 0 to Grid1.RowCount - 1 do
begin
T := TTextCell(Grid1.Columns[I].Children[J]);
T.TextAlign := TTextAlign.taTrailing;
end;
Если вы используете livebindings, когда у вас меньше шансов настроить создаваемый класс столбца, но вы можете создать помощников для Column, который устанавливает некоторые атрибуты отдельных элементов управления ячейки. Не слишком элегантно, но просто и работает:
unit GridColumnHelper;
interface
uses
Fmx.Types, Fmx.Controls, Fmx.Grid, Fmx.Edit;
type
TGridColumnHelper = class helper for TColumn
public
procedure SetEditMaxLength(aValue: Integer);
procedure SetEditTextAlign(aValue: TTextAlign);
end;
implementation
{ TGridColumnHelper }
procedure TGridColumnHelper.SetEditMaxLength(aValue: Integer);
var
lControl: TStyledControl;
begin
for lControl in FCellControls do
begin
if lControl is TEdit then
(lControl as TEdit).MaxLength := aValue;
end;
end;
procedure TGridColumnHelper.SetEditTextAlign(aValue: TTextAlign);
var
lControl: TStyledControl;
begin
for lControl in FCellControls do
begin
if lControl is TEdit then
(lControl as TEdit).TextAlign := aValue;
end;
end;
end.
После того, как привязка заполнит сетку, вы можете вызвать помощников:
MyGrid.Columns[0].SetEditTextAlign(TTextAlign.taTrailing);
MyGrid.Columns[1].SetEditMaxLength(15);