Getting Data for Custom Report Component
Mark Elder
SD, USA
I'm trying to build a custom Report Component
My component will add an IndentLevelFieldName and IndentWidth property to the standard View. This will add an indent before printing the field based on the "level" set in a different DataSet field. I'm going to use this to print tree structures in a report.
I can register the component, add it to a report, and see my new properties. However I can't seem to get the correct values by the time I'm in the draw event. I have overridden the GetData event, but I still always have a zero for the FIndentLevel when I get into the draw code.
How do I setup my component state so that the Draw method as the correct values?
Here is the code for my component:
My component will add an IndentLevelFieldName and IndentWidth property to the standard View. This will add an indent before printing the field based on the "level" set in a different DataSet field. I'm going to use this to print tree structures in a report.
I can register the component, add it to a report, and see my new properties. However I can't seem to get the correct values by the time I'm in the draw event. I have overridden the GetData event, but I still always have a zero for the FIndentLevel when I get into the draw code.
How do I setup my component state so that the Draw method as the correct values?
Here is the code for my component:
unit MgrFastReportComponents;
interface
uses
  // Delphi
  System.Types,
  Classes, Graphics,
  // FastReport
  frxClass, frxDesgnEditors;
type
  TMgrIndentMemoView = class(TFrxMemoView)
    private
      FIndentWidth: integer;
      FIndentLevelFieldName: string;
      FIndentLevel: integer;
    public
      procedure Draw(Canvas: TCanvas; ScaleX, ScaleY, OffsetX, OffsetY: Extended); override;
    published
      property IndentWidth: integer read FIndentWidth write FIndentWidth;
      property IndentLevelFieldName: string read FIndentLevelFieldName write FIndentLevelFieldName;
      property IndentLevel: integer read FIndentLevel write FIndentLevel;
      procedure GetData; override;
  end;
implementation
uses
  System.UITypes,
  StrUtils,
  SysUtils,
  frxDsgnIntf,
  frxUtils,
  frxRes,
  Winapi.Windows;
type
  TfrxDataFieldProperty = class(TfrxPropertyEditor)
  public
    function GetValue: String; override;
    function GetAttributes: TfrxPropertyAttributes; override;
    procedure GetValues; override;
    procedure SetValue(const Value: String); override;
  end;
{ TfrxDataFieldProperty }
function TfrxDataFieldProperty.GetAttributes: TfrxPropertyAttributes;
begin
  Result := [paMultiSelect, paValueList];
end;
function TfrxDataFieldProperty.GetValue: String;
begin
  Result := GetStrValue;
end;
procedure TfrxDataFieldProperty.SetValue(const Value: String);
begin
  SetStrValue(Value);
  if Component is TfrxCustomMemoView then
    with TfrxCustomMemoView(Component) do
      if IsDataField then
        Text := '[' + DataSet.UserName + '."' + DataField + '"]';
end;
procedure TfrxDataFieldProperty.GetValues;
var
  ds: TfrxDataSet;
begin
  inherited;
  ds := TfrxView(Component).DataSet;
  if ds <> nil then
    ds.GetFieldList(Values);
end;
var
  Bmp_IndentMemo: Graphics.TBitmap;
{ TMgrIndentMemoView }
procedure TMgrIndentMemoView.Draw(Canvas: TCanvas; ScaleX, ScaleY, OffsetX,
  OffsetY: Extended);
begin
  if IsDesigning = true then
    inherited
  else
  begin
    inherited Draw(Canvas, ScaleX, ScaleY, OffsetX + (FIndentLevel * FIndentWidth), OffsetY);
  end;
end;
procedure TMgrIndentMemoView.GetData;
begin
  FIndentLevel := 0;
  if DataSet <> nil then
  begin
    try
      FIndentLevel := DataSet.Value[FIndentLevelFieldName];
    except on E: Exception do
      begin
        // can I log the exception anywhere?? Where do our "info" errors
        // get logged?
        FIndentLevel := 0;
      end;
    end;
  end;
  inherited;
end;
initialization
  Bmp_IndentMemo := Graphics.TBitmap.Create;
  //Bmp_FormProp.LoadFromResourceName(hInstance, 'CF_PAGE_PROPERTIES');
  frxObjects.RegisterObject(TMgrIndentMemoView, Bmp_IndentMemo);
  frxPropertyEditors.Register(TypeInfo(String), TfrxView, 'IndentLevelFieldName', TfrxDataFieldProperty);
finalization
  FreeAndNil(Bmp_IndentMemo);
end.
Comments