Reputation:
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
Reputation: 38875
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
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
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
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
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