自作コンポーネント上のTEditのプロパティを保存させるには?

解決


めじな  2007-11-29 18:31:32  No: 28740

TWinControl上にTEditを2つ乗っけるコンポーネントを作成しています。
動的に生成したTEditにアクセスするために以下のようなプロパティを用意したのですが、オブジェクトインスペクタで変更した値がうまくDFMに保存されません。
  property EditCode: TEdit read FEditCode;

生成時に↓のように「Self」指定で作っているため、と思われます。
  FEditCode := TEdit.Create(Self);
「AOwner」を指定するとプロパティは保存されますが、デザイン画面でコンポーネント内のTEditを直接選択出来てしまい、移動させたり、削除出来てしまうなど問題があります。
(また、下記に示すサンプルソースではTEditがいくつも出来てしまいます)

2つのTEditにアクセスするためのプロパティをそれぞれ2個ずつ記述すれば良いのですが、プロパティが多くなりごちゃごちゃしてしまいそうなので、出来るならオブジェクトインスペクタでそれぞれグループ化されるようにしたいと考えています。

宜しくお願いします。

環境:BDS2006 win32 + WinXP Pro SP2

--- 以下サンプルソース -----------------------------------------------
unit Sample;

interface

uses
  SysUtils, Classes, Controls, StdCtrls;

type
  TSample = class(TWinControl)
  private
    { Private 宣言 }
    FEditCode: TEdit;
    FEditName: TEdit;
  protected
    { Protected 宣言 }
  public
    { Public 宣言 }
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    { Published 宣言 }
    property EditCode: TEdit read FEditCode;
    property EditName: TEdit read FEditName;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Samples', [TSample]);
end;

{ TSample }

constructor TSample.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

//  FEditCode := TEdit.Create(AOwner);  //プロパティ保存されるが問題あり
  FEditCode := TEdit.Create(Self);
  FEditCode.Parent := Self;
  FEditCode.Left   := 0;
  FEditCode.Top    := 0;
  FEditCode.Width  := 50;

//  FEditName := TEdit.Create(AOwner);
  FEditName := TEdit.Create(Self);
  FEditName.Parent := Self;
  FEditName.Left   := 50;
  FEditName.Top    := 0;
  FEditName.Width  := 100;

  Self.Height := 21;
  Self.Width  := 150;
end;

destructor TSample.Destroy;
begin
  FEditCode.Free;
  FEditName.Free;
  inherited Destroy;
end;

end.


KHE00221  2007-11-29 19:35:28  No: 28741

おそらくオブジェクトインスペクタ上でプロパティ名が黒で表示されない時点でプロパティの保存は無理かと思います。

フォームをエディタで表示した時点で設定が消えています。

>「AOwner」を指定するとプロパティは保存されますが、デザイン画面でコン>ポーネント内のTEditを直接選択出来てしまい、移動させたり、削除出来てし>まうなど問題があります。

仮に出来たとしてもプロパティを設定する事により移動とか可能になってしまいますよ

>2つのTEditにアクセスするためのプロパティをそれぞれ2個ずつ記述すれ
>ば良いのですが、プロパティが多くなりごちゃごちゃしてしまいそうなの
>で、出来るならオブジェクトインスペクタでそれぞれグループ化されるよう>にしたいと考えています。

ですが下記のようにすればオブジェクトインスペクタ上でグループ化する事は可能です

unit PanelEx;

interface

uses
  SysUtils, Classes, Controls, StdCtrls,ExtCtrls,Graphics;

type

  TEditProperty = class(TPersistent)
  private
    FEdit : TEdit;
    FText : String;
  protected
    procedure SetText(Value:String);
    function GetText:String;
    procedure SetColor(Value:TColor);
    function GetColor:TColor;
  public
    constructor Create(AOwner: TComponent;Edit:TEdit);
    destructor Destroy;override;
  published
    property Text : String read GetText write SetText;
    property Color : TColor read GetColor write SetColor;
  end;

  TPanelEx = class(TPanel)
  private
    FEdit1 : TEdit;
    FEdit2 : TEdit;
    FEdit1Property : TEditProperty;
    FEdit2Property : TEditProperty;
  protected
    procedure SetEdit1(Value:TEdit);
    procedure SetEdit2(Value:TEdit);
  public
    constructor Create(AOwner: TComponent);override;
    destructor Destroy;override;
  published
    property Edit1 : TEditProperty read FEdit1Property write FEdit1Property;
    property Edit2 : TEditProperty read FEdit2Property write FEdit2Property;
  end;

procedure Register;

implementation

//--------------------------------------------
// TEditProperty
//--------------------------------------------

procedure TEditProperty.SetText(Value: string);
begin
    if Assigned(FEdit) = True then FEdit.Text := Value;
end;

function TEditProperty.GetText;
begin
    if Assigned(FEdit) = True then Result := FEdit.Text;
end;

procedure TEditProperty.SetColor(Value: TColor);
begin
    if Assigned(FEdit) = True then FEdit.Color := Value;
end;

function TEditProperty.GetColor;
begin
    if Assigned(FEdit) = True then Result := FEdit.Color;
end;

constructor TEditProperty.Create(AOwner: TComponent;Edit:TEdit);
begin
    inherited Create;
    FEdit := Edit;
end;

destructor TEditProperty.Destroy;
begin
    inherited Destroy;
end;

//--------------------------------------------
// TPanel
//--------------------------------------------

procedure TPanelEx.SetEdit1(Value: TEdit);
begin
    FEdit1.Assign(Value);
end;

procedure TPanelEx.SetEdit2(Value: TEdit);
begin
    FEdit2.Assign(Value);
end;

constructor TPanelEx.Create(AOwner: TComponent);
begin
    inherited Create(AOwner);

    FEdit1 := TEdit.Create(Self);
    FEdit1.Parent := Self;
    FEdit1.Left := 0;
    FEdit1.Top  := 0;

    FEdit2 := TEdit.Create(Self);
    FEdit2.Parent := Self;
    FEdit2.Left := 0;
    FEdit2.Top  := 20;

    FEdit1Property := TEditProperty.Create(Self,FEdit1);
    FEdit2Property := TEditProperty.Create(Self,FEdit2);
end;

destructor TPanelEx.Destroy;
begin

    FEdit2Property.Free;
    FEdit1Property.Free;

    FEdit2.Free;
    FEdit1.Free;
    inherited Destroy;
end;

procedure Register;
begin
  RegisterComponents('Component', [TPanelEx]);
end;

end.


めじな  2007-11-29 22:35:30  No: 28742

教えて頂いた方法で出来そうです。
公開するプロパティもTEditPropertyで定義出来るのでこちらとしてはうれしい限りです。
有難う御座います。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加