Desenvolvendo componente com sub-propriedades e sub-eventos dinâmicos

Delphi

06/10/2012

Olá,

Preciso desenvolver um componente com sub-propriedades e sub-eventos agrupados relacionados a um tipo especifico, por exemplo, quando eu alterar esse tipo específico, a propriedade em si deve ser alterada também, dessa maneira, tenho duas propriedades em meu componente:

"_MyPropertyType" - Determina o tipo da minha propriedade.
"_MyProperty" - A propriedade com seus atributos em si, de acordo com o tipo escolhido em "_MyPropertyType".

Consegui criar "_MyProperty" de acordo com o escolhido em "_MyPropertyType", também consegui gravar as alterações no arquivo ".dfm", porém tenho problemas em relação ao "Object Inspector".

* Primeiro problema:

Quando mudo o valor da propriedade "_MyPropertyType", o valor de "_MyProperty" é criado corretamente, porém o "Object inspector" fica desatualizado, com os valores da propriedade escolhida anteriormente. Se eu selcionar a aba "Events" do "Object inspector" e selecionar novamente a aba "Properties" do "Object inspector", a propriedade "_MyProperty" é atualiza e aparece corretamente. Seria necessário que o "Object inspector" atualizasse a visualização das propriedades corretamente assim que eu mudasse o valor da propriedade "_MyPropertyType" instantaneamente, sem que eu precise mudar de aba no "Object inspector".

* Segundo problema

O tipo da minha propriedade "_MyProperty" (TMyProperty), possui além de propriedades comuns, também eventos. Esses eventos não são exibidos no "Object inspector". Gostaria que esses eventos fossem mostrados de maneira agrupada assim como as propriedades.


Li um artigo que mostra algo parecido com o que quero fazer, porém não soube aplicar.

"Custom Component Editors in Delphi - #2 - Sub-events and Sub-properties"
[url]http://edn.embarcadero.com/article/32956[/url]

Abaixo segue o código do que pretendo fazer, é bem simples:


unit UMyComponent;

interface

uses
  System.SysUtils, System.Classes, Vcl.Controls, Vcl.ExtCtrls;

type

  { EMyPropertyType }

  EMyPropertyType = (ptTypeA, ptTypeB);

  { TMyProperty }

  TMyProperty = class(TPersistent);

  { TMyPropertyA }

  TMyPropertyA = class(TMyProperty)
  private
    FIntegerPropertyA: integer;
    FEventPropertyA: TNotifyevent;
    FStringPropertyA: string;
  public
    procedure Assign(Source: TPersistent); override;
    procedure AssignTo(Dest: TPersistent); override;
  published
    property StringPropertyA : string read FStringPropertyA write FStringPropertyA;
    property IntegerPropertyA : integer read FIntegerPropertyA write FIntegerPropertyA;
    property EventPropertyA : TNotifyevent read FEventPropertyA write FEventPropertyA;
  end;

  { TMyPropertyB }

  TMyPropertyB = class(TMyProperty)
  private
    FDoubleProperty: Double;
    FEventPropertyB: TNotifyevent;
    FBooleanPropertyB: boolean;
  public
    procedure Assign(Source: TPersistent); override;
    procedure AssignTo(Dest: TPersistent); override;
  published
    property BooleanPropertyB : boolean read FBooleanPropertyB write FBooleanPropertyB;
    property DoublePropertyB : Double read FDoubleProperty write FDoubleProperty;
    property EventPropertyB : TNotifyevent read FEventPropertyB write FEventPropertyB;
  end;

  { TMyComponent }

  TMyComponent = class(TCustomPanel)
  private
    { Private declarations }
    FMyPropertyType: EMyPropertyType;
    FMyProperty: TMyProperty;
    procedure DestroyMyProperty;
    procedure CreateMyProperty(const pMyPropertyType : EMyPropertyType);
    procedure SetMyProperty(const Value: TMyProperty);
    procedure SetMyPropertyType(const Value: EMyPropertyType);
  protected
    { Protected declarations }
  public
    { Public declarations }
    constructor Create;
    destructor Destroy; override;
  published
    { Published declarations }
    property _MyPropertyType : EMyPropertyType read FMyPropertyType write SetMyPropertyType;
    property _MyProperty : TMyProperty read FMyProperty write SetMyProperty;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('SubPropertyComponent', [TMyComponent]);
end;

{ TMyPropertyA }

procedure TMyPropertyA.Assign(Source: TPersistent);
begin
     if (Source is TMyPropertyA) then
     begin
          Self.StringPropertyA  := TMyPropertyA(Source).StringPropertyA;
          Self.IntegerPropertyA := TMyPropertyA(Source).IntegerPropertyA;
          Self.EventPropertyA   := TMyPropertyA(Source).EventPropertyA;
     end
     else
     begin
          inherited;
     end;
end;

procedure TMyPropertyA.AssignTo(Dest: TPersistent);
begin
     if (Dest is TMyPropertyA) then
     begin
          TMyPropertyA(Dest).StringPropertyA  := Self.StringPropertyA;
          TMyPropertyA(Dest).IntegerPropertyA := Self.IntegerPropertyA;
          TMyPropertyA(Dest).EventPropertyA   := Self.EventPropertyA;
     end
     else
     begin
          inherited;
     end;
end;

{ TMyPropertyB }

procedure TMyPropertyB.Assign(Source: TPersistent);
begin
     if (Source is TMyPropertyB) then
     begin
          Self.BooleanPropertyB := TMyPropertyB(Source).BooleanPropertyB;
          Self.DoublePropertyB  := TMyPropertyB(Source).DoublePropertyB;
          Self.EventPropertyB   := TMyPropertyB(Source).EventPropertyB;
     end
     else
     begin
          inherited;
     end;
end;

procedure TMyPropertyB.AssignTo(Dest: TPersistent);
begin
     inherited;
     if (Dest is TMyPropertyB) then
     begin
          TMyPropertyB(Dest).BooleanPropertyB := Self.BooleanPropertyB;
          TMyPropertyB(Dest).DoublePropertyB  := Self.DoublePropertyB;
          TMyPropertyB(Dest).EventPropertyB   := Self.EventPropertyB;
     end
     else
     begin
          inherited;
     end;
end;

{ TMyComponent }

constructor TMyComponent.Create;
begin
     CreateMyProperty(FMyPropertyType);
end;

destructor TMyComponent.Destroy;
begin
     DestroyMyProperty;
     inherited;
end;

procedure TMyComponent.CreateMyProperty(const pMyPropertyType: EMyPropertyType);
begin
     DestroyMyProperty;
     case pMyPropertyType of
      ptTypeA : FMyProperty := TMyPropertyA.Create;
      ptTypeB : FMyProperty := TMyPropertyB.Create;
     end;
end;

procedure TMyComponent.DestroyMyProperty;
begin
     if Assigned(FMyProperty) then
     begin
          FreeAndNil(FMyProperty);
     end;
end;

procedure TMyComponent.SetMyProperty(const Value: TMyProperty);
begin
     FMyProperty.Assign(Value);
end;

procedure TMyComponent.SetMyPropertyType(const Value: EMyPropertyType);
begin
     FMyPropertyType := Value;
     CreateMyProperty(FMyPropertyType);
end;

end.

Gabriel Omizollo

Gabriel Omizollo

Curtidas 0
POSTAR