0

I created a custom TClientDataset that I then registered as a design time component.

TMyDataset = class(TClientDataset)
public
constructor Create(AOwner : TComponent); override;
end;

in the Create method, I created the fields of this dataset

implementation

constructor TMyDataset.Create(aOwner : TComponent);
var
  lField : TStringField;
begin
  inherited Create(aOwner);
  lField := TStringField.Create(Self);
  lField.FieldName := 'NAME';
  lField.Dataset := Self;
  Fields.Add(lField);      
end;

When registering the component as such

procedure Register;
begin
RegisterComponents('Queries', [TMyDataset]);
end;

And dropping the TMyDataset onto a form, I do not see the NAME field in the Fields collection of this dataset.

My goal is to define and register these predefined queries so I can use them at design time.

I would like to prevent anyone using this component from redefining the Fields of this dataset, but still be able to see them in the visual editor to bind cxGrid or such (automatic column creation and so on).

Also, this Dataset is only a placeholder for another dataset. It will only serve to present the Fields collection to other visual editors that can bind to them.

My question is :

Why can't I see the field I created in the constructor in the visual editor and how can I make it visible?

How can I override the behavior of the component to never save the user modifications on its TFields into the DFM ?

Thank you

Ludovic C
  • 2,855
  • 20
  • 40

1 Answers1

1

The following works fine for me, including the NAME field showing up in the TMyDataSet Fields editor:

uses
  SysUtils, Classes, DB, DBClient;

type
  TMyDataSet = class(TClientDataSet)
  private
    FMyStringField : TStringField;
    function GetMyStringField: TStringField;
  protected
  public
    constructor Create(AOwner : TComponent); override;
    property MyStringField : TStringField read GetMyStringField;
  published
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Data Access', [TMyDataSet]);
end;

{ TMyDataSet }

constructor TMyDataSet.Create(AOwner: TComponent);
begin
  inherited;
  FMyStringField := TStringField.Create(AOwner);
  FMyStringField.FieldName := 'NAME';
  FMyStringField.Size := 80;
  FMyStringField.DataSet := Self;
end;

function TMyDataSet.GetMyStringField: TStringField;
begin
  Result := FMyStringField;
end;

You should be able to easily identify how your code needs modifying to work similarly. You are omitting the Size of the StringField for one thing.

[tbc]

MartynA
  • 30,454
  • 4
  • 32
  • 73
  • Thank you, I think that the AOwner of the field must be the owner of the Dataset, that's what worked when I modified my code – Ludovic C May 15 '17 at 17:15
  • Do you know how I can prevent the modification of the DFM by the user ? (prevent adding / modifying of Fields) ? – Ludovic C May 15 '17 at 17:30
  • "prevent the modification..." Not offhand, but I have a feeling @SertacAkyuz's answer to this q of mine may be relevant to this and the fact that Delphi complains about a duplicate `NAME` field whan using my code:http://stackoverflow.com/questions/38293072/how-to-correctly-stream-a-tcollection-property-of-a-subcomponent-e-g-the-colum – MartynA May 15 '17 at 17:36