Board index » delphi » Creating Arrays of Controls at Runtime

Creating Arrays of Controls at Runtime

How is it possible to create an array of a control at run time?
The size of the array is unknown at design time. I have tried using:
   MyArray: Array of MyControl;
then setting the size of the array, thence assigning each element of the
array to MyControl.Create(Self). This works for the first element, then
has a run-time error when it tries to create the second element, citing
that an object with this name already exists.

I have considered creating a large number of controls on the form,
assigning these to an array of pointers to the controls, then hiding the
ones I don't need, but this seems like quite a pointless waste of
memory, and would hope there is a more elegant method.

Any help would be appreciated.

Cheers,

Victor Rajewski
v...@progsoc.uts.edu.au

 

Re:Creating Arrays of Controls at Runtime


On Mon, 19 Oct 1998 11:28:12 +1000, trevor Baillie

Quote
<ozwe...@dot.net.au> wrote:
> How is it possible to create an array of a control at run time?

There are a wide variety of ways to do this. Probably the easiest is
to use a TList. Below is a simple example.

[Note that the example implements properties named Controls and
ControlCount, which will obscure the normal TForm.Controls and
TForm.ControlCount properties. There is no harm in this, but
presumably you'll select more appropriate and meaningful property
names.]

unit Unit1;

interface

uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    FControls : TList;
    function GetControlCount: Integer;
    function GetControls(Index: Integer): TControl;
    procedure FreeControls;
  public
    procedure AddControl(Control: TControl);
    property Controls[Index: Integer]: TControl read GetControls;
    property ControlCount: Integer read GetControlCount;
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
const
  NumberOfControls = 3;
var
  Button: TButton;
  I : Integer;
begin
  for I := 0 to (NumberOfControls - 1) do
  begin
    Button := TButton.Create(Self);
    Button.SetBounds(0, I * 32, 75, 25);
    Button.Parent := Self;
    AddControl(Button);
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FControls := TList.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FreeControls;
  FControls.Free;
end;

procedure TForm1.FreeControls;
var
  I : Integer;
begin
  for I := (ControlCount - 1) downto 0 do Controls[I].Free;
end;

procedure TForm1.AddControl(Control: TControl);
begin
  FControls.Add(Control);
end;

function TForm1.GetControls(Index: Integer): TControl;
begin
  Result := TControl(FControls[Index]);
end;

function TForm1.GetControlCount: Integer;
begin
  Result := FControls.Count;
end;

end.

--
Rick Rogers (TeamB) | Fenestra Technologies
http://www.fenestra.com/

Re:Creating Arrays of Controls at Runtime


The problem is that the VCL requires that each component has a unique name.

After you do
  MyArray [Ix] := MyControl.Create (Self)
add
  MyArray [Ix].Name := 'AUniqueName' + IntToStr (Ix);

... making sure that your "unique" name is, in fact, unique.

-- DaveM

Quote
trevor Baillie wrote in message <362A95AC.6...@dot.net.au>...
>How is it possible to create an array of a control at run time?
>The size of the array is unknown at design time. I have tried using:
>   MyArray: Array of MyControl;
>then setting the size of the array, thence assigning each element of the
>array to MyControl.Create(Self). This works for the first element, then
>has a run-time error when it tries to create the second element, citing
>that an object with this name already exists.

>I have considered creating a large number of controls on the form,
>assigning these to an array of pointers to the controls, then hiding the
>ones I don't need, but this seems like quite a pointless waste of
>memory, and would hope there is a more elegant method.

>Any help would be appreciated.

>Cheers,

>Victor Rajewski
>v...@progsoc.uts.edu.au

Re:Creating Arrays of Controls at Runtime


Could you not just dynamically create the controls you need at run-time and
use the form's Components property to locate the controls?
Quote
trevor Baillie wrote in message <362A95AC.6...@dot.net.au>...
>How is it possible to create an array of a control at run time?
>The size of the array is unknown at design time. I have tried using:
>   MyArray: Array of MyControl;
>then setting the size of the array, thence assigning each element of the
>array to MyControl.Create(Self). This works for the first element, then
>has a run-time error when it tries to create the second element, citing
>that an object with this name already exists.

>I have considered creating a large number of controls on the form,
>assigning these to an array of pointers to the controls, then hiding the
>ones I don't need, but this seems like quite a pointless waste of
>memory, and would hope there is a more elegant method.

>Any help would be appreciated.

>Cheers,

>Victor Rajewski
>v...@progsoc.uts.edu.au

Re:Creating Arrays of Controls at Runtime


Hi,

I was wondering, what if I wanted to create, let's say, two TList to
hold two different sets controls. Is there a way to use the functions,
procedures and methods in your example with both list?

Thanks,

Robert

Re:Creating Arrays of Controls at Runtime


Quote
On Wed, 21 Oct 1998 22:33:54 -0600, Robert Barr <b...@unm.edu> wrote:
> I was wondering, what if I wanted to create, let's say, two TList to
> hold two different sets controls.

OK, no problem.

Quote
> Is there a way to use the functions, procedures and methods in
> your example with both list?

The access methods in my example just make life easier. You could use
the same approach with any number of TList instances, like this:

  FList1.Add(MyControl);
  FList2.Add(MyOtherControl);

Alternatively you could create a TList descendant, or a TList
aggregate to manage lists of controls.

You might wish to have a look at a free component (which includes
source) on my website at http://www.fenestra.com/freestuff.htm. Here's
a description of the component:

"TControlList Object
This non-visual object (which descends from TObject) is a great way to
manage any arbitrary named list of controls. The class provides a way
to manage multiple named lists of controls, and perform operations
(such as showing, hiding, enabling, and disabling) on those controls.
The source code is a good example of how to use aggregation (classes
which contain classes) to present a simple and highly focused
interface."

--
Rick Rogers (TeamB) | Fenestra Technologies
http://www.fenestra.com/

Re:Creating Arrays of Controls at Runtime


Thanks Rick! I learned something new!

-Robert

Other Threads