我试图使用自定义类的数组作为我的组件的属性,但问题是值没有保存到组件,这意味着如果我设置值,保存所有内容并再次打开项目,组件的值消失…我的代码如下所示:
unit Unit1; interface uses Windows,ExtCtrls,Classes,Controls; type TMyClass=class(TPersistent) private FName: string; FValue: double; public property Name: string read FName write FName; property Value: double read FValue write FValue; end; TMyComponent= class(TCustomPanel) private FMyArray: array[0..200] of TMyClass; function GetmyArray(Index: Integer): TMyClass; procedure SetMyArray(index: Integer; Value: TMyClass); public property myArray[index: Integer]: TMyClass read GetMyArray write SetMyArray; end; implementation function TMyComponent.GetmyArray(Index: Integer): TMyClass; begin result:= FmyArray[Index]; end; procedure TMyComponent.SetMyArray(index: Integer; Value: TMyClass); begin FMyArray[index].FName:= Value.FName; FMyArray[index].FValue:= Value.FValue; end; end.
我知道只有已发布的属性可以流式传输,但问题是我的属性是一个数组而且无法发布…
我的建议是使用DefineProperties()来提供自定义流,但我不知道如何使用数组执行此操作.
我认为的其他可能性是将TMyClass修改为TMyComponent可以作为它的父类的类,就像它在TChart中完成的那样,你可以为它添加不同类的系列.但我不知道这应该是什么课
TMyClass=class(T???????????)
有了它,我可以取出属性MyArray并创建TMyClass并添加到TMyComponent如下:
MyArray1.parent:= MyComponent1; MyArray2.parent:= MyComponent2; ...
.哪一个是更好的选择?或者还有其他更好的主意吗?
解决方法
最简单(和首选)的解决方案是将TMyClass更改为从TCollectionItem派生并将TMyComponent.FMyArray更改为TOwnedCollection.然后DFM将自动为您流式传输项目,您可以获得本机设计时支持,以创建和操作TMyClass对象及其属性.
试试这个:
unit Unit1; interface uses Windows,Controls; type TMyClass = class(TCollectionItem) private FName: string; FValue: double; procedure SetName(const AValue: string); procedure SetValue(AValue: double); public procedure Assign(ASource: TPersistent); override; published property Name: string read FName write SetName; property Value: double read FValue write SetValue; end; TMyArray = class(TOwnedCollection) private function GetItem(Index: Integer): TMyClass; procedure SetItem(Index: Integer; const Value: TMyClass); public constructor Create(AOwner: TPersistent); function Add: TMyClass; reintroduce; function Insert(Index: Integer): TMyClass; reintroduce; property Items[Index: Integer]: TMyClass read GetItem write SetItem; default; end; TMyComponent = class(TCustomPanel) private FMyArray: TMyArray; procedure SetMyArray(Value: TMyArray); public constructor Create(AOwner: TComponent); override; destructor Destroy; override; published property myArray: TMyArray read FMyArray write SetMyArray; end; implementation procedure TMyClass.Assign(ASource: TPersistent); begin if ASource is TMyClass then begin with TMyClass(ASource) do begin Self.FName := Name; Self.FValue := Value; end; Changed(False); end else inherited; end; procedure TMyClass.SetName(const AValue: string); begin if FName <> AValue then begin FName := AValue; Changed(False); end; end; procedure TMyClass.SetValue(AValue: double); begin if FValue <> AValue then begin FValue := AValue; Changed(False); end; end; constructor TMyArray.Create(AOwner: TPersistent); begin inherited Create(AOwner,TMyClass); end; function TMyArray.GetItem(Index: Integer): TMyClass; begin Result := TMyClass(inherited GetItem(Index)); end; procedure TMyArray.SetItem(Index: Integer; const Value: TMyClass); begin inherited SetItem(Index,Value); end; function TMyArray.Add: TMyClass; begin Result := TMyClass(inherited Add); end; function TMyArray.Insert(Index: Integer): TMyClass; begin Result := TMyClass(inherited Insert(Index)); end; constructor TMyComponent.Create(AOwner: TComponent); begin inherited; FMyArray := TMyArray.Create(Self); end; destructor TMyComponent.Destroy; begin FMyArray.Free; inherited; end; procedure TMyComponent.SetMyArray(Value: TMyArray); begin FMyArray.Assign(Value); end; end.