Текущий архив: 2003.08.04;
Скачать: CL | DM;
Вниз
Создание свойств типа Найти похожие ветки
← →
Borealis (2003-07-14 23:13) [0]У моего компонента есть объектное свойство. Когда оно происходит от класса TPersistent всё прекрасно работает, но если оно наследуется от TComponent (или позже), то подсвойства, почему-то, перестают записыватся в dfm-файл.
Наверно я смутно объяснил, поэтому вот пример:
...
type
TMyColors = class(TPersistent)
private
FColor1: TColor;
FColor2: TColor;
published
property Color1: TColor read FColor1 write FColor1;
property Color2: TColor read FColor2 write FColor2;
end;
TSuperPuperComponent = class(TComponent)
private
FColors: TMyColors;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property Colors: TMyColors read FColors write FColors;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents("Samples", [TSuperPuperComponent]);
end;
{ TSuperPuperComponent }
constructor TSuperPuperComponent.Create(AOwner: TComponent);
begin
inherited;
FColors:=TMyColors.Create;
end;
destructor TSuperPuperComponent.Destroy;
begin
FColors.Free;
inherited;
end;
...
В таком варианте всё работает, но если в верхней строке: TMyColors = class(TPersistent), TPersistent заменить на TComponent (и подправить конструктор), то подсвойста Color1 и Color2, свойства Colors, компонента TSuperPuperComponent не записываются в dfm-файл.
Что же мне сделать, что-бы эти свойства записывались?
← →
Rouse_ © (2003-07-15 01:50) [1]А зачем TComponent для данной реализации?
Может быть смысл шире?
Желаю успехов
← →
Юрий Зотов © (2003-07-15 04:42) [2]По умолчанию свойство типа TComponent среда считает ссылкой на внешний компонент, поэтому она записывает только саму эту ссылку (считая, что компонент, на который она ссылается и так уже где-то записывается).
Чтобы записывалась не ссылка, а сам компонент, нужно в классе TSuperPuperComponent заместить метод DefineProperties, а в нем определить методы чтения и записи свойства Colors. Ну и, конечно, написать сами эти методы. Примеры см.в VCL.
← →
Borealis (2003-07-20 10:55) [3]> Rouse_ © (15.07.03 01:50)
> А зачем TComponent для данной реализации?
> Может быть смысл шире?
Совершенно верно. В данной реализации от TComponent больше вреда чем пользы. Данный пример показывает, так сказать, корень зла - TPersistent и любые его потомки (кроме TComponent) ведут себя вполне адекватно, но не TComponent и его потомки. На самом деле, моя компонента должна вобрать в себя несколько (уже готовых) компонент, сама же их создавать, освобождать, отображать в инспекторе объектов, позволять редактировать (в том же инспекторе объектов) любые свойства этих компонент (но не позволять подменять сами компоненты на похожие уже лежащие на форме!), ну и естественно сохранять изменения в "*.dfm"-файле в виде "объект в объекте" (то есть как с TPersistent).
> Юрий Зотов © (15.07.03 04:42)
> ...
> нужно в классе TSuperPuperComponent заместить метод DefineProperties
Это единственный выход? Может есть более естественный способ избавиться от этого глюка (как я его называю :), скажем както зарегистрировать эти свойства чтобы они считались внутренними объектами (а значит подлежащими сохранению в "*.dfm"-файле)?
Если же всё же это единственный выход, то как это реализовать? Я уже весь извёлся - перепробовал все методы типа ReadXXX, WriteXXX у TWriter и TReader - все прекрасно работают кроме ReadComponent и WriteComponent! На все мои эксперименты Delphi говорит или "Stream read error", или "Access violation...", или вобще молча выгружается.
Где ошибка в нижеприведённом варианте?
procedure TSuperPuperComponent.LoadCompProperty(Reader: TReader);
begin
Reader.ReadComponent(FColors);
end;
procedure TSuperPuperComponent.StoreCompProperty(Writer: TWriter);
begin
Writer.WriteComponent(FColors);
end;
procedure TSuperPuperComponent.DefineProperties(Filer: TFiler);
begin
inherited;
Filer.DefineProperty("Colors", LoadCompProperty, StoreCompProperty, True);
end;
← →
Романов Р.В. © (2003-07-20 11:14) [4]Есть способ проще начиная с 6 дельфи, тока я его не помню :)) (т.к. пользуюсь D5).
Суть его в том что у вложенного компонента устанавливается специальный флаг кажелся в свойстве ComponentStyle, после этого компонент сохраняется в dfm его владельцем.
PS: В TComponent по моему появился новый метод который устанавливает это свойство.
← →
Borealis (2003-07-20 11:50) [5]
> Романов Р.В. © (20.07.03 11:14)
> Есть способ проще начиная с 6 дельфи...
Ура! Ура! Ты гений! :))
Действительно в D6 у класса TComponent появилось новое свойство ComponentStyle, и метод SetSubComponent как раз решающий мою проблему :)
Достаточно в конструкторе сказать:
constructor TSuperPuperComponent.Create(AOwner: TComponent);
begin
inherited;
FColors:=TMyColors.Create(Self);
FColors.SetSubComponent(True);
end;
И опля: свойство Colors уже сохраняется в dfm-файле :)
ps. Уже ради спортивного интереса мне всё таки интересно почему у меня не заработали WriteComponent и ReadComponent?
Страницы: 1 вся ветка
Текущий архив: 2003.08.04;
Скачать: CL | DM;
Память: 0.48 MB
Время: 0.014 c