Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.06.26;
Скачать: CL | DM;

Вниз

Как сохранить список   Найти похожие ветки 

 
REA ©   (2003-06-11 10:20) [0]

Не могу вот вспомнить как сохранить список объектов компонента. Все объекты наследники TPersistent, но не одного типа - TCollection не подойдет. Если кто уже делал, подскажите как лучше. Сам список сейчас TObjectList не published property.


 
Digitman ©   (2003-06-11 10:53) [1]

см.
TPersistent.DefineProperties()
TPersistent.DefineProperty()
TPersistent.DefineBinaryProperty()
TWriter.WriteListBegin/End
TReader.ReadListBegin/End


 
REA ©   (2003-06-11 11:20) [2]

Да это я видел, но мысль голову не посетила - было бы проперти - нет проблем. Причем сам родительский объект TCollectionItem - и в список его объектов не запихать. Посмотреть что ли как в TComponent сделано?


 
REA ©   (2003-06-11 11:32) [3]

Спасибо за подсказку с WriteList.


 
Digitman ©   (2003-06-11 11:41) [4]


> REA



> было бы проперти - нет проблем


на то и вышеприведенные методы, чтобы определить дополнительные (неопубликованные) св-ва, требуемые к сохранению/восстановлению наряду с автоматически сохраняемыми опубликованными св-вами


> список его объектов не запихать


это почему же ? см. TReader.ReadCollection, TWriter.WriteCollection

цитата :

ReadCollection is a helper method used by other reader methods to read a tagged collection value at the current reader Position. ReadCollection iterates through items in a collection so that each item in a collection property has an opportunity to stream out its properties. This method does not write out the number of items and the collection indices, because a user can add or delete items.


 
REA ©   (2003-06-11 11:50) [5]

Я имел ввиду, что CollectionItem не объект и у него нет свойства Objects. Сейчас как раз гляжу:
procedure TWriter.WriteCollection(Value: TCollection);
var
I: Integer;
OldAncestor: TPersistent;
begin
OldAncestor := Ancestor;
Ancestor := nil;
try
WriteValue(vaCollection);
if Value <> nil then
for I := 0 to Value.Count - 1 do
begin
WriteListBegin;
WriteProperties(Value.Items[I]);
WriteListEnd;
end;
WriteListEnd;
finally
Ancestor := OldAncestor;
end;
end;
Там механизм немного другой - у меня объекты разных классов. Он же при загрузке делает Add и потом ReadProperties. Тут такой фокус не пройдет.


 
Digitman ©   (2003-06-11 12:03) [6]


> CollectionItem не объект


как это "не объект" ? это же наследник TPersistent !

значит, при сохранении коллекции для каждого ее элемента будет австоматически вызван метод DefineProperties, который можно переопределить для каждого конкретного класса-наследника TCollectionItem.

И - далее : если экземпляр-наследник TCollectionItem хочет при сохранении его самого сохранить и свои собственные списки или поля (в кач-ве собственных св-в), то делает он это точно так же !


 
REA ©   (2003-06-11 12:13) [7]

в смысле не компонет. ну не важно.
У меня не TCollectionItem нужно сохранять, с этим нет проблем, а проблемы с тем что он содержит, а он содержит список разнородных объектов наследников TPersistent (который кстати может расширяться за счет внешних Package plugin-ов). Метода WritePersistentObject нет, поэтому видимо придется наследовать все от TComponent и писать в список WriteComponent.


 
Digitman ©   (2003-06-11 12:23) [8]


> содержит список разнородных объектов наследников TPersistent
>


для каждого из них ты волен "вручную" вызвать DefineProperties() !
А у ж каждый из них сам запишет/прочитает свои индивидуальные св-ва


 
REA ©   (2003-06-11 12:28) [9]

А как объекты то сами конструировать при чтении? Нужно же его класс знать. Опять же вручную это морока. Список классов заранее не известен. В TCollection класс определен (Он даже его не хранит видимо в ресурсе), а TComponent берет из списка зарегистрированных классов.


 
Digitman ©   (2003-06-11 12:50) [10]


> Нужно же его класс знать


при записи в поток записывай имя класса самым первым св-вом


> Опять же вручную это морока


Иных способов нет - тольуо "вручную", единожды определив поведение persistent-экз-ра при вызове его метода DefineProperties()


> Список классов заранее не известен


сделай так, чтобы он был известен
каждый из классов в списке зарегистрируй
иначе задача (в том виде как ты ее задумал) нерешаема


> TComponent берет из списка зарегистрированных классов


ничто не мешает класс зарегистрировать !
лишь бы существовала его декларация.


 
REA ©   (2003-06-11 13:02) [11]

В общем для данного случая мне проще унаследовать не от TPersistent, а от TComponent. Он сам имя класса запишет. DefineProperties мне впрочем тоже понадобятся - сами эти классы в свою очередь содержат данные.

>ничто не мешает класс зарегистрировать !
Это обязательно.

Спасибо!


 
Digitman ©   (2003-06-11 13:26) [12]

в целом - да
TComponent как наследник несколько облегчит рутинную работу
Но регистрация, конечно, необходима, только уже не класса, а компонента (TRegisterComponent[s])

присмотрись еще к TComponent.GetChildren()
в кач-ве достаточно разумной альтернативы можно отказаться от использования коллекций в пользу св-ва списка TComponent.Components[] - опять же уменьшение рутинной работы ! Раз TComponent уже реализует список (и управление им) компонентов, для которых он является владельцем, грех им не воспользоваться)

пример :

TMyObject = class(TComponent)
...
protected
procedure GetChildren(Proc: TGetChildProc); override;
...
end;
...
procedure TMyObject.GetChildren(Proc: TGetChildProc);
var
i: Integer;
begin
for i:= 0 to ComponentCount - 1 do
Proc(Components[i]);
end;

в результате при сохранении/восстановлении некоего компонента автоматически будут сохранены/восстановлены все его "дети"


 
REA ©   (2003-06-11 14:30) [13]

Я в курсе. Я так уже делал, но на этот раз структура получилась такая: Компонент - Документ (тоже компонент) - Документ с данными (наследник) - Данные Root (Collection) - Блоки данных (CollectionItems) - Поля данных (TComponent по видимому) - Собственно Данные. И все это безобразие нужно сохранять.



Страницы: 1 вся ветка

Текущий архив: 2003.06.26;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.074 c
1-84192
AtoL2k2
2003-06-12 09:56
2003.06.26
Две даты


14-84586
DMN
2003-06-09 01:35
2003.06.26
Дозвон?


1-84308
ASt
2003-06-15 02:49
2003.06.26
Непонятная ошибка при компиляции


1-84149
Bosso
2003-06-11 09:57
2003.06.26
Как бороть баг с 300-ми кнопками?


3-83993
DBDev
2003-05-30 12:32
2003.06.26
Знатоки, помогите с процедурой - не редактируется!