-
Есть простой класс: TStepNotifyEvent = procedure (Sender: TWizzardStep) of object;
TActionState = class(TPersistent)
strict private
FVisible: Boolean;
FEnabled: Boolean;
FChecked: Boolean;
FCaption: string;
published
property Visible: Boolean read FVisible write FVisible default True;
property Enabled: Boolean read FEnabled write FEnabled default True;
property Checked: Boolean read FChecked write FChecked default False;
property Caption: string read FCaption write FCaption;
end; его экземпляры используются в другом классе published
property NextActionState: TActionState read FNextActionState write
FNextActionState;
property PreviousActionState: TActionState read FPreviousActionState write
FPreviousActionState;
property CancelActionState: TActionState read FCancelActionState write
FCancelActionState;
end; этот класс их и создаёт: FNextActionState := TActionState.Create;
FNextActionState.Caption := rsNext; В дизайн тайме назначаю, например Visible = True, а в ран тайме там False. Что-то наверно я упустил, что?
-
TActionState = class(TPersistent)
........
FVisible: Boolean;
published
constructor Create(); virtual;
property Visible: Boolean read FVisible write FVisible default True;
...........
end;
constructor TActionState.Create();
begin
FVisible:=True;
end; или убери эту дерективу из описания свойства. тогда конструктор не нужен. деректива default не выставляет свойству значение которое указывается за этой дерективой, оно нужно для ИнспОбъек. А у тебя > В дизайн тайме назначаю, например Visible = True
И IDE думает, что у тебя в конструкторе FVisible приравниватся к True, и поэтому она не сохраняет это свойство в dfm > а в ран тайме там False.
А как инициализируются переменные по умолчанию? ведь в dfm нет этой информации....
-
Или вот такой вариант(если не хочется конструктор делать) property Visible: Boolean read FVisible write FVisible stored True default True; stored True - принудительно запишет значение в DFM....
-
> И IDE думает, что у тебя в конструкторе FVisible приравниватся > к True,
Ааа, понятно. Благодарю все работает :)
-
> stored
Я о такой дерективе и незнал, благодарю. Остановился на конструкторе.
-
И еще:
published
property NextActionState: TActionState read FNextActionState write
SetNextActionState;
property PreviousActionState: TActionState read FPreviousActionState write
SetPreviousActionState;
property CancelActionState: TActionState read FCancelActionState write
SetCancelActionState;
end;
В методах Set вызвать Assign. У класса TActionState перекрыть AssignTo.
-
> В методах Set вызвать Assign. У класса TActionState перекрыть > AssignTo
А вот если честно, «сет» мне тут вообще не нужен. Т.к. объекты создаются самим компонентом. Пользователю нужно не объект изменять, а его свойства(Visible и т.д.). Но если не написать write
, то в инспекторе NextActionState, например, будет серым и недоступным
-
> Kolan © (07.05.07 09:35) [6]
> А вот если честно, «сет» мне тут вообще не нужен. Т.к. объекты > создаются самим компонентом. Пользователю нужно не объект изменять, а > его свойства(Visible и т.д.).
А если СОВСЕМ честно, то ИМЕННО для этого Set и нужен - чтобы пользователь НЕ МОГ изменить САМ объект, а мог изменить ТОЛЬКО его свойства.
-
> чтобы пользователь НЕ МОГ изменить САМ объект
Да, действительно :)
> В методах Set вызвать Assign. У класса TActionState перекрыть > AssignTo.
Пошел сделаю :о)
-
Итак в сеттере я пишу: procedure TWizzardStep.SetNextActionState(const Value: TActionState);
begin
FNextActionState.Assign(Value);
end; Так? Возникло два вопроса: 1. Поясните плз про Assign и AssignTo. В справке написано: if A knows how to handle B, then it does so and returns. If A doesn’t know how to handle B’s type, execution will trickle to the TPersistent version of Assign, which calls:
[Delphi]B.AssignTo(A);
[C++]B->AssignTo(A);
Так а почему именно AssignTo перекрывать? 2. А что я пишу тут: procedure TActionState.AssignTo(Dest: TPersistent);
begin
inherited;
end; ?
-
> А что я пишу тут:
procedure TActionState.AssignTo(Dest: TPersistent);
var
TempState: TActionState;
begin
inherited;
TempState := (Dest as TActionState);
FVisible := TempState.Visible;
FEnabled := TempState.Enabled;
FChecked := TempState.Checked;
FCaption := TempState.Caption;
end; Так?
-
procedure TActionState.AssignTo(Dest: TPersistent); begin if Dest is TActionState then with TActionState(Dest) do begin Visible := Self.Visible; Enabled := Self.Enabled; Checked := Self.Checked; Caption := Self.Caption; end else inherited end;
-
Благодарю. Но вопрос остался: «Так а почему именно AssignTo перекрывать?» а не Assign?
-
Принципиально - значения не имеет если не рассматривать тот вариант, что при копировании должны быть известны типы.
Например как скопировать данные в стандартную кнопку ??? Ведь в коде TButton ничего не известно о вашем контроле.
Button1.Assign(MyControl);
-
> Kolan © (07.05.07 14:37) [12]
Дефолтный Assign вызывает AssignTo, а дефолтный AssignTo генерит исключение.
Поэтому, если перекрыть Assign, то вызов AssignTo ВСЕГДА даст исключение. А нам ВСЕГДА не надо, нам надо чтобы исключение возникало только тогда, когда операция действительно не может быть выполнена.
Если же перекрыть AssignTo, то и при вызове Assign, и при вызове AssignTo операция будет выполнена, если она вообще может быть выполнена. А исключение возникнет только тогда, когда действительно не может.
Что и требуется.
-
Усе понял. Благодарю.
|