2007. április 8., vasárnap

How to create a TCollection


Problem/Question/Abstract:

How do I create a Collection myself? I need a Collection of Items with ArticelNr, Name, Price, etc.. Each item should be in the collection of ResellItems.

Answer:

First, you need to create your ResellItem class based upon TCollectionItem:


TResellItem = class(TCollectionItem)
private
  fArticleNr: integer;
  fName: string;
  fPrice: double;
public
  property ArticleNr: integer read fArticleNr write fArticleNr;
  property Name: string read fName write fName;
  property Price: double read fPrice write fPrice;
end;


The next step is optional although I generally find it useful (self-documents for a start): create a descendent of TCollection:


TResellCollection = class(TCollection)
end;


Now you need to declare an instance somewhere:


var
  ResellCollection: TResellCollection;


The constructor for TCollection takes a TCollectionItem class parameter:


ResellCollection: TResellCollection.Create(TResellItem);


Having created our collection (don't forget to free it afterwards) then adding items becomes:


var
  item: TResellItem;

  item := ResellCollection.Add as TResellItem;
  item.ArticleNr := aNumber;
  item.Name := aName;
  item.Price := aPrice;


I generally wrap the above code into a TResellCollection method, say AddResellItem, thus allowing:


ResellCollection.AddResellItem(aNumber, aName, aPrice);


Accessing items afterwards is done like this:


item := ResellCollection.Items[index] as TResellItem;


The syntax above can be simplified by adding a new default array property to TResellCollection, thus encapsulating the messy casting:


property ResellItem[index: integer]: TResellItem read GetResellItem; default;


The GetResellItem method required looks like this:


function TResellCollection.GetResellItem(index: integer): TResellItem;
begin
  Result := Items[index] as TResellItem;
end;


Now you can say things like:


item := ResellCollection[0];
ResellCollection[1].Name := newname;


Just in case you have got a bit lost with the changes, the interface and implementation of TResellCollection now look like this:


TResellCollection = class(TCollection)
private
  function GetResellItem(index: integer): TResellItem;
public
  procedure AddResellItem(aNumber: integer; const aName: string; aPrice: Double);
  property ResellItem[index: integer]: TResellItem read GetResellItem;
  default;
end;

procedure TResellCollection.AddResellItem(aNumber: integer; const aName: string;
  aPrice: Double);
var
  item: TResellItem;
begin
  item := Add as TResellItem;
  item.ArticleNr := aNumber;
  item.Name := aName;
  item.Price := aPrice;
end;

function TResellCollection.GetResellItem(index: integer): TResellItem;
begin
  Result := Items[index] as TResellItem;
end;

Nincsenek megjegyzések:

Megjegyzés küldése