Hey all,

I am trying to make a form that is blank and will add in 2 comboboxes, a textbox, 2 buttons and a checkbox next to each other in a row. I want the controls to be part of an array, so that all controls on a row are associated with that array number.

I am currently able to make the first row appear when the form is loaded, however when i click one of the buttons(which are used to create thenext row of controls) it comes up with an error stating that the index was outside the array bounds.

Here is the code I currently have:

Public Class frmWhere

    Public SQLString3 As String
    Public locationy As Integer
    Public DatabaseSource As New AutoCompleteStringCollection

    Dim index As Integer
    Dim btn1(index) As Button
    Dim btn2(index) As Button
    Dim chk(index) As CheckBox
    Dim cbo(index) As ComboBox
    Dim cbo1(index) As ComboBox
    Dim txt(index) As TextBox

    Private Sub frmWhere_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        locationy = 17

        CreateRow(locationy)

        For i = 0 To (frmStart.clbTables.Items.Count - 1)
            DatabaseSource.Add(frmStart.clbTables.Items.Item(i))
        Next

    End Sub

    Private Sub CreateRow(ByVal locationY As Integer)

        cbo1(index) = New ComboBox
        cbo1(index).Name = "cboAttribute" & index
        cbo1(index).Location = New Point(12, locationY)
        cbo1(index).Size = New Size(221, 21)
        cbo1(index).DropDownStyle = ComboBoxStyle.DropDownList
        Me.pnlWhere.Controls.Add(cbo1(index))

        For i = 0 To (frmStart.clbTables.Items.Count - 1)
            cbo1(index).Items.Add(frmStart.clbTables.Items.Item(i))
        Next

        cbo(index) = New ComboBox
        cbo(index).Name = "cboCondition" & index
        cbo(index).Location = New Point(239, locationY)
        cbo(index).Size = New Size(68, 21)
        cbo(index).DropDownStyle = ComboBoxStyle.DropDownList
        Me.pnlWhere.Controls.Add(cbo(index))

        txt(index) = New TextBox
        txt(index).Name = "txtCondition" & index
        txt(index).Location = New Point(313, locationY)
        txt(index).Size = New Size(146, 20)
        txt(index).AutoCompleteCustomSource = DatabaseSource
        txt(index).AutoCompleteMode = AutoCompleteMode.SuggestAppend
        txt(index).AutoCompleteSource = AutoCompleteSource.CustomSource
        Me.pnlWhere.Controls.Add(txt(index))

        btn1(index) = New Button
        btn1(index).Name = "btnAnd" & index
        btn1(index).Text = "AND"
        btn1(index).Location = New Point(465, locationY)
        btn1(index).Size = New Size(40, 23)
        Me.pnlWhere.Controls.Add(btn1(index))
        AddHandler btn1(index).Click, AddressOf btnAnd_Click

        btn2(index) = New Button
        btn2(index).Name = "btnOr" & index
        btn2(index).Text = "OR"
        btn2(index).Location = New Point(511, locationY)
        btn2(index).Size = New Size(40, 23)
        Me.pnlWhere.Controls.Add(btn2(index))
        AddHandler btn2(index).Click, AddressOf btnAnd_Click

        chk(index) = New CheckBox
        chk(index).Name = "chkDelete" & index
        chk(index).Text = "Delete"
        chk(index).Location = New Point(557, locationY)
        chk(index).Size = New Size(57, 17)
        Me.pnlWhere.Controls.Add(chk(index))
        AddHandler chk(index).Click, AddressOf chkDelete_CheckedChanged

        index = index + 1

    End Sub

    Private Sub btnAnd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)

        locationy = locationy + 40

        CreateRow(locationy)

    End Sub

Any help is greatly appreciated :)

Since your Dim index As Integer has no value when the application loads, it is set by default to 0.
.This means that any control array that uses (index), only declares one control.

You have to ReDim the control array for the Index not to be outside the bounds of the array.

Private Sub btnAnd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        ReDim btn1(index), btn2(index), chk(index), cbo(index), cbo1(index), txt(index)
        locationy += 40
        CreateRow(locationy)
    End Sub

Edited 5 Years Ago by codeorder: n/a

There is a difference between index and capacity. To use array, you want to say,

Dim nCap as integer = 1000 ' just for example.
Dim txtArr(nCap) as TextBox

There are different cases in practice.
1. You know the capacity at design time. Like the above, it is 1000, for example
2. You know it later at run time. For example, you get it from user input or read from file. Then you use ReDim.
3. If you will never know the capacity, use List, not Array.

Since your Dim index As Integer has no value when the application loads, it is set by default to 0.
.This means that any control array that uses (index), only declares one control.

You have to ReDim the control array for the Index not to be outside the bounds of the array.

Private Sub btnAnd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        ReDim btn1(index), btn2(index), chk(index), cbo(index), cbo1(index), txt(index)
        locationy += 40
        CreateRow(locationy)
    End Sub

It runs, but ... you may not want to ReDim in a loop of calling the sub. Thanks.

This question has already been answered. Start a new discussion instead.