2
votes

I need to get my money cells on a grid to show the local currency symbol, be right aligned and have negative numbers shown in red.

Unlike similar posts I am populating my TGrid from a dataset using livebindings. Other solutions suggest sub-classing a "TFinancialCell" from a TStringCell for the grid which is difficult when using livebindings.

With Livebindings, the Bind Manager controls the creation of the grid columns and cells so that sub-classing the Bind Manager (and other relevant classes) is probably neither practical nor elegant.

1
If it is solved you should left the question as a question and then add the answer too. o.o''EMBarbosa

1 Answers

3
votes

Having messed with this some more I have found a solution which answers my problem

The money symbol is obtained by using the OnGetText event of the dataset field to return the formatted string:

procedure FDTableMyCurrFieldGetText(Sender: TField; var Text: string;
  DisplayText: Boolean);
begin
  DisplayText := True;
  Text := FloatToStrF(Sender.AsCurrency, ffCurrency, 18, 2);
end;

I could have done this in the Grid OnPainting event but doing it this way formats the field for all linked controls as well as for the grid. I use "Sender" rather than "FDTableMyCurrField" to refer to the Field so that I can point the OnGetText event of all the other currency fields in my datasets to this method.

The rest of the formatting is done in the Grid. The Cells of the Grid are not exposed explicitly but you can get to them like this "TTextCell(Grid1.Columns[I].Children[J])". Use the Grid OnPainting event to format the cells immediately before they are painted.

Right alignment is achieved by setting the alignment of the Cell in the grid.

The cell text color is set by using Styles. We need to create a "textcellnegativestyle" in our application StyleBook. This will be identical to the default "textcellstyle" except that the "foreground" Brush colour will be red. On a desktop application you could drop a TEdit on your application, right-click it and select "Edit Custom Style..." then name the custom style "textcellnegativestyle" based on the "editstyle" but just change the foreground Brush color to red.

Mine is a mobile app where "Edit Custom Style" does not appear on the Delphi form editor popup menu options for this reason. To add a custom style you have to edit (a copy of) the .style file with Notepad or some text editor.

  1. Copy/paste the "textcellstyle" object
  2. edit the name of the pasted object to "textcellnegativestyle"
  3. change the 'foreground' Brush color to red.
  4. Load the edited file into your application StyleBook.

Here is how it looks in my .style file:

  object TLayout
    StyleName = 'textcellnegativestyle'
    DesignVisible = False
    Height = 50.000000000000000000
    Width = 50.000000000000000000
    object TLayout
      StyleName = 'content'
      Align = alContents
      Locked = True
      Height = 42.000000000000000000
      Margins.Left = 4.000000000000000000
      Margins.Top = 4.000000000000000000
      Margins.Right = 4.000000000000000000
      Margins.Bottom = 4.000000000000000000
      Width = 42.000000000000000000
    end
    object TBrushObject
      StyleName = 'foreground'
      Brush.Color = claRed
    end
    object TBrushObject
      StyleName = 'selection'
      Brush.Color = x7F72B6E6
    end
    object TFontObject
      StyleName = 'font'
    end
  end

I use the Grid OnPainting event to set the Cells alignment and style. here is my working solution:

procedure TFormMain.Grid1Painting(Sender: TObject; Canvas: TCanvas;
  const ARect: TRectF);
var
  I, J: Integer;
  T: TTextCell;
begin
  // my Column 0 is text, all other columns are money in this example
  for I := 1 to Grid1.ColumnCount - 1 do
    for J := 0 to Grid1.Columns[I].ChildrenCount- 1 do
    begin
      T := TTextCell(Grid1.Columns[I].Children[J]);
      // set the Cell text alignment to right align
      T.TextAlign := TTextAlign.taTrailing;

      // test the Cell string for a negative value
      if (T.Text[1] = '-') then
      begin
        // remove the leading minus sign
        T.Text := Copy(T.Text, 2, Length(T.Text) - 1);
        // set the font to red using the style
        T.StyleLookup := 'textcellnegativestyle';
      end
      else T.StyleLookup := 'textcellstyle';
    end;
end;