Export (0) Print
Expand All
Debugging: Root Out Elusive Production Bugs with These Effective Techniques
Smart Tags: Simplify UI Development with Custom Designer Actions in Visual Studio
Ten Essential Tools: Visual Studio Add-Ins Every Developer Should Download Now
XML Comments: Document Your Code in No Time At All with Macros in Visual Studio
Expand Minimize

Creating Control Arrays in Visual Basic .NET and Visual C# .NET

Visual Studio .NET 2003
 

Matthew A. Stoecker
Visual Studio Team
Microsoft Corporation

January 2002

Summary: This paper shows how to create and manage control arrays with Visual Basic .NET and Visual C# .NET. (11 printed pages)

Contents

Introduction
Prerequisites
Creating the Project
Implementing a Collection
Exposing the Array of Controls
Creating a Common Event Handler
Testing Your Project
Conclusion

Introduction

Arrays provide convenient ways to work with groups of controls that share common functionality. Groups of controls might be used to display related data, or provide related behavior when clicked, for example. Although Visual Basic® .NET and Visual C#® have no inherent support for creating control arrays, you can duplicate all of the functionality of control arrays programmatically. This article will walk you through the creation of a simple component that duplicates control array functionality.

Some of the more useful aspects of control arrays include the following:

  • Accessing a set of controls with the same name by index, allowing you to retrieve and set properties by number and iterate through all the controls in an array. This would typically be done using the following syntax:
    ' Visual Basic pseudo-code
    MyControl(myIndex).MyProperty = myValue
    MyControl(myIndex + 1).MyMethod
    
    // C# pseudo-code
    myControl[myIndex].MyProperty = myValue;
    myControl[myIndex + 1].MyMethod
    
  • Handling events for multiple controls with a single event handler, and retrieving and using the index in those events, as shown in this example:
    ' Visual Basic pseudo-code
    Private Sub MyControl_Click(sender as Object, e as EventArgs)
       Messagebox.Show("You have clicked MyControl number " & _
          MyControl.Index)
    End Sub
    
    // C# pseudo-code
    private void myControl_Click(System.Object sender, System.EventArgs e)
       {
          Messagebox.Show("You have clicked MyControl number " +
             myControl.Index);
       }
    
  • Dynamically adding or removing controls at run time, as shown here:
    ' Visual Basic pseudo-code
    Dim i as Integer
    For i = 1 to 5
       ' Insert code to create controls and assign values to properties.
    Next i
    
    // C# pseudo-code
    for (int i = 1; i < 6; i++)
    {
       // Insert code to create controls and assign values to properties. 
    }
    

Visual Basic .NET and C# allow you to duplicate some of the functionality commonly associated with control arrays. For example, you can use delegates to bind events from multiple controls to a single event handler. However, it might be more convenient to incorporate that functionality into a single dynamic, easy-to-manage component. In this article you will create a component that uses the following:

  • A collection to index and sort your controls. A collection of buttons will be used for demonstration purposes.
  • An event handler to handle the click event from your derived button.
  • Code to allow referencing the control and its members by index.
  • Code to dynamically add and remove controls from your form.

Prerequisites

  • You should be familiar with components and how they work. For more information on component see Programming with Components
  • You should have some understanding of polymorphism. For more information, see Polymorphism in Components.
  • You should have an understanding of Visual Basic .NET or C# .NET syntax.

Creating the Project

In this section, you will create and name your project and add a class to your project. This class will encapsulate the code to implement the control array.

To create the ButtonArrayProject and the ButtonArray component

  1. On the File menu, point to New and then select Project to open the New Project dialog box.
  2. Select the Windows Application project template from the list of Visual Basic or Visual C# projects, and type ButtonArrayProject in the Name box.
  3. From the File menu, choose Save All to save your project.

Implementing a Collection

Your ButtonArray class will handle the tasks of holding and organizing your control array through the implementation of a collection. A collection is an object that contains a list of indexed object variables, as well as methods to add, remove, and otherwise manipulate objects in the collection. In this section, you will create a class that inherits from System.Collections.CollectionBase, a class in the .NET Framework that provides much of the functionality required for collections, and implement methods that will provide the required functionality.

To create your inherited class

  1. From the Project Menu, choose Add Class.
  2. Name your class ButtonArray.vb or ButtonArray.cs, as appropriate.

    The Code Editor for your class opens.

  3. In the class declaration, specify that this class inherits from the .NET Framework System.Collections.CollectionBase class.
    ' Visual Basic
    Public Class ButtonArray
       Inherits System.Collections.CollectionBase
    End Class
    
    // C#
    public class ButtonArray : System.Collections.CollectionBase
    {
       // Code added by designer omitted.
    }
    

The System.Collections.CollectionBase class provides much of the required functionality for your collection. This includes a List object that keeps track of the objects contained by your collection, the Count property, which maintains a total of the objects currently in the collection, and the RemoveAt method, which allows you to remove the object at a particular index. You will make use of each of these when implementing your control-array collection.

Because each control array component will be associated with a single form, you will need to add a field to hold a reference to that form. By creating a private, read-only field to hold that reference, you ensure that each control-array component will be associated with only one form.

To add a private, read-only field to your component.

  • Add the following line immediately inside the class declaration:
    ' Visual Basic
    Private ReadOnly HostForm as System.Windows.Forms.Form
    
    // C#
    private readonly System.Windows.Forms.Form HostForm;
    

The first method you will have to implement in your collection is AddNewButton. This method will create a new button control and add it to the desired form. You will also use this method to set the initial properties for your new button.

To implement the AddNewButton method

  • In the Code Editor for your ButtonArray class, type the following code:
    Public Function AddNewButton() As System.Windows.Forms.Button
       ' Create a new instance of the Button class.
       Dim aButton As New System.Windows.Forms.Button()
       ' Add the button to the collection's internal list.
       Me.List.Add(aButton)
       ' Add the button to the controls collection of the form 
       ' referenced by the HostForm field.
       HostForm.Controls.Add(aButton)
       ' Set intial properties for the button object.
       aButton.Top = Count * 25
       aButton.Left = 100
       aButton.Tag = Me.Count
       aButton.Text = "Button " & Me.Count.ToString
       Return aButton
    End Function
    
    // C# 
    public System.Windows.Forms.Button AddNewButton()
    {
       // Create a new instance of the Button class.
       System.Windows.Forms.Button aButton = new 
          System.Windows.Forms.Button();
       // Add the button to the collection's internal list.
       this.List.Add(aButton);
       // Add the button to the controls collection of the form 
       // referenced by the HostForm field.
       HostForm.Controls.Add(aButton);
       // Set intial properties for the button object.
       aButton.Top = Count * 25;
       aButton.Left = 100;
       aButton.Tag = this.Count;
       aButton.Text = "Button " + this.Count.ToString();
       return aButton;
    }
    

This method:

  1. Creates a new button.
  2. Adds it to the internal list and to the controls collection of the form referenced by HostForm.
  3. Sets initial properties, including setting the Tag property to the index of the button. You would add code in this section to set additional properties for your control.
  4. Returns the new button so that it can be immediately modified or assigned to an additional object reference.

You must also create a constructor (the method that is run when your component is instantiated) that sets the value of the HostForm field and automatically adds a new button to your form whenever a new instance of your control array class was created. You would accomplish this in the following manner.

To create the constructor

  • Create a constructor for your class.
    ' Visual Basic
    Public Sub New(ByVal host as System.Windows.Forms.Form)
       HostForm = host
       Me.AddNewButton()
    End Sub
    
    // C# 
    // Replace the default constructor with this one.
    public ButtonArray(System.Windows.Forms.Form host)
    {
       HostForm = host;
       this.AddNewButton();
    }
    

    The constructor requires a parameter, the form on which your button array is to be placed. It assigns the value supplied to the HostForm field, and then invokes the AddNewButton method of the class to add a new button to the form.

Exposing the Array of Controls

Now that you have created a way to create and track the controls in your array, you need to be able to expose them to other developers. You can do this with a property. You will create a default property (Visual Basic) or indexer (C#) that returns a reference to a particular button, based on its index. This will also allow you to programmatically use the MyButtonArray(myIndex) syntax that is typical of control arrays.

To create the default property

  • Add the following code to your component.
    ' Visual Basic
    Default Public ReadOnly Property Item(ByVal Index As Integer) As _
       System.Windows.Forms.Button
       Get
          Return CType(Me.List.Item(Index), System.Windows.Forms.Button)
       End Get
    End Property
    
    // C#
    public System.Windows.Forms.Button this [int Index]
    {
    get
       {
          return (System.Windows.Forms.Button) this.List[Index];
       }
    }
    

Implementing a Remove Method

Now that you have created a property for exposing the buttons in your array, you can implement a mechanism for removing buttons from the array. To remove a button from the array, you must remove it from the collection's internal List object and from the form's Controls collection.

To implement the Remove method

  • Add the following method to your component.
    ' Visual Basic
    Public Sub Remove()
       ' Check to be sure there is a button to remove.
       If Me.Count > 0 Then
          ' Remove the last button added to the array from the host form 
          ' controls collection. Note the use of the default property in 
          ' accessing the array.
          HostForm.Controls.Remove(Me(Me.Count -1))
          Me.List.RemoveAt(Me.Count -1)
       End If
    End Sub
    
    // C#
    public void Remove()
    {
       // Check to be sure there is a button to remove.
       if (this.Count > 0)
       {
          // Remove the last button added to the array from the host form 
          // controls collection. Note the use of the indexer in accessing 
          // the array.
          HostForm.Controls.Remove(this[this.Count -1]);
          this.List.RemoveAt(this.Count -1);
       }
    }
    

Creating a Common Event Handler

The last step is to create event handlers to handle the common events for your array. In this demonstration, you will create a method to handle the click event of your button, and then add code to associate the event with the event handler.

To create a common event handler

  • Add the following method to your component.
    ' Visual Basic
    Public Sub ClickHandler(ByVal sender As Object, ByVal e As _
       System.EventArgs)
       MessageBox.Show("you have clicked button " & CType(CType(sender, _
          System.Windows.Forms.Button).Tag, String))
    End Sub
    
    // C#
    public void ClickHandler(Object sender, System.EventArgs e)
    {
       System.Windows.Forms.MessageBox.Show("You have clicked button " + 
          ((System.Windows.Forms.Button) sender).Tag.ToString());
    }
    

    This method displays a message box indicating what button was clicked by retrieving the index stored in the Tag property of the button. Note that the signature of this method is the same as that of the event it will be handling, as is required for event handlers.

You also need to associate the event with the event handler.

To associate the event with the event handler

  • Add the following code to your AddNewButton method.
    ' Visual Basic
    AddHandler aButton.Click, AddressOf ClickHandler
    
    // C#
    aButton.Click += new System.EventHandler(ClickHandler);
    

Testing Your Project

Now that your component is complete, you need to create an application that tests the functionality of your component.

To create the test application

  1. In Solution Explorer, right-click Form1 and select View Designer from the shortcut menu.

    The designer for Form1 opens.

  2. From the Toolbox, add two buttons to the form.
  3. Relocate these buttons to the right side of the form.
  4. Set the properties of these buttons as follows.
    Button Name Text
    Button1 btnAdd Add Button
    Button2 btnRemove Remove Button
  5. In Solution Explorer, right-click Form1 and select View Code from the shortcut menu.

    The Code Editor for Form1 opens.

  6. Within the class declaration for Form1, declare the control-array object.
    ' Visual Basic
    ' Declare a new ButtonArray object.
    Dim MyControlArray as ButtonArray
    
    // C#
    // Declare a new ButtonArray object.
    ButtonArray MyControlArray;
    
  7. In the constructor of the form, just before the end of the method, add the following code:
    ' Visual Basic
    MyControlArray = New ButtonArray(Me)
    
    // C#
    MyControlArray = new ButtonArray(this);
    

    This statement creates a new ButtonArray object. The parameter (Me or this) refers to the form that is creating the new ButtonArray, and will be the form that the array of buttons will be placed upon.

    Note:    In Visual Basic .NET, the constructor is found in the code region labeled "Windows Form Designer generated code". You might need to expand this region to view the constructor.
  8. In Solution Explorer, right-click Form1 and select View Designer from the shortcut menu.
  9. In the designer, double-click btnAdd to open the Code Editor at the btnAdd_Click event.
  10. In the btnAdd_Click method, add code to call the AddNewButton method of MyControlArray:
    ' Visual Basic
    ' Call the AddNewButton method of MyControlArray.
    MyControlArray.AddNewButton()
    ' Change the BackColor property of the Button 0. 
    MyControlArray(0).BackColor = System.Drawing.Color.Red
    
    // C#
    // Call the AddNewButton method of MyControlArray.
    MyControlArray.AddNewButton();
    // Change the BackColor property of the Button 0.
    MyControlArray[0].BackColor = System.Drawing.Color.Red;
    
  11. In Solution Explorer, right-click Form1 and select View Designer from the shortcut menu.
  12. In the designer, double-click btnRemove to open the Code Editor at the btnRemove_Click event.
  13. In the btnRemove_Click method, add the following code:
    ' Visual Basic
    ' Call the Remove method of MyControlArray.
    MyControlArray.Remove()
    
    // C#
    // Call the Remove method of MyControlArray.
    MyControlArray.Remove();
    
  14. Save your project.

To test your project

  1. From the Debug menu, choose Start.

    Form1 opens with three buttons on it, labeled Add Button, Remove Button, and Button 1.

  2. Click Button 1.

    Note that a message box is displayed, and that this message box correctly displays the index.

  3. Click the Add Button button a few times.

    With each click, a new button is added to the form. Clicking each of these new buttons results a message box that correctly reports the index of the button. Note also that the color of Button 0 has changed to red, resulting from this line in the btnAdd_Click event:

    MyControlArray(0).BackColor = System.Drawing.Color.Red
    
  4. Click the Remove Button button several times.

    With each click, a button is removed from the form.

  5. Click this button until all the buttons on the left-hand side of the form are removed.
  6. Click the Add Button button again.

    Buttons are again added to the form and are numbered with the correct index.

Conclusion

This article has demonstrated how to create a component that encapsulates the functionality of a control array. You have seen how to create methods to dynamically add and remove controls from a form, and to expose an object through a default property or indexer. Because you implement all of the functionality, you can extend your control array by writing custom code for your component.

Show:
© 2014 Microsoft