我做了一个类似,TCollection这样的容器类,设计时,一点问题都没有,里面的TList对象可以保存我设计的对象。但是,运行的时候,TList保存的对象就消失了,为何???需要什么注册函数吗?即便不需要TCollection这样的也无所谓,TFields这样的也行。

解决方案 »

  1.   

    我就是怎么都搞不定,我不才来这里问嘛。TCollectionItem要求的类类型是固定的,不符合需要,TFields就是因为这个才专门搞得一个类,TCollection和TFields设计时,运行时保存的内容都存在。写一个当然很简单,但是我现在就是不知道怎么保存设计时的内容。运行时内容就消失了。
      

  2.   

    也就是说,TCollection的FItems能够保存内容,不管设计时还是运行时都可以。但是我自己设计的类的FItems,设计时是有的,但是运行时就空了。:(我不知道为什么,HubDog的书根本没有写,故国的根本就没有……
      

  3.   

    把你的代码贴出来让俺们Look....look啊
      

  4.   

    reallike,设计时候编辑的东西,都存在DFM里面..你的容器类继承于TPersistent吗?重载了Assign方法吗?
      

  5.   

    reallike,有些东西说穿并不希奇.呵呵.看看这儿的代码.TReader.ReadPropValue看见了那一长串难看的CASE了吗?
    .............
        tkClass:
          case NextValue of
            vaNil:
              begin
                ReadValue;
                SetOrdProp(Instance, PropInfo, 0)
              end;
            vaCollection:
              begin
                ReadValue;
                ReadCollection(TCollection(GetOrdProp(Instance, PropInfo)));
              end
          else
            SetObjectIdent(Instance, PropInfo, ReadIdent);
          end;
    ...............
      

  6.   

    但是我不明白的是  TFields = class(TObject)本来是想仿照这个做的。但是为什么这个不行?
      

  7.   

    >但是我不明白的是
    >TFields = class(TObject)
    >本来是想仿照这个做的。但是为什么这个不行?说明你仿照得不对。^O^
    不过要存到DFM里,还是应该从TPersistent继承会比较简单一点,不然要自己处理一堆序列化的工作。
      

  8.   

    reallike,让我猜一下你问题出在哪儿。。TField 继承自TComponent,TComponent继承自TPersistent
    在字段编辑器编辑永久字段后,这些永久字段是会被加入TFORM1的published 属性,
    它们的串行化,看来是不依赖它们的容器TFields了。所以,它的TFields可以继承于TOBJECT,你的却没有成功。
      

  9.   

    TO:哈欠
    这样虽然TField被保存了,但TFields还是要自己实现序列化,否则TField的列表还是没有保存。
      

  10.   

    我想也是,运行时TFields保存的应该是用TFieldList进行初始化之后的。要不然FindField就找不到内容了。TForm1属性具有的TField应该是独立的。我想我也得建立一个列表了。老兄们,我做的类似这样  object ADOTable1: TADOTable
        Connection = ADOConnection1
        TableName = 'Customers'
        Left = 200
        Top = 90
      end
      object ADOTable1Region: TWideStringField
        FieldName = 'Region'
        Size = 15
      end
      object ADOTable1PostalCode: TWideStringField
        FieldName = 'PostalCode'
        Size = 10
      end是平级的关系,但是我现在需要这样的关系:  object ADOTable1: TADOTable
        Connection = ADOConnection1
        TableName = 'Customers'
        Left = 200
        Top = 90
        object ADOTable1Region: TWideStringField
          FieldName = 'Region'
          Size = 15
        end
        object ADOTable1PostalCode: TWideStringField
          FieldName = 'PostalCode'
          Size = 10
        end
      end这样也是TDataSet做到的,我不知道为什么做不到这种子集的关系。
      

  11.   

    TFields里面列表不是同TFields一起串行化的。
    而是在串行化TField的时候。。它的调用序列如下:TReader.ReadComponent
    TField.ReadState
    TField.SetDataSet
    。 
        if (ADataSet <> nil) and (FParentField = nil) then
        begin
          if FieldKind = fkAggregate then
            ADataSet.FAggFields.Add(Self) else
            ADataSet.FFields.Add(Self);//这儿把自己加进Fields去的。
        end;

    TFields.Add
      

  12.   

    另外,我还是不明白TCollection怎么把item保存到dfm中的。比如这个:  object ADODataSet1: TADODataSet
        FieldDefs = <
          item
            Name = 'ADODataSet1Field1'
          end
          item
            Name = 'ADODataSet1Field2'
          end
          item
            Name = 'ADODataSet1Field3'
          end>
        StoreDefs = True
        Left = 330
        Top = 150
      end怎么回事呢?这个是我最最不明白的一件事情。
      

  13.   

    娘的……TReader.ReadComponent
    TField.ReadState
    TField.SetDataSet要学的东西可是太多了……
      

  14.   

    TWideStringField.CREATE的时候,参数传入ADODataSet1为OWNER,
    串行化生成的就是你要的那样了:)
      

  15.   

    reallike,对象串行化是个大话题,就象一棵枝叶繁杂的大树,不过接近主干的地方,还是容易理解.
      

  16.   

    呵呵.REALLIKE,
    再刺激你一下,这是一个包含COLLECTION属性成员的COMPONENT,存入DFM的调用序列.TComponent.WriteState
    TWriter.WriteData
    TWriter.WriteProperties
    TWriter.WriteProperty
    WriteObjectProp
    WriteCollectionProp
    WriteCollection
    TWriter.WriteCollection
      

  17.   

    在设计期创建并保存到DFM中的好象不是TField吧,应该是TFieldDef,它是从TCollectionItem衍生来的。
      

  18.   

    to 短歌兄TFieldDef保存的是字段类型TFieldType,不是TField的东西。然后通过DefaultFieldClasses,这么一个数组得到类引用来建立字段的。
      

  19.   

    我知道为什么TField可以加在DataSet内了。procedure TField.ReadState(Reader: TReader);
    begin
      inherited ReadState(Reader);
      if Reader.Parent is TObjectField then
        ParentField := TObjectField(Reader.Parent)
      else if Reader.Parent is TDataSet then
        DataSet := TDataSet(Reader.Parent);
    end;DataSet做了他的Parent……
      

  20.   

    一天的研究,明白了很多。好多书籍都是大概地说了一下而已。包括Inside Vcl, 开发人员指南。可能几乎用不到写TComponent的持久化机制。介绍的一般都是TControl的再次谢谢哈欠老兄。