当前位置: 首页 > 工具软件 > VCL > 使用案例 >

VCL类学习之(五) TCollection

邬朗
2023-12-01
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.
  1.  TCollectionItemClass = class of TCollectionItem;
  2.   TCollectionNotification = (cnAdded, cnExtracting, cnDeleting);
  3.   TCollection = class(TPersistent)
  4.   private
  5.     FItemClass: TCollectionItemClass;
  6.     FItems: TList;
  7.     FUpdateCount: Integer;
  8.     FNextID: Integer;
  9.     FPropName: string;
  10.     function GetCount: Integer;
  11.     function GetPropName: string;
  12.     procedure InsertItem(Item: TCollectionItem);
  13.     procedure RemoveItem(Item: TCollectionItem);
  14.   protected
  15.     procedure Added(var Item: TCollectionItem); virtual; deprecated;
  16.     procedure Deleting(Item: TCollectionItem); virtual; deprecated;
  17.     property NextID: Integer read FNextID;
  18.     procedure Notify(Item: TCollectionItem; Action: TCollectionNotification); virtual;
  19.     { Design-time editor support }
  20.     function GetAttrCount: Integer; dynamic;
  21.     function GetAttr(Index: Integer): string; dynamic;
  22.     function GetItemAttr(Index, ItemIndex: Integer): string; dynamic;
  23.     procedure Changed;
  24.     function GetItem(Index: Integer): TCollectionItem;
  25.     procedure SetItem(Index: Integer; Value: TCollectionItem);
  26.     procedure SetItemName(Item: TCollectionItem); virtual;
  27.     procedure Update(Item: TCollectionItem); virtual;
  28.     property PropName: string read GetPropName write FPropName;
  29.     property UpdateCount: Integer read FUpdateCount;
  30.   public
  31.     constructor Create(ItemClass: TCollectionItemClass);
  32.     destructor Destroy; override;
  33.     function Owner: TPersistent;
  34.     function Add: TCollectionItem;
  35.     procedure Assign(Source: TPersistent); override;
  36.     procedure BeginUpdate; virtual;
  37.     procedure Clear;
  38.     procedure Delete(Index: Integer);
  39.     procedure EndUpdate; virtual;
  40.     function FindItemID(ID: Integer): TCollectionItem;
  41.     function GetNamePath: string; override;
  42.     function Insert(Index: Integer): TCollectionItem;
  43.     property Count: Integer read GetCount;
  44.     property ItemClass: TCollectionItemClass read FItemClass;
  45.     property Items[Index: Integer]: TCollectionItem read GetItem write SetItem;
  46.   end;
  47. { Collection class that maintains an "Owner" in order to obtain property
  48.   path information at design-time }
  49. { TCollection }
  50. constructor TCollection.Create(ItemClass: TCollectionItemClass);
  51. begin
  52.   FItemClass := ItemClass;
  53.   FItems := TList.Create;
  54.   NotifyDesigner(Self, Self, opInsert);
  55. end;
  56. destructor TCollection.Destroy;
  57. begin
  58.   FUpdateCount := 1;
  59.   if FItems <> nil then
  60.     Clear;
  61.   NotifyDesigner(Self, Self, opRemove);
  62.   FItems.Free;
  63.   inherited Destroy;
  64. end;
  65. function TCollection.Add: TCollectionItem;
  66. begin
  67.   Result := FItemClass.Create(Self);
  68.   Added(Result);
  69. end;
  70. procedure TCollection.Assign(Source: TPersistent);
  71. var
  72.   I: Integer;
  73. begin
  74.   if Source is TCollection then
  75.   begin
  76.     BeginUpdate;
  77.     try
  78.       Clear;
  79.       for I := 0 to TCollection(Source).Count - 1 do
  80.         Add.Assign(TCollection(Source).Items[I]);
  81.     finally
  82.       EndUpdate;
  83.     end;
  84.     Exit;
  85.   end;
  86.   inherited Assign(Source);
  87. end;
  88. procedure TCollection.BeginUpdate;
  89. begin
  90.   Inc(FUpdateCount);
  91. end;
  92. procedure TCollection.Changed;
  93. begin
  94.   if FUpdateCount = 0 then Update(nil);
  95. end;
  96. procedure TCollection.Clear;
  97. begin
  98.   if FItems.Count > 0 then
  99.   begin
  100.     BeginUpdate;
  101.     try
  102.       while FItems.Count > 0 do
  103.         TCollectionItem(FItems.Last).Free;
  104.     finally
  105.       EndUpdate;
  106.     end;
  107.   end;
  108. end;
  109. procedure TCollection.EndUpdate;
  110. begin
  111.   Dec(FUpdateCount);
  112.   Changed;
  113. end;
  114. function TCollection.FindItemID(ID: Integer): TCollectionItem;
  115. var
  116.   I: Integer;
  117. begin
  118.   for I := 0 to FItems.Count-1 do
  119.   begin
  120.     Result := TCollectionItem(FItems[I]);
  121.     if Result.ID = ID then Exit;
  122.   end;
  123.   Result := nil;
  124. end;
  125. function TCollection.GetAttrCount: Integer;
  126. begin
  127.   Result := 0;
  128. end;
  129. function TCollection.GetAttr(Index: Integer): string;
  130. begin
  131.   Result := '';
  132. end;
  133. function TCollection.GetItemAttr(Index, ItemIndex: Integer): string;
  134. begin
  135.   Result := Items[ItemIndex].DisplayName;
  136. end;
  137. function TCollection.GetCount: Integer;
  138. begin
  139.   Result := FItems.Count;
  140. end;
  141. function TCollection.GetItem(Index: Integer): TCollectionItem;
  142. begin
  143.   Result := FItems[Index];
  144. end;
  145. function TCollection.GetNamePath: string;
  146. var
  147.   S, P: string;
  148. begin
  149.   Result := ClassName;
  150.   if GetOwner = nil then Exit;
  151.   S := GetOwner.GetNamePath;
  152.   if S = '' then Exit;
  153.   P := PropName;
  154.   if P = '' then Exit;
  155.   Result := S + '.' + P;
  156. end;
  157. function TCollection.GetPropName: string;
  158. var
  159.   I: Integer;
  160.   Props: PPropList;
  161.   TypeData: PTypeData;
  162.   Owner: TPersistent;
  163. begin
  164.   Result := FPropName;
  165.   Owner := GetOwner;
  166.   if (Result <> ''or (Owner = nilor (Owner.ClassInfo = nilthen Exit;
  167.   TypeData := GetTypeData(Owner.ClassInfo);
  168.   if (TypeData = nilor (TypeData^.PropCount = 0then Exit;
  169.   GetMem(Props, TypeData^.PropCount * sizeof(Pointer));
  170.   try
  171.     GetPropInfos(Owner.ClassInfo, Props);
  172.     for I := 0 to TypeData^.PropCount-1 do
  173.     begin
  174.       with Props^[I]^ do
  175.         if (PropType^^.Kind = tkClass) and
  176.           (GetOrdProp(Owner, Props^[I]) = Integer(Self)) then
  177.           FPropName := Name;
  178.     end;
  179.   finally
  180.     Freemem(Props);
  181.   end;
  182.   Result := FPropName;
  183. end;
  184. function TCollection.Insert(Index: Integer): TCollectionItem;
  185. begin
  186.   Result := Add;
  187.   Result.Index := Index;
  188. end;
  189. procedure TCollection.InsertItem(Item: TCollectionItem);
  190. begin
  191.   if not (Item is FItemClass) then TList.Error(@SInvalidProperty, 0);
  192.   FItems.Add(Item);
  193.   Item.FCollection := Self;
  194.   Item.FID := FNextID;
  195.   Inc(FNextID);
  196.   SetItemName(Item);
  197.   Notify(Item, cnAdded);
  198.   Changed;
  199.   NotifyDesigner(Self, Item, opInsert);
  200. end;
  201. procedure TCollection.RemoveItem(Item: TCollectionItem);
  202. begin
  203.   Notify(Item, cnExtracting);
  204.   if Item = FItems.Last then
  205.     FItems.Delete(FItems.Count - 1)
  206.   else
  207.     FItems.Remove(Item);
  208.   Item.FCollection := nil;
  209.   NotifyDesigner(Self, Item, opRemove);
  210.   Changed;
  211. end;
  212. procedure TCollection.SetItem(Index: Integer; Value: TCollectionItem);
  213. begin
  214.   TCollectionItem(FItems[Index]).Assign(Value);
  215. end;
  216. procedure TCollection.SetItemName(Item: TCollectionItem);
  217. begin
  218. end;
  219. procedure TCollection.Update(Item: TCollectionItem);
  220. begin
  221. end;
  222. procedure TCollection.Delete(Index: Integer);
  223. begin
  224.   Notify(TCollectionItem(FItems[Index]), cnDeleting);
  225.   TCollectionItem(FItems[Index]).Free;
  226. end;
  227. function TCollection.Owner: TPersistent;
  228. begin
  229.   Result := GetOwner;
  230. end;
  231. procedure TCollection.Added(var Item: TCollectionItem);
  232. begin
  233. end;
  234. procedure TCollection.Deleting(Item: TCollectionItem);
  235. begin
  236. end;
  237. procedure TCollection.Notify(Item: TCollectionItem;
  238.   Action: TCollectionNotification);
  239. begin
  240.   case Action of
  241.     cnAdded: Added(Item);
  242.     cnDeleting: Deleting(Item);
  243.   end;
  244. end;
 类似资料: