Конференция "Компоненты" » Что то странно ведет себя потомок TPersistent
 
  • Kolan © (06.05.07 22:57) [0]
    Есть простой класс:
     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.

    Что-то наверно я упустил, что?
  • {RASkov} © (06.05.07 23:16) [1]
    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 нет этой информации....
  • {RASkov} © (06.05.07 23:29) [2]
    Или вот такой вариант(если не хочется конструктор делать)
    property Visible: Boolean read FVisible write FVisible stored True default True;
    stored True - принудительно запишет значение в DFM....
  • Kolan © (06.05.07 23:30) [3]
    > И IDE думает, что у тебя в конструкторе FVisible приравниватся
    > к True,

    Ааа, понятно. Благодарю все работает :)
  • Kolan © (06.05.07 23:31) [4]
    > stored

    Я о такой дерективе и незнал, благодарю. Остановился на конструкторе.
  • Юрий Зотов © (07.05.07 00:26) [5]
    И еще:

    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.
  • Kolan © (07.05.07 09:35) [6]
    > В методах Set вызвать Assign. У класса TActionState перекрыть
    > AssignTo

    А вот если честно, «сет» мне тут вообще не нужен. Т.к. объекты создаются самим компонентом. Пользователю нужно не объект изменять, а его свойства(Visible и т.д.). Но если не написать write …, то в инспекторе NextActionState, например, будет серым  и недоступным…
  • Юрий Зотов © (07.05.07 09:41) [7]
    > Kolan ©   (07.05.07 09:35) [6]

    > А вот если честно, «сет» мне тут вообще не нужен. Т.к. объекты
    > создаются самим компонентом. Пользователю нужно не объект изменять, а
    > его свойства(Visible и т.д.).

    А если СОВСЕМ честно, то ИМЕННО для этого Set и нужен - чтобы пользователь НЕ МОГ изменить САМ объект, а мог изменить ТОЛЬКО его свойства.
  • Kolan © (07.05.07 09:52) [8]
    > чтобы пользователь НЕ МОГ изменить САМ объект

    Да, действительно :)


    > В методах Set вызвать Assign. У класса TActionState перекрыть
    > AssignTo.

    Пошел сделаю :о)
  • Kolan © (07.05.07 10:00) [9]
    Итак в сеттере я пишу:
    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); {Delphi}
    [C++]B->AssignTo(A); // C++



    Так а почему именно AssignTo перекрывать?

    2. А что я пишу тут:
    procedure TActionState.AssignTo(Dest: TPersistent);
    begin
     inherited;

    end;


    ?
  • Kolan © (07.05.07 10:06) [10]
    > А что я пишу тут:

    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;



    Так?
  • Юрий Зотов © (07.05.07 12:08) [11]
    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;
  • Kolan © (07.05.07 14:37) [12]
    Благодарю. Но вопрос остался:
    «Так а почему именно AssignTo перекрывать?»


    а не Assign?
  • DimaBr © (07.05.07 15:00) [13]
    Принципиально - значения не имеет если не рассматривать тот вариант, что при копировании должны быть известны типы.

    Например как скопировать данные в стандартную кнопку ??? Ведь в коде TButton ничего не известно о вашем контроле.

    Button1.Assign(MyControl);
  • Юрий Зотов © (07.05.07 15:12) [14]
    > Kolan ©   (07.05.07 14:37) [12]

    Дефолтный Assign вызывает AssignTo, а дефолтный AssignTo генерит исключение.

    Поэтому, если перекрыть Assign, то вызов AssignTo ВСЕГДА даст исключение. А нам ВСЕГДА не надо, нам надо чтобы исключение возникало только тогда, когда операция действительно не может быть выполнена.

    Если же перекрыть AssignTo, то и при вызове Assign, и при вызове AssignTo операция будет выполнена, если она вообще может быть выполнена. А исключение возникнет только тогда, когда действительно не может.

    Что и требуется.
  • Kolan © (07.05.07 15:23) [15]
    Усе понял. Благодарю.
 
Конференция "Компоненты" » Что то странно ведет себя потомок TPersistent
Есть новые Нет новых   [134428   +41][b:0.008][p:0.002]