user2087008
user2087008

Reputation:

For Each Textbox loop returning controls last to first?

I have the following code along with 9 textboxes on a form:

For Each ctrl As Control In Me.Controls
    If TypeName(ctrl) = "TextBox" Then
        If Not ctrl.Text.Length = 0 Then
            MsgBox(ctrl.Name)
        End If
    End If
Next

However if for example 3 of the textboxes are filled, the resulting messageboxes will say:

TextBox3
Textbox2
Textbox1

In that order, bottom to top. Can anybody explain why it is doing this? Is there a simple way to make them return in order first to last?

Upvotes: 1

Views: 4735

Answers (5)

You cant go by the name to determine order, you have to look at the designer file to really see who's on first. For instance:

Me.Button1 = New System.Windows.Forms.Button()
Me.Button2 = New System.Windows.Forms.Button()
Me.Button3 = New System.Windows.Forms.Button()
'...
Me.Controls.Add(Me.Button7)
Me.Controls.Add(Me.Button6)
Me.Controls.Add(Me.Button5)
Me.Controls.Add(Me.Button4)

They will "come back out" seemingly last to first by name, but they are actually in the collection in a meaningful order, namely by z-order:

For Each ctl As Control In Controls
    Console.WriteLine(ctl.Name)
Next
TextBox2.BringToFront()
Console.WriteLine("new order:")
For Each ctl As Control In Controls
    Console.WriteLine(ctl.Name)
Next

Output:

TextBox3
TextBox2
TextBox1
new order:
TextBox2
TextBox3
TextBox1

You can always fetch a control reference by name so the order doesnt much matter:

thisBtn = CType(Controls("Button1"), Button)

If it is important to your code to process some controls in a specific order, you should maintain your own list - either List(Of String) representing the control names or a List(Of TextBox) (for example) to store actual object references:

Private myTBList As New List(Of String)
...
myTbList.Add("TextBox13")
...etc

To process them:

Dim TB As TextBox

For Each s As String In myTBList
    TB = CType(Controls(s), TextBox)
    If TB IsNot Nothing Then
        ' do something wonderful here
    End If
Next

Upvotes: 1

dbasnett
dbasnett

Reputation: 11773

Give this a try. It assumes that you are NOT adding controls at run time.

Dim tbs As New List(Of TextBox)
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
    'this will get all controls including those in
    'containers
    Dim ctrl As Control = Me.GetNextControl(Me, True)
    Do Until ctrl Is Nothing
        If TypeOf ctrl Is TextBox Then
            tbs.Add(DirectCast(ctrl, TextBox))
        End If
        ctrl = Me.GetNextControl(ctrl, True)
    Loop
    tbs = tbs.OrderBy(Function(tb) tb.Name).ToList
End Sub

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    For Each t As TextBox In (From tb As TextBox In tbs Where tb.TextLength > 0 Select tb)
        Debug.WriteLine(t.Name)
    Next
End Sub

Upvotes: 0

ron tornambe
ron tornambe

Reputation: 10780

The order is predetermined by VB.NET. You can set the. BringToFront properties of the controls in reverse order to rectify this functionality. In your example, first click TextBox3 and then in the Format menu, choose Order and select BringToFront. Do the same for TextBox2 and then TextBox1. This isn't elegant, but it does work.

Upvotes: 0

LarsTech
LarsTech

Reputation: 81610

If you want the order to be Top to Bottom, you can sort it that way:

For Each ctrl As TextBox In Me.Controls.OfType(Of TextBox).OrderBy( _
                                               Function(x) x.Top)
  If Not ctrl.Text.Length = 0 Then
    MsgBox(ctrl.Name)
  End If
Next

Upvotes: 2

Rahul
Rahul

Reputation: 77866

I don't think you can control that order. Rather create a list of string. Store the control name then sort it. Display accordingly.

Dim list As List(Of String) = New List(Of String)

For Each ctrl As Control In Me.Controls
    If TypeName(ctrl) = "TextBox" Then
        If Not ctrl.Text.Length = 0 Then
            list.Add(ctrl.Name);
        End If
    End If
Next

list.Sort();

For Each element As String In list
    MsgBox(element)
Next

Upvotes: 0

Related Questions