简体   繁体   中英

Applying a style to a Delphi XE4 Firemonkey StringGrid cell at runtime

I am trying to apply a style to an XE4 FM Stringgrid at runtime, but am unable to find the correct syntax to do this.

The StringGrid already inherits the 'TextCellStyle' (the default) which I have created at design time, and display the cells in the stringgrid according to this style.

What I would ideally like to do is change the colour of the fonts in specific cells (negative=Red, positive=green etc) at runtime, but cannot work out how to do this, as I am unable to access the Stylelookup at cell level.

Please remember that this query relates to a TStringGrid, and not a TGrid, as our application requires us to allocate memory to the grid dynamically at run-time, and it is much easier to do with a stringgrid.

Any help would be very much appreciated, and thanks in advance.

I have been attempting to learn how to do this with a TGrid, and thanks to Mike Sutton's help have managed this.

[See Changing TTextCell background colour at runtime XE4 for background.]

Having managed to get this right, I attempted a similar logic on a TStringGrid and it worked fine. As stringgrid doesn't use Grid1GetValue, I simply hard-coded random numbers into the grid in FormCreate.

[In the code below I have a style called textcellstyle; to the 'background' component of textcellstyle I added a TRectangle, so I could call on the 'Fill' property of TRectangle. Still not on top of the styles yet, see link above.]

My code, in case it's helpful:

    Procedure TForm1.FormCreate(Sender : TObject);

    begin
      { CREATE AN EXTRA COLUMN }
      StringGrid1.AddObject(TFinancialColumn.CreateStringGrid1));  
      { HARD-CODE THE ROWS }
      StringGrid1.Cells[0,0] :='0';
      StringGrid1.Cells[0,1] :='1';
      StringGrid1.Cells[0,2] :='2';
      StringGrid1.Cells[0,3] :='3';
      StringGrid1.Cells[0,4] :='4';
      StringGrid1.Cells[0,5] :='5';
      StringGrid1.Cells[0,6] :='6';
      StringGrid1.Cells[0,7] :='7';
      StringGrid1.Cells[0,8] :='8';
      StringGrid1.Cells[0,9] :='9';
      StringGrid1.Cells[0,10]:='10';
      { HARD-CODE A BUNCH OF NUMBERS. NOTE THAT HASH IN FRONT OF A NUMBER IS SIMPLY A  FLAG FOR IsImportant }
      StringGrid1.Cells[1,0] :='-10';
      StringGrid1.Cells[1,1] :='-6.86999999';
      StringGrid1.Cells[1,2] :='76.0999999';
      StringGrid1.Cells[1,3] :='#10.25';        
      StringGrid1.Cells[1,4] :='#17.2900006';
      StringGrid1.Cells[1,5] :='#57.1599993';
      StringGrid1.Cells[1,6] :='21.86000';
      StringGrid1.Cells[1,7] :='6.17';
      StringGrid1.Cells[1,8] :='27.219999';
      StringGrid1.Cells[1,9] :='#32.56000';
      StringGrid1.Cells[1,10]:='-1.7999';
    end;


    Function TFinancialColumn.CreateCellControl : TStyledControl;

    begin
      Result:=TFinancialCell.Create(Self);

      TTextCell(Result).OnTyping:=DoTextChanged;
      TTextCell(Result).OnExit  :=DoTextExit;
    end;

    Constructor TFinancialCell.Create(AOwner : TComponent);

    begin
      inherited;
      StyleLookup:='textcellstyle';
      StyledSettings:=StyledSettings-[TStyledSetting.ssStyle,TStyledSetting.ssFontColor]; { THIS LINE MUST BE HERE TO APPLY A NEW STYLE; IT CLEARS THE 'DEFAULT' STYLE SETTINGS }
      TextAlign:=TTextAlign.taTrailing;
    end;

    Procedure TFinancialCell.SetData(const Value          : TValue);

    var 
      F                                                   : Single;
      O                                                   : TFMXObject;
      S                                                   : String;

    begin
      S:=Value.AsString;

      If Length(S)>1 then 
      begin 
        FIsImportant:=S[1]='#';
        If IsImportant then
          S:=Copy(Value.AsString,2,MaxInt)
        else
          S:=Value.AsString;

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

        ApplyStyling;
      end;  
    end;

    Procedure TFinancialCell.ApplyStyle;

    var 
      T                                                   : TFMXObject;

    begin
      inherited;

      T:=FindStyleResource('rectangle1');

      If T is TRectangle then
      begin 
        If IsNegative then 
        begin
          TRectangle(T).Fill.Color:=claRed; 
        end;  
      end;

      ApplyStyling;
    end;

    Procedure TFinancialCell.ApplyStyling;

    var 
      T                                                   : TFMXObject;

    begin
      If IsNegative then
        FontColor:=claBlack
      else
        FontColor:=claGreen;

      If IsImportant then Font.Style:=[TFontStyle.fsItalic,TFontStyle.fsBold]; { REPEAT THE ITALIC ELSE IT WILL ONLY BE BOLD, IE IT OVERWRITES THE ITALIC WITH BOLD }

      If Assigned(Font.OnChanged) then
        Font.OnChanged(Font);

      Repaint;
    end;

This code works in terms of restyling the fonts and backgrounds. Any suggestions to improve the above are most welcome, but hopefully this can help.

The styling falls apart as soon as you start scrolling, though, haven't figured out how to fix that yet. Any suggestion would be most welcome!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM