我想製作一個包含整數列表作爲其序列化屬性之一的組件。我知道我不能聲明TList<integer>
作爲已發佈的屬性,因爲它不會從TPersistent下降。我讀過你可以定義「假」發佈的屬性,如果你重寫DefineProperties,但我不太確定這是如何工作的,尤其是當涉及到創建一個列表的假屬性,而不是一個單一的值。如何發佈整數列表?
有人能指出我正確的方向嗎?
我想製作一個包含整數列表作爲其序列化屬性之一的組件。我知道我不能聲明TList<integer>
作爲已發佈的屬性,因爲它不會從TPersistent下降。我讀過你可以定義「假」發佈的屬性,如果你重寫DefineProperties,但我不太確定這是如何工作的,尤其是當涉及到創建一個列表的假屬性,而不是一個單一的值。如何發佈整數列表?
有人能指出我正確的方向嗎?
下面是與DefineBinaryProperty
(寫在D2007,沒有仿製藥)小例子:
type
TTestComponent = class(TComponent)
private
FList: TList;
function GetValueCount: Integer;
function GetValues(Index: Integer): Integer;
procedure ReadValueList(Stream: TStream);
procedure SetValues(Index: Integer; Value: Integer);
procedure WriteValueList(Stream: TStream);
protected
procedure DefineProperties(Filer: TFiler); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function AddValue(Value: Integer): Integer;
procedure ClearValues;
procedure DeleteValue(Index: Integer);
property ValueCount: Integer read GetValueCount;
property Values[Index: Integer]: Integer read GetValues write SetValues;
end;
{ TTestComponent }
function TTestComponent.GetValueCount: Integer;
begin
Result := FList.Count;
end;
function TTestComponent.GetValues(Index: Integer): Integer;
begin
Result := Integer(FList[Index]);
end;
procedure TTestComponent.ReadValueList(Stream: TStream);
var
Count, I, Value: Integer;
begin
ClearValues;
Stream.Read(Count, SizeOf(Count));
for I := 0 to Count - 1 do
begin
Stream.Read(Value, SizeOf(Value));
AddValue(Value);
end;
end;
procedure TTestComponent.SetValues(Index: Integer; Value: Integer);
begin
FList[Index] := Pointer(Value);
end;
procedure TTestComponent.WriteValueList(Stream: TStream);
var
Count, I, Value: Integer;
begin
Count := ValueCount;
Stream.Write(Count, SizeOf(Count));
for I := 0 to Count - 1 do
begin
Value := Values[I];
Stream.Write(Value, SizeOf(Value));
end;
end;
procedure TTestComponent.DefineProperties(Filer: TFiler);
begin
inherited DefineProperties(Filer);
Filer.DefineBinaryProperty('ValueList', ReadValueList, WriteValueList, ValueCount > 0);
end;
constructor TTestComponent.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FList := TList.Create;
// add some values for testing
AddValue(0);
AddValue(1);
AddValue(2);
end;
destructor TTestComponent.Destroy;
begin
FList.Free;
inherited Destroy;
end;
function TTestComponent.AddValue(Value: Integer): Integer;
begin
Result := FList.Add(Pointer(Value));
end;
procedure TTestComponent.ClearValues;
begin
FList.Clear;
end;
procedure TTestComponent.DeleteValue(Index: Integer);
begin
FList.Delete(Index);
end;
和.DFM看起來是這樣的:
object TestComponent1: TTestComponent
Left = 96
Top = 56
ValueList = {03000000000000000100000002000000}
end
謝謝,這正是我所需要的。 – 2010-05-21 12:28:59
+1優秀的解決方案@TOndrej – RRUZ 2010-05-22 00:37:34
實現它的最快最簡單的方法是使用TCollection - 但是您將花費每個Integer的「裝飾」TCollectionItem類的代價!除非有很多整數,否則這是要走的路,因爲您幾乎可以免費獲得Object Inspector集成(免費,因爲在額外的工作時間內)。
如果你確實想保持你的列表是當前高效的形式(TList),那麼你是對的,要走的路是定義你自己的屬性。查看Graphics.pas單元,瞭解如何實現TPicture.DefineProperties,因爲這與您需要的非常接近!
想法:如果你去「DefineProperties」路線,你可能想看看RegisterComponentEditor,因爲你的整數列表在Object Inspector中不可見!
什麼是整數的意思?如果它們與表單上的組件實例有某種相關性,那麼你可能會做類似TGridPanel一樣的操作。 ColumnSpan。 – 2010-05-21 06:49:53