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?
something like this:
+Edit
+Label
Name
Tag
How is this done?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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
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(Typ eInfo(TLab el),TLabel Edit,'Prom pt',TLabel EditProper ty);
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('Sample s', [TLabelEdit]);
RegisterPropertyEditor(Typ eInfo(TLab el),TLabel Edit,'Prom pt',TLabel EditProper ty);
RegisterPropertyEditor(Typ eInfo(TEdi t),TLabelE dit,'Field ',TLabelEd itProperty );
end;
end.
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(Typ
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:
begin
fField.Assign(Value);
end;
procedure TLabelEdit.SetPrompt(Value
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('Sample
RegisterPropertyEditor(Typ
RegisterPropertyEditor(Typ
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 ;-)
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 ;-)
ASKER
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:TADOConnecti on;
procedure SetConnection(Value:TADOCo nnection);
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(O wner);
fQuery.Parameters.AddParam eter;
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.GetConnectio n:TADOConn ection;
begin
Result:=fQuery.Connection;
end;
procedure TQueryWrapper.SetConnectio n(Value:TA DOConnecti on);
begin
fQuery.Connection:=Value;
end;
function TQueryWrapper.GetSQL:TStri ngs;
begin
Result:=fQuery.SQL;
end;
procedure TQueryWrapper.SetSQL(Value :TStrings) ;
begin
fQuery.SQL.Assign(Value);
end;
function TQueryWrapper.GetActive:bo olean;
begin
Result:=fQuery.Active;
end;
procedure TQueryWrapper.SetActive(Va lue:boolea n);
begin
fQuery.Active:=Value;
end;
end.
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:TADOConnecti
procedure SetConnection(Value:TADOCo
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
begin
inherited Create;
fQuery:=TADOQuery.Create(O
fQuery.Parameters.AddParam
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.GetConnectio
begin
Result:=fQuery.Connection;
end;
procedure TQueryWrapper.SetConnectio
begin
fQuery.Connection:=Value;
end;
function TQueryWrapper.GetSQL:TStri
begin
Result:=fQuery.SQL;
end;
procedure TQueryWrapper.SetSQL(Value
begin
fQuery.SQL.Assign(Value);
end;
function TQueryWrapper.GetActive:bo
begin
Result:=fQuery.Active;
end;
procedure TQueryWrapper.SetActive(Va
begin
fQuery.Active:=Value;
end;
end.
ASKER
Small mistake: Add
destructor TQueryWrapper.Destroy;
begin
fQuery.Free;
inhertied Destroy;
end;
destructor TQueryWrapper.Destroy;
begin
fQuery.Free;
inhertied Destroy;
end;
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('Standa
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...