Description
Each TCollection holds a group of TCollectionItem descendants. TCollection maintains an index of the collection items in its Items array. The Count property contains the number of items in the collection. Use the Add and Delete methods to add items to the collection and delete items from the collection.
Objects descended from TCollection can contain objects descended from TCollectionItem. Thus, for each TCollection descendant, there is a corresponding TCollectionItem descendant. The following table lists some typical descendants of TCollection with the corresponding TCollectionItem descendant and the component that uses each pair.
TCollection
descendant TCollectionItem
descendant Component
TAggregates TAggregate TClientDataSet
TCookieCollection TCookie TWebResponse
TCoolBands TCoolBand TCoolBar
TDBGridColumns TColumn TDBGrid
TDependencies TDependency TService
TDisplayDims TDisplayDim TDecisionGrid
TFieldDefs TFieldDef TDataSet
THeaderSections THeaderSection THeaderControl
TIndexDefs TIndexDef TTable
TListColumns TListColumn TListView
TParams TParam many datasets
TStatusPanels TStatusPanel TStatusBar
TWorkAreas TWorkArea TListView
The controls that use TCollection and TCollectionItem descendants have a published property that holds a collection. (For example, the Panels property of TStatusBar holds a TStatusPanels.) A standard property editor, referred to generically as the Collection editor, can be invoked from the Object Inspector to edit the items in the collection.
Note: When writing a TCollection descendant that is used by another control, be sure to override the protected GetOwner method of the collection so that it can appear in the Object Inspector.
- TCollectionItemClass = class of TCollectionItem;
- TCollectionNotification = (cnAdded, cnExtracting, cnDeleting);
- TCollection = class(TPersistent)
- private
- FItemClass: TCollectionItemClass;
- FItems: TList;
- FUpdateCount: Integer;
- FNextID: Integer;
- FPropName: string;
- function GetCount: Integer;
- function GetPropName: string;
- procedure InsertItem(Item: TCollectionItem);
- procedure RemoveItem(Item: TCollectionItem);
- protected
- procedure Added(var Item: TCollectionItem); virtual; deprecated;
- procedure Deleting(Item: TCollectionItem); virtual; deprecated;
- property NextID: Integer read FNextID;
- procedure Notify(Item: TCollectionItem; Action: TCollectionNotification); virtual;
-
- function GetAttrCount: Integer; dynamic;
- function GetAttr(Index: Integer): string; dynamic;
- function GetItemAttr(Index, ItemIndex: Integer): string; dynamic;
- procedure Changed;
- function GetItem(Index: Integer): TCollectionItem;
- procedure SetItem(Index: Integer; Value: TCollectionItem);
- procedure SetItemName(Item: TCollectionItem); virtual;
- procedure Update(Item: TCollectionItem); virtual;
- property PropName: string read GetPropName write FPropName;
- property UpdateCount: Integer read FUpdateCount;
- public
- constructor Create(ItemClass: TCollectionItemClass);
- destructor Destroy; override;
- function Owner: TPersistent;
- function Add: TCollectionItem;
- procedure Assign(Source: TPersistent); override;
- procedure BeginUpdate; virtual;
- procedure Clear;
- procedure Delete(Index: Integer);
- procedure EndUpdate; virtual;
- function FindItemID(ID: Integer): TCollectionItem;
- function GetNamePath: string; override;
- function Insert(Index: Integer): TCollectionItem;
- property Count: Integer read GetCount;
- property ItemClass: TCollectionItemClass read FItemClass;
- property Items[Index: Integer]: TCollectionItem read GetItem write SetItem;
- end;
- constructor TCollection.Create(ItemClass: TCollectionItemClass);
- begin
- FItemClass := ItemClass;
- FItems := TList.Create;
- NotifyDesigner(Self, Self, opInsert);
- end;
- destructor TCollection.Destroy;
- begin
- FUpdateCount := 1;
- if FItems <> nil then
- Clear;
- NotifyDesigner(Self, Self, opRemove);
- FItems.Free;
- inherited Destroy;
- end;
- function TCollection.Add: TCollectionItem;
- begin
- Result := FItemClass.Create(Self);
- Added(Result);
- end;
- procedure TCollection.Assign(Source: TPersistent);
- var
- I: Integer;
- begin
- if Source is TCollection then
- begin
- BeginUpdate;
- try
- Clear;
- for I := 0 to TCollection(Source).Count - 1 do
- Add.Assign(TCollection(Source).Items[I]);
- finally
- EndUpdate;
- end;
- Exit;
- end;
- inherited Assign(Source);
- end;
- procedure TCollection.BeginUpdate;
- begin
- Inc(FUpdateCount);
- end;
- procedure TCollection.Changed;
- begin
- if FUpdateCount = 0 then Update(nil);
- end;
- procedure TCollection.Clear;
- begin
- if FItems.Count > 0 then
- begin
- BeginUpdate;
- try
- while FItems.Count > 0 do
- TCollectionItem(FItems.Last).Free;
- finally
- EndUpdate;
- end;
- end;
- end;
- procedure TCollection.EndUpdate;
- begin
- Dec(FUpdateCount);
- Changed;
- end;
- function TCollection.FindItemID(ID: Integer): TCollectionItem;
- var
- I: Integer;
- begin
- for I := 0 to FItems.Count-1 do
- begin
- Result := TCollectionItem(FItems[I]);
- if Result.ID = ID then Exit;
- end;
- Result := nil;
- end;
- function TCollection.GetAttrCount: Integer;
- begin
- Result := 0;
- end;
- function TCollection.GetAttr(Index: Integer): string;
- begin
- Result := '';
- end;
- function TCollection.GetItemAttr(Index, ItemIndex: Integer): string;
- begin
- Result := Items[ItemIndex].DisplayName;
- end;
- function TCollection.GetCount: Integer;
- begin
- Result := FItems.Count;
- end;
- function TCollection.GetItem(Index: Integer): TCollectionItem;
- begin
- Result := FItems[Index];
- end;
- function TCollection.GetNamePath: string;
- var
- S, P: string;
- begin
- Result := ClassName;
- if GetOwner = nil then Exit;
- S := GetOwner.GetNamePath;
- if S = '' then Exit;
- P := PropName;
- if P = '' then Exit;
- Result := S + '.' + P;
- end;
- function TCollection.GetPropName: string;
- var
- I: Integer;
- Props: PPropList;
- TypeData: PTypeData;
- Owner: TPersistent;
- begin
- Result := FPropName;
- Owner := GetOwner;
- if (Result <> '') or (Owner = nil) or (Owner.ClassInfo = nil) then Exit;
- TypeData := GetTypeData(Owner.ClassInfo);
- if (TypeData = nil) or (TypeData^.PropCount = 0) then Exit;
- GetMem(Props, TypeData^.PropCount * sizeof(Pointer));
- try
- GetPropInfos(Owner.ClassInfo, Props);
- for I := 0 to TypeData^.PropCount-1 do
- begin
- with Props^[I]^ do
- if (PropType^^.Kind = tkClass) and
- (GetOrdProp(Owner, Props^[I]) = Integer(Self)) then
- FPropName := Name;
- end;
- finally
- Freemem(Props);
- end;
- Result := FPropName;
- end;
- function TCollection.Insert(Index: Integer): TCollectionItem;
- begin
- Result := Add;
- Result.Index := Index;
- end;
- procedure TCollection.InsertItem(Item: TCollectionItem);
- begin
- if not (Item is FItemClass) then TList.Error(@SInvalidProperty, 0);
- FItems.Add(Item);
- Item.FCollection := Self;
- Item.FID := FNextID;
- Inc(FNextID);
- SetItemName(Item);
- Notify(Item, cnAdded);
- Changed;
- NotifyDesigner(Self, Item, opInsert);
- end;
- procedure TCollection.RemoveItem(Item: TCollectionItem);
- begin
- Notify(Item, cnExtracting);
- if Item = FItems.Last then
- FItems.Delete(FItems.Count - 1)
- else
- FItems.Remove(Item);
- Item.FCollection := nil;
- NotifyDesigner(Self, Item, opRemove);
- Changed;
- end;
- procedure TCollection.SetItem(Index: Integer; Value: TCollectionItem);
- begin
- TCollectionItem(FItems[Index]).Assign(Value);
- end;
- procedure TCollection.SetItemName(Item: TCollectionItem);
- begin
- end;
- procedure TCollection.Update(Item: TCollectionItem);
- begin
- end;
- procedure TCollection.Delete(Index: Integer);
- begin
- Notify(TCollectionItem(FItems[Index]), cnDeleting);
- TCollectionItem(FItems[Index]).Free;
- end;
- function TCollection.Owner: TPersistent;
- begin
- Result := GetOwner;
- end;
- procedure TCollection.Added(var Item: TCollectionItem);
- begin
- end;
- procedure TCollection.Deleting(Item: TCollectionItem);
- begin
- end;
- procedure TCollection.Notify(Item: TCollectionItem;
- Action: TCollectionNotification);
- begin
- case Action of
- cnAdded: Added(Item);
- cnDeleting: Deleting(Item);
- end;
- end;