Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 209
  • Last Modified:

Newbie Question: Create a component using other components

I have spent countless hours trying to learn how to create a new component, and am coming up short.  I'm sure this question is easy for the experts, but I'm getting frustrated with the lack of answers out there.

I have found several tutorials on creating new components. Many of them mention my problem but never get into details.

I'm creating a component that is a TPanel.  Within that Panel there is a edit box and a label.  I would like to present to the object inspector only certain properties of the panel, and selected properties of the edit and the label.

I have figured out that if you want to "hide" some of the parameters, then you have to use a "TCustomPanel" and only publish the properties of the panel that I want (however, some of them like top/left/help still remain!?!?).  However, I can't for the life of me figure out how to publish the properties of the edit box or the label as properties of the new component.

Ideally, what I would like to do is call the component "MyComponent".  Within the object inspector, I would like to see:

"Heading" (string referring to "label.caption")
"Data" (string referring to "editbox.text")
etc...

I figured out that when I publish the properties, I can pass the entire object as a property, and I can see it as a sub item in object inspector.  When I change the value of it in the object inspector, I can see the values updated in the form, HOWEVER when I run the program, the values are reset to the defaults (only on the sub components!)

ie:

type
  TDataField = class (TCustomPanel)
  protected
    fHeading: TLabel;
    fData: TEditBox;

    fDataType: String;
    fDigits: Integer;
    fDecimals: Integer;
    fExpression: String;

  private
  public
    constructor Create(AOwner:TComponent); override;
  published
    property Caption;
    property Heading: TLabel read fLabel write fLabel;
    property Data: TEditBox read fData write fData;
    property DataType: String read fDataType write fDataType;
    property Digits: Integer read fDigits write fDigits default 0;
    property Decimals: Integer read fDecimals write fDecimals default 2;
    property Expression: String read fExpression write fExpression;
end;

I create my Label/Editbox in the constructor and give them the default values, but it doesn't appear at runtime the program is passing in the values from the object inspector....but this is only the case with the label/editbox.  Values on the object inspector are correctly applied to the parent panel.

There may be something wrong with my constructor statement.

Anyways, any help would be appreciated!
0
ncnmra
Asked:
ncnmra
1 Solution
 
kretzschmarCommented:
0
 
Slick812Commented:
hello  ncnmra, , I would not want to have a control on my component and then try an Expose it as that control, as you did -

property Data: TEditBox read fData write fData;

although there may be a rare occation that this was nessary, I can not see it,
I would not expose any properties of the Control and just have my own Component properties to adjust that control , , ,


not sure if this is what you are asking, but here is a panel component, that may help you to look at -



unit vPanel;
interface
uses
  SysUtils, Windows, Messages, Classes, stdctrls, Graphics, Controls,
  Forms, ExtCtrls;

type
  TvPanel = class(TCustomPanel)
  private
    //property Width;
    //property Height;
  protected
    FHeading, FData: String;
    FEdit1: TEdit;
    FLabel1: TLabel;
    procedure setHeading(Value: String);
    procedure setData(Value: String);
    property Width;  
// if you move the base component properties into the protected or private, it will hide them from user in form code
    property Height;
    property Caption;
  public
     constructor Create(AOwner: TComponent); override;
  published
    property Heading: String read FHeading write setHeading;
// use a setHeading procedure to access the Control's properties
    property Data: String read FData write setData;

  end;

procedure Register;

implementation

constructor TvPanel.Create( AOwner: TComponent );
begin
inherited Create(AOwner);
Self.
Width := 237;
Height := 71;
ControlStyle:= ControlStyle - [csSetCaption];
FLabel1 := TLabel.Create(Self);
with FLabel1 do
  begin
  Parent := Self;
  Color := $84007B;
  Caption := ' vPanel ';
  Font.Style := Font.Style+[fsBold];
  Font.Color := $E8FFEF;
  AutoSize := True;
  SetBounds(94,4,88,23);
  end;

FEdit1 := TEdit.Create(Self);
with FEdit1 do
  begin
  Parent := Self;
  Text := 'No data';
  Font.Name := 'Arial';
  SetBounds(6,31,225,20);
  end;
Caption := '';
end;

procedure TvPanel.setHeading(Value: String);
var
widthT: Integer;
oFont: TFont;
begin
if Value <> FHeading then
  begin
  FHeading := Value;
  oFont := Canvas.Font;
  Canvas.Font := FLabel1.Font;
  widthT := Canvas.TextWidth(' '+FHeading+' ');
  Canvas.Font := oFont;
  FLabel1.Caption := ' '+FHeading+' ';
  FLabel1.Left := (Width div 2) - (widthT div 2);
  end;
end;

procedure TvPanel.setData(Value: String);
begin
if Value <> FHeading then
  begin
  FData := Value;
  FEdit1.Text := FData;
  end;
end;


procedure Register;
begin
RegisterComponents('Jack', [TvPanel]);
end;

end.


 = = = = = = = = = = = = = = = = = = = = =
I hope this will help
0

Featured Post

Upgrade your Question Security!

Add Premium security features to your question to ensure its privacy or anonymity. Learn more about your ability to control Question Security today.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now