2012-02-12 3 views
6

Я использую элемент управления сеткой FireMonkey, но у меня есть постоянная проблема при попытке выравнивания столбца справа. Из сообщений других пользователей мне удалось создать новый тип TColumn, применить к нему стиль (текст HorzAlign = taTrailing), а в теории - подумал, что это будет решение. Значения предоставляются функцией OnGetValue для управления сеткой.Управление сеткой Firemonkey - выравнивание столбца вправо

Проблема заключается в том, что, хотя сначала это выглядит нормально, если вы прокручиваете колесико/мышь и т. Д. Новый столбец типа 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. 

С уважением. Ян.

ответ

5

Все это напоминает мне о том, что я до сих пор не написал свое сообщение в блоге об этом.

В любом случае ячейкой сетки может быть любой потомок TStyledControl (в основном любой элемент управления). По умолчанию для текстовой ячейки является TTextCell, который является просто TEdit. Быть TEdit означает, что изменение выравнивания очень просто: просто измените свойство TextAlign. Не нужно возиться со стилями (если вы этого не хотите).

В вашей колонке необходимо создать свои ячейки в методе CreateCellControl. Фактически вы создаете экземпляр своего столбца, который является вашей основной проблемой.

Вам не нужен метод Create для вашего столбца (он ничего не делает), поэтому удалите его (если вам не нужно что-то еще) и внесите изменения в CreateCellControl.

function TStringColNum.CreateCellControl: TStyledControl; 
begin 
    Result:=inherited; 
    TTextCell(Result).TextAlign := taTrailing; 
end; 

Наконец, ваши потребности обработчик события ПолучитьЗначение ничего не делать больше, чем возвращать значение:

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; 
+2

Благодаря Mike - "идеальный ответ" Я искал; настоящая суперзвезда ..! – Ian

0

нисходящее колонки не очень хорошо работает с LiveBindings как bindmanager создает столбцы, так что вы должны связываться с нисходящим что. На мой взгляд, ни элегантный, ни практический.

Просто выровняйте свои ячейки в сетке события OnPainting.

I := Col; 
for J := 0 to Grid1.RowCount - 1 do 
begin 
    T := TTextCell(Grid1.Columns[I].Children[J]); 
    T.TextAlign := TTextAlign.taTrailing; 
end; 
0

Если вы используете 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); 
0

Я думаю, что это леность Embarcadero.

добавление/изменение 3 строк в FMX.Grid.pas решает эту проблему.

вместо модификации оригинального FMX.Grid pas, я рекомендую скопировать исходный файл FMX.Grid в каталог 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;

0

Решение "suat dmk" работает нормально, вы должны recompile Fmx.Bind.DBLinks.pas and Fmx.Bind.Editors.pas, если вы собираетесь использовать ссылки DB.

После этого, вы просто положить в OnPainting событие:

SGrid1.ColumnByIndex(1).HorizontalAlign := TTextAlign.Leading; 
Смежные вопросы