首页  编辑  

控件属性数据的保存

Tags: /超级猛料/VCL/Control.控件使用开发和第三方控件/属性编辑器/   Date Created:

有的时候,自己写一个自定义控件,有一些属性,不是Delphi的标准属性,那么如何能够保存这些属性呢?Kingron查看了一夜的帮助,终于发现了这些文字:

Creating properties

Storing and loading unpublished properties

Topic groups

By default, only published properties are loaded and saved with a component. However, it is possible to load and save unpublished properties. This allows you to have persistent properties that do not appear in the Object Inspector. It also allows components to store and load property values that Delphi does not know how to read or write because the value of the property is too complex. For example, the TStrings object can抰 rely on Delphi抯 automatic behavior to store and load the strings it represents and must use the following mechanism.

You can save unpublished properties by adding code that tells Delphi how to load and save your property抯 value.

To write your own code to load and save properties, use the following steps:

1        Create methods to store and load the property value.

To store and load unpublished properties, you must first create a method to store your property value and another to load your property value. You have two choices:

Create a method of type TWriterProc to store your property value and a method of type TReaderProc to load your property value. This approach lets you take advantage of Delphi抯 built-in capabilities for saving and loading simple types. If your property value is built out of types that Delphi knows how to save and load, use this approach.

       Create two methods of type TStreamProc, one to store and one to load your property抯 value. TStreamProc takes a stream as an argument, and you can use the stream抯 methods to write and read your property values.

For example, consider a property that represents a component that is created at runtime. Delphi knows how to write this value, but does not do so automatically because the component is not created in the form designer. Because the streaming system can already load and save components, you can use the first approach. The following methods load and store the dynamically created component that is the value of a property named MyCompProperty:

procedure TSampleComponent.LoadCompProperty(Reader: TReader);

begin

 ifReader.ReadBoolean then

   MyCompProperty := Reader.ReadComponent(nil);

end;

procedure TSampleComponent.StoreCompProperty(Writer: TWriter);

begin

 Writer.WriteBoolean(MyCompProperty <> nil);

 if MyCompProperty <> nil then

   Writer.WriteComponent(MyCompProperty);

end;

2        Override the DefineProperties method, passing those methods to a filer object.

Once you have created methods to store and load your property value, you can override the component抯 DefineProperties method. Delphi calls this method when it loads or stores the component. In the DefineProperties method, you must call the DefineProperty method or the DefineBinaryProperty method of the current filer, passing it the method to use for loading or saving your property value. If your load and store methods are of type TWriterProc and type TReaderProc, then you call the filer抯 DefineProperty method. If you created methods of type TStreamProc, call DefineBinaryProperty instead.

No matter which method you use to define the property, you pass it the methods that store and load your property value as well as a boolean value indicating whether the property value needs to be written. If the value can be inherited or has a default value, you do not need to write it.

For example, given the LoadCompProperty method of type TReaderProc and the StoreCompProperty method of type TWriterProc, you would override DefineProperties as follows:

procedure TSampleComponent.DefineProperties(Filer: TFiler);

 functionDoWrite: Boolean;

 begin

   if Filer.Ancestor <> nil then { check Ancestor for an inherited value }

   begin

     if TSampleComponent(Filer.Ancestor).MyCompProperty = nil then

       Result := MyCompProperty <> nil

     else if MyCompProperty = nil or

        TSampleComponent(Filer.Ancestor).MyCompProperty.Name <> MyCompProperty.Name then

       Result := True

     else Result := False;

   end

   else { no inherited value -- check for default (nil) value }

     Result := MyCompProperty <> nil;

 end;

begin

 inherited; { allow base classes to define properties }

 Filer.DefineProperty('MyCompProperty', LoadCompProperty, StoreCompProperty, DoWrite);

end;