2012-02-12 12 views
6

Używam kontrolki Grid FireMonkey, ale mam problem z próbą wyrównania kolumny. Od innych użytkowników postów, udało mi się stworzyć nowy typ TColumn, zastosować do tego styl (tekst jako HorzAlign = taTrailing) i teoretycznie - myślałem, że to będzie rozwiązanie. Wartości są dostarczane przez funkcję OnGetValue do kontrolki Grid.Sterowanie siatką Firemonkey - wyrównanie kolumny w prawo

Problem polega jednak na tym, że chociaż początkowo wygląda to dobrze, jeśli przewijasz pasek/kółko myszy itp. Nowa kolumna typu kolumny nie wygląda na prawidłowo odświeżającą, używając poniższej metody/kodu. Może to być błąd/funkcja siatki (lub sposób, w jaki to robię). Próbowałem .ReAlign etc ...; ale bez skutku. Jedynym sposobem na przywrócenie siatki jest zmiana rozmiaru kolumny na przykład - która następnie jest poprawnie przerysowana?

Poniższy kod pokazuje, że jest to prosty TGrid, z 2 colami, 1 standardową kolumną StringColumn i 1 moją nową wartością StringColNum (zastosowane prawe wyrównanie wuth). - Każda pomoc doceniona, ponieważ jest to podstawowy wymóg jakiejkolwiek pracy w sieci.

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. 

Z pozdrowieniami. Ian.

Odpowiedz

5

Wszystko to przypomina mi, że nadal nie napisałem o tym wpisie na blogu.

W każdym razie, komórka siatki może być dowolnym potomkiem TStyledControl (w zasadzie każda kontrola). Domyślną komórką tekstową jest TTextCell, czyli po prostu TEdit. Bycie TEditem oznacza, że ​​zmiana wyrównania jest naprawdę łatwa: wystarczy zmienić właściwość TextAlign. Nie musisz robić bałaganu ze stylami (chyba, że ​​naprawdę chcesz).

Twoja kolumna musi utworzyć komórki w metodzie CreateCellControl. W rzeczywistości tworzysz instancję kolumny, która jest Twoim głównym problemem.

Nie potrzebujesz metody Create dla swojej kolumny (nic nie robi), więc usuń ją (chyba, że ​​potrzebujesz jej do czegoś innego) i zmień CreateCellControl.

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

Wreszcie twoi getValue potrzeby obsługi zdarzeń nie robić nic więcej niż zwróci wartość:

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

Dzięki Mike - The "doskonała odpowiedź" Szukałem; prawdziwa supergwiazda ..! – Ian

0

malejący kolumn nie działa dobrze z livebindings jak bindmanager tworzy kolumny więc trzeba zadzierać z malejącej że. Ani elegancka, ani praktyczna w mojej opinii.

Wystarczy wyrównać komórki w zdarzeniu OnPainting siatki.

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

Jeśli używasz livebindings gdy masz mniejsze szanse, aby dostosować klasę kolumny, który jest tworzony, ale można utworzyć pomocników dla kolumny, która wyznacza pewne atrybuty poszczególnych kontroli komórkowych. Niezbyt eleganckie, ale proste i działa:

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. 

po związaniu wypełnił siatkę można nazwać pomocników:

MyGrid.Columns[0].SetEditTextAlign(TTextAlign.taTrailing); 
MyGrid.Columns[1].SetEditMaxLength(15); 
0

myślę, że jest to lenistwo Embarcadero.

dodanie/modyfikacja 3 linii w FMX.Grid.pas rozwiązuje ten problem.

zamiast modyfikować oryginalny FMX.Grid pas, polecam kopiowanie oryginalnego pasma FMX.Grid do katalogu projektu, w tym do twojego projektu (dodaj do projektu) i dodawania/modyfikowania kolejnych linii.

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 ***** 

wreszcie można ustawić nową właściwość w projekcie. np .:

MyColumn.HorizontalAlign: = TTextAlign.taCenter;

0

Rozwiązanie "suat dmk" działa dobrze, musisz mieć recompile Fmx.Bind.DBLinks.pas and Fmx.Bind.Editors.pas, jeśli chcesz korzystać z łączy DB.

Po tym, po prostu umieścić w OnPainting imprezy:

SGrid1.ColumnByIndex(1).HorizontalAlign := TTextAlign.Leading; 
Powiązane problemy