2012-02-12 24 views
6

Estoy usando el control FireMonkey Grid pero tengo un problema continuo al intentar alinear correctamente una columna. De las publicaciones de otros usuarios, he logrado crear un nuevo tipo TColumn, aplicar un estilo a esto (texto como HorzAlign = taTrailing) y, en teoría, pensé que esta sería la solución. Los valores son proporcionados por la función OnGetValue al control Grid.Firemonkey Grid Control - Alineación de una columna a la derecha

El problema es, sin embargo, que aunque al principio se ve bien, si desplaza la barra/mouse, etc., la nueva columna de tipo TColumn no parece actualizarse correctamente utilizando el método/código siguiente. Podría ser un error/característica de la Grilla (o la forma en que lo estoy haciendo). He intentado .ReAlign, etc ...; pero fue en vano. La única forma de volver a poner a la red en línea es hacer un cambio de tamaño de columna, por ejemplo, que luego se redibuja correctamente?

El siguiente código muestra que es un TGrid simple, con 2 cols, 1 StringColumn estándar y 1 mi nuevo StringColNum (alineación correcta de wuth). - Cualquier ayuda apreciada ya que este es un requisito básico de cualquier trabajo de cuadrícula.

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. 

Saludos cordiales. Ian.

Respuesta

5

Todo lo cual me recuerda que todavía no he escrito la entrada de mi blog sobre esto.

De todos modos, una celda de la cuadrícula puede ser cualquier descendiente de TStyledControl (básicamente cualquier control). El valor predeterminado para una celda de texto es TTextCell, que es simplemente un TEdit. Ser un TEdit significa cambiar la alineación es realmente fácil: simplemente cambie la propiedad TextAlign. No es necesario que te metas con los estilos (a menos que realmente quieras).

Su columna necesita crear sus celdas en el método CreateCellControl. En realidad, estás creando una instancia de tu columna, que es tu principal problema.

No necesita el método Create para su columna (no está haciendo nada), entonces bórrelo (a menos que lo necesite para otra cosa) y modifique su CreateCellControl.

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

Por último, sus necesidades de control de eventos GetValue no hacen más que devolver el valor:

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

Gracias Mike - La "respuesta perfecta" que estaba buscando; una verdadera superestrella ..! – Ian

0

descendente columnas no funciona bien con LiveBindings como el bindmanager crea las columnas por lo que tiene que meterse con descendente ese. Ni elegante ni práctico en mi opinión.

Simplemente alinee sus celdas en la cuadrícula OnPainting event.

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

Si LiveBindings utilizar cuando se tiene menos posibilidades de personalizar la clase columna que se está creando, pero puede crear ayudantes para la columna, que establece algunos atributos de controles de células individuales. No demasiado elegante, pero simple y funciona:

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. 

Después de la unión ha llenado la cuadrícula, puede llamar a los ayudantes:

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

Creo que es una pereza del embarcadero.

añadiendo/modificando 3 líneas en FMX.Grid.pas resuelve este problema.

en lugar de modificar el FMX original.Grid pas, recomiendo copiar el pasaje FMX.Grid original a su directorio de proyecto, incluso en su proyecto (agregar al proyecto) y agregar/modificar las siguientes líneas.

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

Finalmente, puede definir la nueva propiedad en su proyecto. por ejemplo:

MyColumn.HorizontalAlign: = TTextAlign.taCenter;

0

La solución de "suat dmk" está funcionando bien usted tiene que recompile Fmx.Bind.DBLinks.pas and Fmx.Bind.Editors.pas si va a utilizar enlaces DB.

Después de eso, sólo tiene que poner en OnPainting evento:

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