-
Надо созранять TCollection в dfm, причем только те изменения которые были сделаны на этапе проектирования, а не все.
Если ставлю published то сохраняються все изменения включая и Run-Timе, а если читаю посредством defineproperty то возникает ошибка чтения при обращении к ReаdCollection. В dfm WriteCollection пишет правильно
-
Что о вы намудрили. Как в Run-Timе вы сохраняете в dfm. Или это хранилище формы ??? Приведите код, будет легче помочь.
-
Про Run-Time я и сам .... Но запустив приложение и потом посмотрев в dfm обнаружил изменения сделаные "в живую",а код примерно такой
TItemCol = class(TCollectionItem)
published
property Caption: string read FCaption write SetCaption;
property Width: integer read FWidth write SetWidth default 50;
end;
TCols = class(TCollection)
property Items[Index: Integer]: TGridColumn read GetItem write SetItem;
end;
TMyClass = class(TCustomControl)
published
property Columns: TCols read FListColumns write SetListColumns;
end;
после этого я и попробывал сделать сохранение с помощью defineproperty
но при чтении говорит ошибка
-
Прошу пардону, ошибочка. Вместо TGridColumn TItemCol
-
Сохранять через DefineProperty судя по всему вам ещё рано, да и нужно ли ?
В вашем примере свойство Caption будет сохраняться при значение отличного от пустой строки а свойство Width при значенни отличного от 50.
А вам как нужно ?
-
Нет это как надо сохраняется во всех вариантах. Надо чтобы изменения вносились только в design-time во время работы с objectinspector, но что бы изменения в run-time не сохранялись, например как в ListView columns. Например добавляю элементы в коллекцию в design-time это должно сохраниться, а добавляю в run-time не должно. а сохранение и восстановление элементов коллекции происходит правильно. Странно все это умом понимаю что должно работать как надо, а вот нет.
-
А в Run-Time и не будет сохраняться
-
Может у вас какой нибудь сторонний компонент загружает и сохраняет свойства ???
-
Где-то я лоханулся но однако как всегда просто все почистил перекомпилил
и все как надо заработало. Однако у меня вопрос а почему через DefineProperty мне рано. Вот пользуясь случаем и пояснили бы когда использовать это надо а в каких нет. В кратце общими понятиями. Думаю не мне одному интересно будет. (Я с этим конечно сам разберусь, ни чего сложного там нет, но когда помогают легче, ведь ежли один построил второй завсегда сломать может)
-
А что тут объяснять ?
DefineProperty нужно для сохранения всего того что нельзя сохранить стандартными средствами. Например непублекуемые свойства или бинарные свойства (картинки неизестных форматов), масивы или специфические списки.
Конечно можно запретить стандартное сохранения и вручную сохранять те же свойства типа String или Integer через DefineProperty, но для этого придётся написать дополнительный код, а в часности три процедуры: чтение, сохранение, указание какими процедурами какое свойство обрабатывать.
Почему рано ? Разберитесть с простым сохранением с диррективами default, nodefault, stored.
-
> если читаю посредством defineproperty то возникает ошибка
> чтения при обращении к ReаdCollection
Открываем генофонд и видим там:
procedure TReader.ReadPropValue(Instance: TPersistent; PropInfo: Pointer);
..
begin
..
case PropType^.Kind of
..
tkClass:
case NextValue of
vaNil:
begin
ReadValue;
SetOrdProp(Instance, PropInfo, 0);
end;
vaCollection:
begin
ReadValue;
ReadCollection(TCollection(GetOrdProp(Instance, PropInfo)));
end
Вот и все чудеса.
-
Не рано, это точно, поскольку с этим знаком (просто клин в голове от работы и частично беспорядка в коде). А теперь по существу: 1: добавочный код это 12 строк стандартного практически кода это не накладные расходы ну конечно если это надо; 2: Допустим мне все таки пришлось сохранять TCollection writer пишем writer.writelistbegin; writecollection(collection); writelistend; reader пишем reader.readlistbegin; readcollection(collection); readlistend; Вопрос т.е. сcollection должна быть а) непубликуемым свойством либо иметь проперти риадонли либо stored False; б) коллекция должна быть создана в конструкторе. или какие-то варианты. я не понимаю почему не стало читать коллекцию.
-
> begin
> ReadValue; //пропускаем префикс vaCollection,
> записанный в стрим на этапе предшествующей записи коллекции
> в теле метода Writer.WriteCollection
Может я не прав но в dfm пишеться Collection = <> ну и если есть item`ы то прописываються сохраняемые поля Item`ов нет там префикса vaCollection
-
а если и был бы то его writecollection должна была прописать для совместимости
-
Для того чтобы сохрнять коллекцию самостоятельно нужно запретить сохранять её стандартными методами (непубликуемым свойством либо иметь проперти ReadOnly либо stored False)
> Может я не прав но в dfm пишеться Collection = <>
Не прав, достаточно кинуть на форму например THeaderControl и посмотреть в ресурс что получилось
object HeaderControl1: THeaderControl
Left = 0
Top = 0
Width = 688
Height = 17
DragReorder = False
Sections = <>
end
> коллекция должна быть создана в конструкторе, или какие-то варианты
Есть, например создавать коллекцию при первом к ней обращении
function GetCollection: TMyCollection;
begin
if not Assigned(fCollection) then fCollection := TMyCollection.Create(self, TMyCollectionItem);
Result := fCollection;
end;
Только для счего всё это, если стандартные средства прекрасно справляются с чтением и сохранением коллекции ?
-
> в dfm пишеться Collection = <>
В случае c dfm это и есть префикс
-
> DimaBr © (14.01.09 11:27) [14]
> Sections = <>
я про это и говорю (что Section что Collection) пишеться имя из defineproperty
> Есть, например создавать коллекцию при первом к ней обращении
> function GetCollection: TMyCollection;
> begin
> if not Assigned(fCollection) then fCollection := TMyCollection.
> Create(self, TMyCollectionItem);
> Result := fCollection;
> end;
>
> Только для счего всё это, если стандартные средства прекрасно
> справляются с чтением и сохранением коллекции ?
для чего надо? допустим что надо. но вот вопрос куда будет читаться коллекция если она не создана, а в readcollection она не создается
> Сергей М. © (14.01.09 11:34) [15]
>
> В случае c dfm это и есть префикс
но тогда Readcollection должна читать все нормально поскольку это имя проперти куда загружается коллекция
-
ЕНапример пишем
property myCollection: Tcollection read FMyCollection;
defineproperty: .... Filer.DefineProperty('myCollection', ReadData, WriteData, True);
WriteData: writecollection(FMyCollection); (обрамляя listbegin и listend)
ReadData: readcollection(FMyCollection); и вот тут вопросы
1. Должна быть коллекция создана до ReadData или нет
2. и должно быть указано FMyCollection или как-то еще
3. нужно обрамление из listbegin и listend или нет
-
Если не создавать в конструкторе а создавать в GetCollection, тогда нужно написать без префикса 'F'
WriteCollection(MyCollection);
Тогда произойдёт обращение к коллекции и на создастся
-
Вообще, мне кажется что мы толчём воду в ступе. Расскажите что вы имеете и что хотите получить. Так будет гораздо проще.
-
Если все остальное про ReadColeection правильно (с учетом последнего замечания) то все понятно, должно работать. Я обязательно попробую. Спасибо.