Control Arrays

Up

There is good news and bad news about Control arrays with the newest version of Visual Studio. Visual Studio .NET does not have control arrays like Visual Basic 6.0 does. Thatís the bad news. The good news is that you can still set things up to do similar things. In fact, not only can you do similar things but they can be done with more power and flexibility. What follows is a brief description of how to create arrays of objects in VB .NET and in C#.

Creating and using an Array of Controls (Visual Basic .NET)

This example creates a simple game of Space invaders. An array of picture boxes will be moved down a form controlled by a timer. When an object reaches the bottom of the form or is clicked by the user it is returned to the top of the form. By creating an array of picture boxes the program can move the boxes using a simple loop. A second advantage of this technique is that only one method is required to respond to a click of any of the picture boxes.

The first step is to create a number of picture boxes one a form. The names of the picture boxes do not have to be similar. The array that controls them can also have an unrelated name. For example, you could create four boxes named PictureBox1 through PictureBox4. The array of picture boxes could be named ships. This array will not be an array of independent boxes. It will be an array of references to the independently named objects.

The array will be declared at the top of the class declaration after the controls on the form are declared. The statement will look something like:

Public Class Form1

Inherits System.Windows.Forms.Form

Dim ships(4) As PictureBox

Now that your picture boxes have been created and an array has been declared to hold references to them they must be copied into the array. This is done using a set of assignment statements in the class constructor after the call to the InitializeComponent method like the example below.

InitializeComponent()

ships(0) = PictureBox1

ships(1) = PictureBox2

ships(2) = PictureBox3

ships(3) = PictureBox4

This will allow you to move these objects using a loop. These objects can be moved by changing the location property of the object. A new point is determined and assigned to the location property of the object. This code might look something like the following:

Dim i As Int16

Dim newPoint As Point

For i = 0 To 3

newPoint.Y = ships(i).Location.Y + 5

If newPoint.Y > 200 Then newPoint.Y = 0

newPoint.X = ships(i).Location.X

ships(i).Location = newPoint

Next

The for loop will process each picture box in the array. As the Y value in the Location property is increased the box moves down the form. If the form moves past the 200th pixel it is placed back at the top of the form.

The next step is to create a method that will respond to mouse clicks. Create a simple method called hitMe. It will look something like this:

Private Sub HitMe(ByVal sender As System.Object,

ByVal e As System.EventArgs)

Handles PictureBox1.Click, PictureBox2.Click, PictureBox3.Click, PictureBox4.Click

Dim s As PictureBox = sender

Dim p As Point = New Point(s.Location.X, 0)

s.Location = p

End Sub

The Handles clause lists all the objects and the events that this method will process. In this example, a click event to any of the four objects listed will cause this method to be called.

Notice that this method casts the object passed in as sender into a PictureBox. This gives the method access to the location property. The base object, called Object, which all other objects are derived from, does not have a Location property. This method should only be used with picture boxes. If a method is written that needs to handle different object types them the GetType method that the Object object supports to determine the type of object to be cast before attempting to process the object.

Adding Objects at Run-Time

Objects can also be created and added to an array of controls under program control at run-time. A dim statement and a new statement, such as the one below, will create a new instance of a PictureBox.

Dim temp As PictureBox = New System.Windows.Forms.PictureBox()

At this point a new object has been created. The program should then set the properties that determine how and where the object is displayed. The object will become visible on the form when it is added to the list of objects on the form using the Add method. In the statement below, Me refers to the form whose initialization code is running.

Me.Controls.Add(temp)

Event handlers can also be added to an object at runtime. The AddHandler statement associates the address of a method to a specific event of an object. The statement below specifies that the method called picClick is to be called when the object named temp experiences a Click event.

AddHandler temp.Click, AddressOf picClick

If the picClick method does not exist or does not meet the parameter requirements of the specified event than an error will be generated.

A newly created object can be added to an array of controls at anytime after it has been created. It is fairly common to have all the setup statements executed before adding the object to the array but there is no requirement to do so. Once the object has been added to the array it can be referenced either by its unique name or as a member of the array. There are times when it makes sense to have the objects created, added to an array and than use a loop to make the initial setup of all members of the array at the same time.

Identifying Members of an Array of Objects

There are many times when it is useful to identify which specific member of an array is responding to an event. For example, if a change must be made to an object and the objects that follow it in the array the program must be able to identify where in the array the object exists. The Tag property can be used to hold an identifier for this purpose.

The Tag property can hold any object. Because Visual Basic .Net treats built-in types such as integer and double as objects they can be stored in the Tag property. When an object is added to an array an index value must be used to place the reference in a specific element of that array. A program can copy that index number into the Tag where it can be retrieved later. For example, if an array named playSquares is being used to hold objects the Tag property could be set as follows.

playSquares(J).Tag = J

This value can be retrieved as an integer using a statement such as that below.

Dim who As Integer = whoHit.Tag

Because Tag holds objects the information stored in it can be much more flexible and powerful than if it were limited to integers or even strings. For example the Point object can be used to hold a two dimensional location for two dimensional arrays. For example:

playSquares(I, J).Tag = New Point(I, J)

This places a Point object with both X and Y values in Tag. These values can be used by casting the Tag into a Point object and using the X and Y properties of that object. For example:

Dim index As Point = whoHit.Tag

Dim i As Integer = index.X

Dim j As Integer = index.Y

A programmer could create their own structure to support three (or greater) dimensional arrays. Programmer developed structures could also hold other identifying information besides location. The possibilities are immense.

 

Creating and using an Array of Controls (C#)

This example creates a simple game of Space invaders. An array of picture boxes will be moved down a form controlled by a timer. When an object reaches the bottom of the form or is clicked by the user it is returned to the top of the form. By creating an array of picture boxes the program can move the boxes using a simple loop. A second advantage of this technique is that only one method is required to respond to a click of any of the picture boxes.

The first step is to create a number of picture boxes one a form. The names of the picture boxes do not have to be similar. The array that controls them can also have an unrelated name. For example, you could create four boxes named PictureBox1 through PictureBox4. The array of picture boxes could be named MyBoxes. This array will not be an array of independent boxes. It will be an array of references to the independently named objects.

The array will be declared at the top of the class declaration after the controls on the form are declared. The statement will look something like:

PictureBox [] myBoxes = new PictureBox [4];

The next step will be to add references to your existing picture boxes to this array. This is done using a set of assignment statements in the class constructor after the call to the InitializeComponent method like the example below.

InitializeComponent();

myBoxes[0] = pictureBox1;

myBoxes[1] = pictureBox2;

myBoxes[2] = pictureBox3;

myBoxes[3] = pictureBox4;

This will allow you to move these objects using a loop. These objects can be moved by changing the value of the picture boxes Top property. This code might look something like the following:

foreach (PictureBox p in myBoxes)

{

p.Top += 3;

if (p.Top > 200) p.Top = 0;

}

The foreach loop will process each picture box in the array. As the Top property is increased the box moves down the form. If the form moves past the 200th pixel it is moved back to the top of the form.

The next step is to create a method that will respond to mouse clicks. Create a simple method called hitMe. It will look something like this:

private void hitMe(object sender, System.EventArgs e)

{

PictureBox who = (PictureBox) sender;

who.Top = 0;

}

This method receives an object called sender and an event called e. These represent the event that happened to the object and the object itself. This provides the information needed to move the right object back to the top of the form.

The object referred to by sender is cast into a PictureBox to give the program access to the Top property. The base object, called Object, which all other objects are derived from, does not have a Top property. With access to the Top property the assignment statement will put the picture box back at the top of the form. This method (hitMe) should only be used with picture boxes. If a method is written that needs to handle different object types them the GetType method that the Object object supports to determine the type of object to be cast before attempting to process the object.

Once this method is created it must be associated with the individual picture boxes in the array. This is done by adding it as a response to the click event. This can be done using a loop immediately following the addition of the picture boxes into the myBoxes array. This code will look something like the following:

for (int i = 0; i < 4;i++)

myBoxes[i].Click += new System.EventHandler(this.hitMe);

This code adds hitMe as the event handling method for a click event. When any of the objects in the array is clicked the hitMe method will be invoked. If the hitMe method has not been created with the proper parameter list for the event the compiler will generate an error.

Adding Objects at Run-Time

Objects can also be created and added to an array of controls under program control at run-time. A declaration statement and a new statement, such as the one below, will create a new instance of a PictureBox.

PictureBox temp = new System.Windows.Forms.PictureBox();

At this point a new object has been created. The program should then set the properties that determine how and where the object is displayed. The object will become visible on the form when it is added to the list of objects on the form using the Add method. In the statement below, this refers to the form whose initialization code is running.

this.Controls.Add(playSquares[I, J]);

A newly created object can be added to an array of controls at anytime after it has been created. It is fairly common to have all the setup statements executed before adding the object to the array but there is no requirement to do so. Once the object has been added to the array it can be referenced either by its unique name or as a member of the array. There are times when it makes sense to have the objects created, added to an array and than use a loop to make the initial setup of all members of the array at the same time.

 

Identifying Members of an Array of Objects

There are many times when it is useful to identify which specific member of an array is responding to an event. For example, if a change must be made to an object and the objects that follow it in the array the program must be able to identify where in the array the object exists. The Tag property can be used to hold an identifier for this purpose.

The Tag property can hold any object. Because C# treats built-in types such as int and double as objects they can be stored in the Tag property. When an object is added to an array an index value must be used to place the reference in a specific element of that array. A program can copy that index number into the Tag where it can be retrieved later. For example, if an array named playSquares is being used to hold objects the Tag property could be set as follows.

playSquares[J].Tag = J;

This value can be retrieved as an integer using a statement such as that below that casts the tag as an integer.

int who = (int) whoHit.Tag;

Because Tag holds objects the information stored in it can be much more flexible and powerful than if it were limited to integers or even strings. For example the Point object can be used to hold a two dimensional location for two dimensional arrays. For example:

playSquares[I, J].Tag = new Point(I,J);

This places a Point object with both X and Y values in Tag. These values can be used by casting the Tag into a Point object and using the X and Y properties of that object. For example:

Point who = (Point) whoHit.Tag;

int i = who.X;

int j = who.Y;

A programmer could create their own structure to support three (or greater) dimensional arrays. Programmer developed structures could also hold other identifying information besides location. The possibilities are immense.

 

 

Copyright Alfred C Thompson II 2006