2012-02-13 35 views
7

Estoy buscando la solución recomendada para diseñar una celda TGrid que se dibuja mediante la llamada OnGetValue (llamada a pintar las celdas a la vista)) Para el fondo, una excelente respuesta de Mike, mostró cómo simplemente aplicar una propiedad tALIGN cuando se crea la celda; pero mi próximo desafío es colorear los contenidos de la celda.Firemonkey Grid Control - Estilo de una celda basado en un valor (a través de la llamada a función OnGetValue)

Previous posting/answer

El objetivo es cambiar los atributos de celda (fuente, estilo, color, etc ...) del valor que voy a volver como la célula "Valor". En el ejemplo de abajo; sería aplicar un estilo al "valor" de OnGetValue que se está devolviendo. Es muy posible que tengamos que hacer esto a través de una hoja de estilo FM; o podemos acceder directamente a los atributos TText? Lo ideal es que ambos escenarios serían grandes - pero en esta etapa que adoptarán una solución ... (; -..>

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; 
    published 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.fmx} 

function TStringColNum.CreateCellControl: TStyledControl; 
begin 
    Result:=TTextCell.Create(Self); 
    TTextCell(Result).TextAlign := TTextAlign.taTrailing; 
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); 
begin 
    if Col=0 then 
    Value:='Row '+IntToStr(Row); 

    if Col=1 then 
    Value := 'Row '+IntToStr(Row); 

// Apply style based on value ? 

end; 

end. 

Muchas gracias de antemano, Ian

+0

¿Puede definir 'basado en un valor'? ¿Quiere decir, por ejemplo, que si el valor es negativo, la fuente será roja, etc.? –

+0

Hola Mike - Sí; lugar perfecto. Tengo dos escenarios, pero ambos son el mismo principio. Un escenario es que el valor negativo se muestra en ROJO y el otro es "poner en negrita" un elemento en la lista (que elijo, debido a detalles fuera de la cuadrícula, cliente importante, etc.). Gracias por adelantado. Ian. – Ian

Respuesta

5

En primer lugar, una disculpa En mi . respuesta a su última pregunta, CreateCellControl debería haber llamado heredaron para crear la célula que he modificado mi respuesta

en cuanto a esta pregunta, he subido a mi entrada de blog sobre las células FireMonkey -. http://monkeystyler.com/blog/entry/firemonkey-grid-basics-custom-cells-and-columns - que cubre las cosas de la respuesta anterior, y también cubre la creación de controles de celda personalizados. Tendrás que leer eso antes de que proce ed. Esperaré.

...

Volver atrás? Bueno.

Siguiendo con el ejemplo en la publicación del blog.

Excepto que he actualizado TFinancialCell para que herede directamente de TTextCell (que por supuesto es un TEdit), lo que tiene mucho más sentido y es mucho más simple de estilo.

Por lo tanto, actualizar la TFinancialCell:

type TFinancialCell = class(TTextCell) 
    private 
    FIsNegative: Boolean; 
    FIsImportant: Boolean; 
    protected 
    procedure SetData(const Value: Variant); override; 
    procedure ApplyStyle;override; 
    procedure ApplyStyling; 
    public 
    constructor Create(AOwner: TComponent); override; 
    published 
    property IsNegative: Boolean read FIsNegative; 
    property IsImportant: Boolean read FIsImportant; 
    end; 

Código de lo anterior:

procedure TFinancialCell.ApplyStyle; 
var T: TFMXObject; 
begin 
    inherited; 
    ApplyStyling; 
end; 

procedure TFinancialCell.ApplyStyling; 
begin 
    if IsNegative then 
    FontFill.Color := claRed 
    else 
    FontFill.Color := claBlack; 
    Font.Style := [TFontStyle.fsItalic]; 
    if IsImportant then 
    Font.Style := [TFontStyle.fsBold] 
    else 
    Font.Style := []; 
    if Assigned(Font.OnChanged) then 
    Font.OnChanged(Font); 
    Repaint; 
end; 

constructor TFinancialCell.Create(AOwner: TComponent); 
begin 
    inherited; 
    TextAlign := TTextAlign.taTrailing; 
end; 

procedure TFinancialCell.SetData(const Value: Variant); 
var F: Single; 
    O: TFMXObject; 
    S: String; 
begin 
    S := Value; 
    FIsImportant := S[1] = '#'; 
    if IsImportant then 
    S := Copy(Value,2,MaxInt) 
    else 
    S := Value; 

    F := StrToFloat(S); 
    inherited SetData(Format('%m', [F])); 
    FIsNegative := F < 0; 
    ApplyStyling; 
end; 

Y, por último, actualizar el controlador de eventos GetValue:

procedure TForm1.Grid1GetValue(Sender: TObject; const Col, Row: Integer; 
    var Value: Variant); 
var Cell: TStyledControl; 
begin 
    if Col = 0 then 
    Value := Row 
    else if Col = 1 then 
    begin 
    Value := FloatToStr(Data[Row]); 
    if Value > 30 then 
     Value := '#'+Value; 
    end; 
end; 
+0

Hola Mike - gracias de nuevo por el ejemplo; usted es de hecho el "gurú TGrid". La publicación de blog/publicación de la placa es excelente y muy bien presentada. He logrado seguir tu ejemplo revisado/editado y obtener el trabajo en negrita y rojo. - Muchas gracias de nuevo; un verdadero caballero ...! Ian. (PD.¿Hay alguna manera de alinear a la derecha el encabezado de la columna utilizando la misma metodología para las columnas TFinancial??) – Ian

+0

Hola Mike: ¿un pequeño problema que anoté en relación con lo anterior? Todo se ve bien hasta que me desplazo por la ventana. Cuando se desplaza, las líneas rojas/negras se salen de línea/sincronización. No estoy seguro de que sea un problema de repintado con FM u otra cosa. Puedo publicar mi código si el tuyo está bien? - Thx por adelantado, Ian. – Ian

+0

Mi mal. El estilo debe volver a aplicarse desde el método SetData, por lo que he actualizado el código anterior para extraer un método ApplyStyles y llamarlo desde ApplyStyle, SetData y SetIsImportant. –

1

Código anterior está muy bien para versiones anteriores a XE4, pero para XE4 y XE5 no funciona. El color y el estilo del texto no se modifican.

Este es un código fijo para XE4 y XE5:

procedure TFinancialCell.ApplyStyling; 
begin 
    StyledSettings := [TStyledSetting.ssFamily, TStyledSetting.ssSize]; 
    if IsNegative then 
    FontColor := claRed 
    else 
    FontColor := claBlack; 
    Font.Style := [TFontStyle.fsItalic]; 
    if IsImportant then 
    Font.Style := [TFontStyle.fsBold] 
    else 
    Font.Style := []; 
    if Assigned(Font.OnChanged) then 
    Font.OnChanged(Font); 
    Repaint; 
end; 
Cuestiones relacionadas