Link to home
Start Free TrialLog in
Avatar of CalvinDay
CalvinDay

asked on

Exposing component properties

Say I want to develop a component that contains a TEdit and a TLabel. I would like a single component that shows the properties of both the edit and the label in the object inspector.
something like this:

+Edit
+Label
  Name
  Tag

How is this done?
Avatar of Ferruccio Accalai
Ferruccio Accalai
Flag of Italy image

what do you mean? a component that have properties linked to a tedit and a tlabel? in this case this is a little example:

unit Mycomponent;

interface

uses
  Windows, Messages, SysUtils, Classes, stdctrls;

type
  tMycomponent = class(tcomponent)
  private
    { Private declarations }
    fedit: TEdit;
    fLabel: TLabel;
  protected
    { Protected declarations }
  public
    { Public declarations }
  published
    { Published declarations }
    property TheEdit: TEdit read fedit write fedit;
    property TheLabel: TLabel read flabel write flabel;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Standard', [tMycomponent]);
end;

end.
 
then, putting this MyComponent, a tedit and a tlabel on the form, and linking the Mycomponent properties to the edit1 and label1 you'll have both objects properties in the mycomponent object inspector...
ASKER CERTIFIED SOLUTION
Avatar of Russell Libby
Russell Libby
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ah  yes of course...you're right russel
cool, rllibby, nice solution :-)
welcome back meikl:)))
you are allways present, f68 :-))

Thanks all, very kind...

Russell
Avatar of CalvinDay
CalvinDay

ASKER

I must be going crazy ...

Russell's example does expose the properties, however properties that are changed do not get saved with the form. If I save the form and reopen it, everything reverts back to default properties.

I had something similar as Russell using the (actually found this at the undu.com site)
   TLabelEditProperty = class(TClassProperty)
and
    RegisterPropertyEditor(TypeInfo(TLabel),TLabelEdit,'Prompt',TLabelEditProperty);

It exposes the properties too. again nothing is saved in the form.

Am I missing something?

unit LabelEdit;

interface

uses
  Classes, Controls, DBCtrls, DsgnIntf, StdCtrls;

const
  SPACING = 5;

type
  TLabelEdit = class(TWinControl)
  private
    fField:TEdit;
    fPrompt:TLabel;
  public
    procedure SetField(Value:TEdit);
    procedure SetPrompt(Value:TLabel);
    constructor Create(Owner: TComponent); override;
    destructor Destroy; override;
  published
    property Field:TPersistent read fField write SetField;
    property Prompt:TPersistent read fPrompt write SetPrompt;
  end;

  TLabelEditProperty = class(TClassProperty)
  end;

procedure Register;

implementation

procedure TLabelEdit.SetField(Value:TEdit);
begin
  fField.Assign(Value);
end;

procedure TLabelEdit.SetPrompt(Value:TLabel);
begin
  fPrompt.Assign(Value);
end;

constructor TLabelEdit.Create(Owner: TComponent);
begin
  inherited Create(Owner);

  fPrompt := TLabel.Create(Self);
  with fPrompt do
  begin
    Align := alLeft;
    Alignment := taRightJustify;
    Caption := 'Prompt :';
    Layout := tlCenter;
    Parent := Self;
  end;

  fField := TEdit.Create(Self);
  with fField do
  begin
    Ctl3D := True;
    Left := fPrompt.Width + SPACING;
    Top := 0;
    Parent := Self;
  end;

  Self.Height := fField.Top + fField.Height;
  Self.Width := fField.Left + fField.Width;
end;

destructor TLabelEdit.Destroy;
begin
  fField.Free;
  fPrompt.Free;
  inherited Destroy;
end;

procedure Register;
begin
  RegisterComponents('Samples', [TLabelEdit]);
  RegisterPropertyEditor(TypeInfo(TLabel),TLabelEdit,'Prompt',TLabelEditProperty);
  RegisterPropertyEditor(TypeInfo(TEdit),TLabelEdit,'Field',TLabelEditProperty);
end;

end.

hmmm,

maybe a wrapper-class is needed
see
https://www.experts-exchange.com/questions/20699349/Custom-DBEdit-conponent.html

(was a q from u, calvin)

looking tomorrow closer about the storage

meikl ;-)

That's what I did. I really needed a TADOQuery as my sub component. I was tired of matching Queries with Dropdown so I figured I would embed a Query withthe dropdown.

I guess I should post a solution: (I tried to also have the parameters property but that was another can of worms. ColnEdit & Toolwnds)

unit QueryWrapper;

interface

uses
  Classes, Controls, DBCtrls, DsgnIntf, StdCtrls, ADODB, DB;

type
  TQueryWrapper = class(TPersistent)
  private
    fQuery: TADOQuery;
  protected
    function GetConnection:TADOConnection;
    procedure SetConnection(Value:TADOConnection);
    function GetSQL:TStrings;
    procedure SetSQL(Value:TStrings);
    function GetActive:boolean;
    procedure SetActive(Value:boolean);
  public
    property Query:TADOQuery read fQuery;
    constructor Create(Owner: TComponent);
    destructor Destroy; override;
  published
    property Connection: TADOConnection read GetConnection write SetConnection;
    property SQL:TStrings read GetSQL write SetSQL;
    property Active:boolean read GetActive write SetActive;
  end;

implementation

constructor TQueryWrapper.Create(Owner: TComponent);
begin
  inherited Create;
  fQuery:=TADOQuery.Create(Owner);
  fQuery.Parameters.AddParameter;

  with fQuery.Parameters[0] do
    begin
    Name:='Param';
    Attributes:=[paNullable];
    DataType:=ftString;
    NumericScale:=255;
    Precision:=255;
    Size:=50;
    Value:='%';
    end;
end;

destructor TQueryWrapper.Destroy;
begin
  fQuery.Free;
end;

function TQueryWrapper.GetConnection:TADOConnection;
begin
  Result:=fQuery.Connection;
end;

procedure TQueryWrapper.SetConnection(Value:TADOConnection);
begin
  fQuery.Connection:=Value;
end;

function TQueryWrapper.GetSQL:TStrings;
begin
  Result:=fQuery.SQL;
end;

procedure TQueryWrapper.SetSQL(Value:TStrings);
begin
  fQuery.SQL.Assign(Value);
end;

function TQueryWrapper.GetActive:boolean;
begin
  Result:=fQuery.Active;
end;

procedure TQueryWrapper.SetActive(Value:boolean);
begin
  fQuery.Active:=Value;
end;

end.


Small mistake: Add

destructor TQueryWrapper.Destroy;
begin
  fQuery.Free;
  inhertied Destroy;
end;