Delphi Programming Guide
Delphi Programmer 

Menu  Table of contents
Bookmark and Share

Part I - Foundations
  Chapter 1 Delphi 7 and Its IDE
  Chapter 2 The Delphi Programming Language
  Chapter 3 The Run-Time Library
  Chapter 4 Core Library classes
  Chapter 5 Visual Controls
  Chapter 6 Building the User Interface
  Chapter 7 Working with Forms
Part II - Delphi Object-Oriented Architectures
  Chapter 8 The Architecture of Delphi Applications
  Chapter 9 Writing Delphi Components
  Chapter 10 Libraries and Packages
  Chapter 11 Modeling and OOP Programming (with ModelMaker)
  Chapter 12 From COM to COM+
Part III - Delphi Database-Oriented Architectures
  Chapter 13 Delphi's Database Architecture
  Chapter 14 Client/Server with dbExpress
  Chapter 15 Working with ADO
  Chapter 16 Multitier DataSnap Applications
  Chapter 17 Writing Database Components
  Chapter 18 Reporting with Rave
Part IV - Delphi, the Internet, and a .NET Preview
  Chapter 19 Internet Programming: Sockets and Indy
  Chapter 20 Web Programming with WebBroker and WebSnap
  Chapter 21 Web Programming with IntraWeb
  Chapter 22 Using XML Technologies
  Chapter 23 Web Services and SOAP
  Chapter 24 The Microsoft .NET Architecture from the Delphi Perspective
  Chapter 25 Delphi for .NET Preview: The Language and the RTL
  Appendix A Extra Delphi Tools by the Author
  Appendix B Extra Delphi Tools from Other Sources
  Appendix C Free Companion Books on Delphi
  List of Figures    
  List of tables    
  List of Listings    
  List of Sidebars  

Previous Section Next Section

Collection Properties

At times you need a property holding a list of values, not a single value. Sometimes you can use a TStringList-based property, but it accounts only for textual data (even though an object can be attached to each string). When you need a property hosting an array of objects, the most VCL-sound solution is to use a collection. The role of collections, by design, is to build properties that contain a list of values. Examples of Delphi collection properties include the DBGrid component's Columns property, and the TStatusBar component's Panels property.

A collection is basically a container of objects of a given type. For this reason, to define a collection, you need to inherit a new class from the TCollection class and also inherit a new class from the TCollectionItem class. This second class defines the objects held by the collection; the collection is created by passing to it the class of the objects it will hold.

Not only does the collection class manipulate the items of the collection, but it is also responsible for creating new objects when its Add method is called. You cannot create an object and then add it to an existing collection. Listing 9.3 shows two classes for the items and a collection, with their most relevant code.

Listing 9.3: The Classes for a Collection and Its Items
Start example
  TMdMyItem = class (TCollectionItem)
    FCode: Integer;
    FText: string;
    procedure SetCode(const Value: Integer);
    procedure SetText(const Value: string);
    property Text: string read FText write SetText;
    property Code: Integer read FCode write SetCode;
  TMdMyCollection = class (TCollection)
    FComp: TComponent;
    FCollString: string;
    constructor Create (CollOwner: TComponent);
    function GetOwner: TPersistent; override;
    procedure Update(Item: TCollectionItem); override;
{ TMdMyCollection }
constructor TMdMyCollection.Create (CollOwner: TComponent);
  inherited Create (TMdMyItem);
  FComp := CollOwner;
function TMdMyCollection.GetOwner: TPersistent;
  Result := FComp;
procedure TMyCollection.Update(Item: TCollectionItem);
  str: string;
  i: Integer;
  // update everything in any case...
  str := '';
  for i := 0 to Count - 1 do
    str := str + (Items [i] as TMyItem).Text;
    if i < Count - 1 then
      str := str + '-';
  FCollString := str;
End example

The collection must define the GetOwner method to be displayed properly in the collection property editor provided by the Delphi IDE. For this reason, it needs a link to the component hosting it, the collection owner (stored in the FComp field in the code). You can see this sample component's collection in Figure 9.11.

Click To expand
Figure 9.11:  The collection editor, with the Object TreeView and the Object Inspector for the collection item

Every time data changes in a collection item, its code calls the Changed method (passing True or False to indicate whether the change is local to the item or refers to the entire set of items in the collection). As a result of this call, the TCollection class calls the virtual method Update, which receives as a parameter the single item requesting the update, or nil if all items changed (and when the Changed method is called with True as a parameter). You can override this method to update the values of other elements of the collection, of the collection itself, or of the target component.

In this example you update a string with a summary of the collection data that you've added to the collection and that the host component will surface as a property. Using the collection within a component is simple. You declare a collection, create it in the constructor and free it at the end, and expose it through a property:

  TCanTest = class(TComponent)
    FColl: TMyCollection;
    function GetCollString: string;
    constructor Create (aOwner: TComponent); override;
    destructor Destroy; override;
    property MoreData: TMyCollection read FColl write SetMoreData;
    property CollString: string read GetCollString;
constructor TCanTest.Create(aOwner: TComponent);
  FColl := TMyCollection.Create (Self);
destructor TCanTest.Destroy;
procedure TCanTest.SetMoreData(const Value: TMyCollection);
  FColl.Assign (Value);
function TCanTest.GetCollString: string;
  Result := FColl.FCollString;

Notice that the collection items are streamed in DFM files along with the component hosting them, using the special item markers and angle brackets, as in the following example:

object MdCollection1: TMdCollection
  MoreData = <
      Text = 'one'
      Code = 1
      Text = 'two'
      Code = 2
      Text = 'three'
      Code = 3

Previous Section Next Section



Copyright © 2004-2016 "Delphi Sources". Delphi Programming Guide
     Twitter     Facebook