2013-05-27 15 views
0

У меня есть следующий компонент, который содержит свойство, полученное из пользовательского класса:значение свойства во время разработки, не отображается во время выполнения

unit MyComponentTest3; 

interface 

uses Windows, ExtCtrls,Classes,Controls; 

type 

    TMyClass3 = class 
    myString: string; 
    myNumber: double; 
    end; 

    TMyComponentTest3 = class(TCustomPanel) 
    private 
    FMyProperty: TMyClass3; 

    procedure SetMyProperty(Value: TMyClass3); 
    public 
    constructor Create(AOwner: TComponent); override; 
    destructor Destroy; override; 

    procedure SetMyPropertyPublic(AmyString: string; AmyNumber: double); 
    published 
    property MyProperty: TMyClass3 read FMyProperty write SetMyProperty; 
    end; 

procedure Register; 

implementation 


procedure Register; 
begin 
    RegisterComponents('MyComponents', [TMyComponentTest3]); 
end; 

{ TMyComponentTest3 } 

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

    FMyProperty:= TMyClass3.Create; 

end; 

destructor TMyComponentTest3.Destroy; 
begin 
    FMyProperty.Free; 

    inherited; 
end; 

procedure TMyComponentTest3.SetMyProperty(Value: TMyClass3); 
begin 
with FMyProperty do 
    begin 
    myString:= Value.myString; 
    myNumber:= Value.myNumber; 
    end; 
end; 

procedure TMyComponentTest3.SetMyPropertyPublic(AmyString: string; 
    AmyNumber: double); 
var 
    auxMyProperty: TMyClass3; 
begin 

    auxMyProperty:= TMyClass3.Create; 

    with auxMyProperty do 
    begin 
    myString:= AmyString; 
    myNumber:= AmyNumber; 
    end; 

    SetMyProperty(auxMyProperty); 

    auxMyProperty.Free; 

end; 

end. 

Он отлично работает, но когда я установил значение свойства во время разработки и запуска программы исчезают. Та же проблема я получаю, если я устанавливаю значения компонента, сохраняю все, и когда я загружаю значения, их больше нет ...

Я думаю, проблема в том, что я создаю экземпляр пользовательского класса для всех но я не уверен, и я не знаю, как обойти это. Кто-нибудь имеет представление о том, что я могу сделать?

+0

какой-либо причине не делать 'TMyClass3' запись вместо класса? –

+0

Это всего лишь простой пример, в моем реальном коде это сложнее ... – Felipe

+2

@J ... Независимо от того, насколько он сложный, ключевым фактором является то, хотите ли вы семантику значения или ссылочного присвоения. –

ответ

4

TMyClass3 необходимо исчислить от TPersistent для обеспечения возможности потокового в DFM. Он также должен опционально переопределять виртуальный метод Assign(), который затем сможет вызвать SetMyProperty().

Попробуйте это:

unit MyComponentTest3; 

interface 

uses 
    Windows, ExtCtrls, Classes, Controls; 

type 

    TMyClass3 = class(TPersistent) 
    private 
    FMyString: string; 
    FMyNumber: double; 
    public 
    procedure Assign(Source: TPersistent); override; 
    published 
    property myString: string read FMyString write FMyString; 
    property myNumber: double read FMyNumber write FMyNumber; 
    end; 

    TMyComponentTest3 = class(TCustomPanel) 
    private 
    FMyProperty: TMyClass3; 

    procedure SetMyProperty(Value: TMyClass3); 
    public 
    constructor Create(AOwner: TComponent); override; 
    destructor Destroy; override; 

    procedure SetMyPropertyPublic(AmyString: string; AmyNumber: double); 
    published 
    property MyProperty: TMyClass3 read FMyProperty write SetMyProperty; 
    end; 

procedure Register; 

implementation 


procedure Register; 
begin 
    RegisterComponents('MyComponents', [TMyComponentTest3]); 
end; 

{ TMyClass3 } 

procedure TMyClass3.Assign(Source: TPersistent); 
begin 
    if Source is TMyClass3 then 
    begin 
    with TMyClass3(Source) do 
    begin 
     Self.FMyString := myString; 
     Self.FMyNumber := myNumber; 
    end; 
    end else 
    inherited; 
end; 

{ TMyComponentTest3 } 

constructor TMyComponentTest3.Create(AOwner: TComponent); 
begin 
    inherited; 
    FMyProperty := TMyClass3.Create; 
end; 

destructor TMyComponentTest3.Destroy; 
begin 
    FMyProperty.Free; 
    inherited; 
end; 

procedure TMyComponentTest3.SetMyProperty(Value: TMyClass3); 
begin 
    FMyProperty.Assign(Value); 
end; 

procedure TMyComponentTest3.SetMyPropertyPublic(AmyString: string; AmyNumber: double); 
begin 
    with MyProperty do 
    begin 
    myString := AmyString; 
    myNumber := AmyNumber; 
    end; 
end; 

end. 
+0

Ничего ... похоже, что он не достигает этой процедуры назначения, значения все еще не отображаются во время выполнения, и я помещаю сообщение внутри процедуры присваивания, чтобы проверить, и он никогда не показывает его. – Felipe

+1

'Assign()' is not будет вызван, потому что средство настройки свойств не вызывается во время потоковой передачи DFM. Это предложение состояло в том, чтобы просто очистить ваш сеттер и реализовать лучшую инкапсуляцию. Ваша проблема - это что-то другое, но вам все равно нужно начинать с основ - извлекать из «TPersistent», сами создавать сами значения значений и т. Д. То, что вы описали, предполагает, что значения не сохраняются в DFM, чтобы начать с , поэтому нет необходимости загружаться позже. –

+0

спасибо за помощь, я попробую еще раз ваши предложения. – Felipe

0
constructor TMyComponentTest3.Create(AOwner: TComponent); 
begin 
    inherited; 
    FMyProperty := TMyClass3.Create; 
    FMyProperty.SetSubComponent(True); 
end; 
Смежные вопросы