Firemonkey Griglia di Controllo – Styling di una Cella in base al valore (via OnGetValue chiamata di funzione)

Sto cercando la soluzione consigliata per uno stile TGrid cella che è disegnato dallo OnGetValue chiamata (che è chiamato a dipingere le cellule in vista). Per lo sfondo, un’ottima risposta da parte di Mike, ha mostrato come applicare semplicemente un tAlign proprietà, quando la cella è creato; ma la mia prossima sfida è la colorazione del contenuto della cella.

Precedente intervento/risposta

L’obiettivo è quello di modificare gli attributi di cella (tipo di Carattere, stile, colore, etc…) del valore che sto per tornare, come la cella “Valore”. Nell’esempio riportato di seguito; sarebbe applicare uno stile al OnGetValue “valore” che viene restituito. Può ben essere che ci sono a fare questo attraverso un FM foglio di stile; oppure possiamo accedere direttamente alla TText attributi? Idealmente, entrambi gli scenari sarebbe bello – ma in questa fase mi prenderò entrambe le soluzioni… (;->

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.

Molte grazie in anticipo,
Ian.

  • Si può definire il ‘basato su un valore’? Intendi dire che, se il valore è negativo, il font sarà rosso, ecc?
  • Ciao Mike – Sì; a posto. Ho due scenari, ma entrambi sono lo stesso principio. Uno scenario è negativo il valore è visualizzato in ROSSO e l’altro scenario è quello di “bold” di un elemento nella lista (che ho scelto – a causa di off grid tenuto dettagli; importante cliente, ecc…). Grazie in anticipo. Ian.
InformationsquelleAutor Ian | 2012-02-13



2 Replies
  1. 5

    In primo luogo, un messaggio di scuse. Nella mia risposta alla tua ultima domanda, CreateCellControl dovrebbe avere chiamato ereditato per creare la cella. Ho modificato la mia risposta.

    Come per questa domanda, ho caricato il mio blog su FireMonkey Cellule – http://monkeystyler.com/blog/entry/firemonkey-grid-basics-custom-cells-and-columns – copre la roba dalla risposta precedente, e comprende anche la creazione di custom controlli cellulari. Avrete bisogno di leggere che prima di procedere. Ti aspetto.

    Indietro ora? Bene.

    Seguito l’esempio nel post del blog.

    Salvo, che ho aggiornato il TFinancialCell di ereditare direttamente da TTextCell (che ovviamente è un TEdit), il che rende molto più senso ed è molto più semplice di stile.

    Quindi, aggiornare il 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;

    Codice di cui sopra:

    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;

    E, infine, aggiornare il GetValue gestore di evento:

    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;
    • Ciao Mike grazie ancora per l’esempio; si sono, infatti, il “TGrid guru”. Il post del blog/board post sono ottimi e molto ben presentato. Sono riuscito a seguire la tua revisione/a cura di esempio e di ottenere il grassetto e in rosso funziona bene. – Grazie di nuovo, un vero gent…! Ian. (PS. C’è un modo per allineare a destra dell’intestazione di colonna e utilizzando la stessa metodologia per il TFinancial colonne..?)
    • Ciao Mike – un piccolo problema che ho notato in relazione a quanto sopra? Sembra tutto bene fino a quando ho scorrere la finestra. Quando si scorre, rosso/grassetto andare fuori linea/sync. Io non sono sicuro di si tratta di un ridisegno problema con FM o qualcos’altro? Posso postare il mio codice se la tua è a posto? Thx in anticipo, Ian.
    • Il mio male. Styling deve essere riapplicato il metodo SetData, quindi ho aggiornato il codice sopra per estrarre un ApplyStyles metodo e chiamata da ApplyStyle, SetData e SetIsImportant.
    • Come per le intestazioni, dovrebbe essere facile. Nelle colonne costruttore aggiungere if (Griglia <> nil) e (Griglia.FHeader <> nil) quindi Griglia.FHeader.Gli Elementi[Indice].TextAlign := TTextAlign.alTrailing; – Ma Fheader è un membro privato, quindi dovrete sottoclasse TGrid di esporre. (E il TColumn non esporre è proprietà di Intestazione è semplicemente una stringa, non un THeader).
    • Grazie per la modifica, nessun problema. Ho ancora sembrano avere uno strano problema quando ho scorrere tuttavia che alcuni valori sono in grassetto ogni tanto di scorrimento, quindi se si scorre all’indietro – non sono? Ho anche dovuto cambiare il “ApplyStyling” a “TFinancialCell.ApplyStyling”; è corretto o ho fatto a causare il problema? Thx Ian.
    • Ciao Mike – forse ho individuato quello che causa il ridisegno problema per me nel mio esempio (potrebbe essere un FM bug?). Se si di scorrimento del mouse (rotellina) la griglia di contenuto; quindi funziona come progettato. Se si trascina la barra di scorrimento – non? – Non sono sicuro se questo aiuta?
    • Oops. Non ho notato che uno. Così, il CellFromIndex roba non funziona in quel punto. L’opzione successiva (a aggiornato il codice di cui sopra) è il passaggio di Valore come stringa, e aggiungere un # char per indicare una voce in grassetto. Un’altra alternativa potrebbe essere quella di aggiungere un evento al cell classe, che avrebbe dovuto essere impostata dall’CreateCellControl di colonna (che, naturalmente, ha bisogno di un’aggiunta di proprietà di evento). Chiamare l’evento dal metodo SetData ed è possibile impostare le proprietà della cella che si desidera cambiare. O il passaggio di un oggetto come il risultato di GetValue ed estraetelo nella SetData.
    • Ha lavorato anche per la perseveranza di Mike. Il TGrid è un controllo veloce, ma sicuramente un FM v1.0 controllo. – Superstar…!

  2. 1

    Codice di cui sopra va bene anche per le versioni prima di XE4, ma per XE4 e XE5 non funziona. Il colore e lo stile del testo non viene modificato.

    Questo è un codice fisso XE4 e 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;

Lascia un commento