Конференция "Компоненты" » Проблемы с загрузкой TCollection из dfm [D7, WinXP]
 
  • vvv777 © (14.01.09 08:19) [0]
    Надо созранять TCollection в dfm, причем только те изменения которые были сделаны на этапе проектирования, а не все.
    Если ставлю published то сохраняються все изменения включая и Run-Timе, а если читаю посредством defineproperty то возникает ошибка чтения при обращении к ReаdCollection. В dfm WriteCollection пишет правильно
  • DimaBr © (14.01.09 09:03) [1]
    Что о вы намудрили. Как в Run-Timе вы сохраняете в dfm. Или это хранилище формы ??? Приведите код, будет легче помочь.
  • vvv777 © (14.01.09 09:56) [2]
    Про 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
    но при чтении говорит ошибка
  • vvv777 © (14.01.09 10:01) [3]
    Прошу пардону, ошибочка. Вместо TGridColumn TItemCol
  • DimaBr © (14.01.09 10:03) [4]
    Сохранять через DefineProperty судя по всему вам ещё рано, да и нужно ли ?
    В вашем примере свойство Caption будет сохраняться при значение отличного от пустой строки а свойство Width при значенни отличного от 50.
    А вам как нужно ?
  • vvv777 © (14.01.09 10:11) [5]
    Нет это как надо сохраняется во всех вариантах. Надо чтобы изменения вносились только в design-time во время работы с objectinspector, но что бы изменения в run-time не сохранялись, например как в ListView columns. Например добавляю элементы в коллекцию в design-time это должно сохраниться, а добавляю в run-time  не должно. а сохранение и восстановление элементов коллекции происходит правильно. Странно все это умом понимаю что должно работать как надо, а вот нет.
  • DimaBr © (14.01.09 10:18) [6]
    А в Run-Time и не будет сохраняться
  • DimaBr © (14.01.09 10:20) [7]
    Может у вас какой нибудь сторонний компонент загружает и сохраняет свойства ???
  • vvv777 © (14.01.09 10:21) [8]
    Где-то я лоханулся но однако как всегда просто все почистил перекомпилил
    и все как надо заработало. Однако у меня вопрос а почему через DefineProperty мне рано. Вот пользуясь случаем и пояснили бы когда использовать это надо а в каких нет. В кратце общими понятиями. Думаю не мне одному интересно будет. (Я с этим конечно сам разберусь, ни чего сложного там нет, но когда помогают легче, ведь ежли один построил второй завсегда сломать может)
  • DimaBr © (14.01.09 10:40) [9]
    А что тут объяснять ?
    DefineProperty нужно для сохранения всего того что нельзя сохранить стандартными средствами. Например непублекуемые свойства или бинарные свойства (картинки неизестных форматов), масивы или специфические списки.

    Конечно можно запретить стандартное сохранения и вручную сохранять те же свойства типа String или Integer через DefineProperty, но для этого придётся написать дополнительный код, а в часности три процедуры: чтение, сохранение, указание какими процедурами какое свойство обрабатывать.

    Почему рано ? Разберитесть с простым сохранением с диррективами default, nodefault, stored.
  • Сергей М. © (14.01.09 10:50) [10]

    > если читаю посредством 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; //пропускаем префикс vaCollection, записанный в стрим на этапе предшествующей записи коллекции в теле метода Writer.WriteCollection
               ReadCollection(TCollection(GetOrdProp(Instance, PropInfo))); //а теперь читаем собссно cfve rjkktrwb.
             end



    Вот и все чудеса.
  • vvv777 © (14.01.09 10:58) [11]
    Не рано, это точно, поскольку с этим знаком (просто клин в голове от работы и частично беспорядка в коде). А теперь по существу: 1: добавочный код это 12 строк стандартного практически кода это не накладные расходы ну конечно если это надо; 2: Допустим мне все таки пришлось сохранять TCollection  writer пишем writer.writelistbegin; writecollection(collection); writelistend; reader пишем reader.readlistbegin; readcollection(collection); readlistend; Вопрос т.е. сcollection должна быть а) непубликуемым свойством либо иметь проперти риадонли  либо stored False; б) коллекция должна быть создана в конструкторе. или какие-то варианты. я не понимаю почему не стало читать коллекцию.
  • vvv777 © (14.01.09 11:04) [12]

    > begin
    >            ReadValue; //пропускаем префикс vaCollection,
    >  записанный в стрим на этапе предшествующей записи коллекции
    > в теле метода Writer.WriteCollection


    Может я не прав но в dfm пишеться Collection = <> ну и если есть item`ы то прописываються сохраняемые поля Item`ов нет там префикса vaCollection
  • vvv777 © (14.01.09 11:06) [13]
    а если и был бы то его writecollection должна была прописать для совместимости
  • DimaBr © (14.01.09 11:27) [14]
    Для того чтобы сохрнять коллекцию самостоятельно нужно запретить сохранять её стандартными методами (непубликуемым свойством либо иметь проперти 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;



    Только для счего всё это, если стандартные средства прекрасно справляются с чтением и сохранением коллекции ?
  • Сергей М. © (14.01.09 11:34) [15]

    > в dfm пишеться Collection = <>


    В случае c dfm это и есть префикс
  • vvv777 © (14.01.09 12:32) [16]

    > 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 должна читать все нормально поскольку это имя проперти куда загружается коллекция
  • vvv777 © (14.01.09 12:41) [17]
    ЕНапример пишем
    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 или нет
  • DimaBr © (14.01.09 12:55) [18]
    Если не создавать в конструкторе а создавать в GetCollection, тогда нужно написать без префикса 'F'
    WriteCollection(MyCollection);


    Тогда произойдёт обращение к коллекции и на создастся
  • DimaBr © (14.01.09 12:57) [19]
    Вообще, мне кажется что мы толчём воду в ступе. Расскажите что вы имеете и что хотите получить. Так будет гораздо проще.
  • vvv777 © (14.01.09 13:05) [20]
    Если все остальное про ReadColeection правильно (с учетом последнего замечания) то все понятно, должно работать. Я обязательно попробую. Спасибо.
 
Конференция "Компоненты" » Проблемы с загрузкой TCollection из dfm [D7, WinXP]
Есть новые Нет новых   [134464   +62][b:0][p:0.002]