7

コンポーネントのプロパティとしてカスタム クラスの配列を使用しようとしていますが、問題は値がコンポーネントに保存されていないことです。つまり、値を設定すると、すべてを保存してプロジェクトを再度開くことになります。コンポーネントの値が消えます...私のコードは次のようになります:

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;
...

. どちらがより良い選択肢ですか?それとも他に良いアイデアはありますか?

4

2 に答える 2

5

私はDefinePropertiesに投票します!必要なコードは次のようになります (配列内のインスタンスがどれも nil でないと仮定します):

procedure TMyComponent.DefineProperties(Filer: TFiler);
begin
  inherited;
  Filer.DefineProperty('MyArray', ReadMyArray, WriteMyArray, true);
end;

procedure TMyComponent.ReadMyArray(Reader: TReader);
var
  N: Integer;
begin
  N := 0;
  Reader.ReadListBegin;
  while not Reader.EndOfList do begin
    Reader.ReadListBegin;
    FMyArray[N].Name := Reader.ReadString;
    FMyArray[N].Value := Reader.ReadFloat;
    Reader.ReadListEnd;
    Inc(N);
  end;
  Reader.ReadListEnd;
end;

procedure TMyComponent.WriteMyArray(Writer: TWriter);
var
  I: Integer;
begin
  Writer.WriteListBegin;
  for I := 0 to High(FMyArray) do begin
    Writer.WriteListBegin;
    Writer.WriteString(FMyArray[I].Name);
    Writer.WriteFloat(FMyArray[I].Value);
    Writer.WriteListEnd;
  end;
  Writer.WriteListEnd;
end;
于 2013-05-29T16:46:17.237 に答える