2012-02-12 54 views
6

我正在使用FireMonkey網格控件,但在嘗試右對齊列時存在持續的問題。從其他用戶的貼子,我已經成功地創建一個新的TColumn類型,樣式應用於此(文本爲HorzAlign = taTrailing),並在理論 - 認爲這將是解決方案。這些值由OnGetValue函數提供給Grid控件。Firemonkey網格控件 - 將列對齊到右邊

然而,問題是,儘管起初它看起來不錯,如果你滾動欄/鼠標滾輪等新的TColumn類型列不會出現使用下面的方法/代碼正確刷新。它可能是網格的一個bug /功能(或者我正在做這件事的方式)。我嘗試過.ReAlign等等。但無濟於事。讓電網回線的唯一方法是做一個調整列 - 例如,然後重新繪製正確?

下面的代碼顯示它是一個簡單的TGrid,帶有2個cols,1個標準StringColumn和1個新的StringColNum(應用了wuth右對齊)。 - 任何幫助讚賞,因爲這是任何電網工作的基本要求。

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方法來創建你的細胞。你實際上正在創建一個你的列的實例,這是你的主要問題。

你不需要爲你的列創建方法(它什麼都不做),所以刪除它(除非你需要它)和修改你的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; 
+2

感謝邁克 - 「完美的答案」我一直在尋找;一個真正的超級明星..! – Ian 2012-02-12 21:15:56

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當你有更少的定製爲其創建列類的機會,但您可以創建爲列其中規定單個細胞控制的一些屬性幫手。不要太優雅,但簡單的工作原理:

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公司的懶惰。

在FMX.Grid.pas中添加/修改3行解決了這個問題。

,而不是原來的modifiying FMX。Grid pas,我建議將原始FMX.Grid pas複製到您的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.Horizo​​ntalAlign:= TTextAlign.taCenter;

0

「suat dmk」的解決方案工作正常,您必須recompile Fmx.Bind.DBLinks.pas and Fmx.Bind.Editors.pas,如果您要使用數據庫鏈接。

之後,你只是把OnPainting事件:

SGrid1.ColumnByIndex(1).HorizontalAlign := TTextAlign.Leading;