Going through controls in order - vb.net

I'm creating an XML file with the text fields of a form. When I go through them using a For Each loop:
For each Ctrl in Me.Controls
'dosomething
Next
it doesn't take them in order; that is, it first takes the TextBox in the middle, then the first one, then another and it keeps going that way.
Is there a way where I can take the values in order?

Me.Controls contains the controls in the order they were created.
To change that, select the first control (in the designer), click Send to Back, and repeat.

You could order by TabIndex:
Dim allTextBoxes = From txt In Me.Controls.OfType(Of TextBox)()
Order By txt.TabIndex
Another way is to order by the location:
allTextBoxes = From txt In Me.Controls.OfType(Of TextBox)()
Order By txt.Location.Y, txt.Location.X
For Each txt In allTextBoxes
' ...
Next

This might work for you. Not a VB guy but this is my attempt at ordering the controls by their location, top to bottom.
... Me.Controls.OrderBy(Function(c) c.Location.Y)

Related

Me.Controls does not find all controls on the form

I have a form that takes a list of search terms, and creates a combo box for each result set. The boxes get created at runtime, they are all individually named, and are all directly on the form, none are in panels or any sub controls.
I want to remove the previous searchs combo boxes every time a new search is done. I made the following sub to remove all combo boxes
For Each c As Control In Me.Controls
If c.GetType Is GetType(ComboBox) Then
Me.Controls.Remove(c)
c.Dispose()
End If
Next c
But for some mysterious reason, the Form doesn't see all the combo boxes the previous search created. If I create 3 boxes, it will see the first and third, but not the second. If I run the sub again, it will see the second one and catch it that time. So I need to run the sub twice to actually clear out all the comboboxes that were created. I checked the control collection and it seems to always be 1 short of the actual number of combo boxes that were created in the previous search
Any idea why it is always leaving a combo box behind and I need to clear them all again a second time to get rid of it?
Further to what Jimi said in the comments, I would recommend that you use this:
For Each cmbx In Controls.OfType(Of ComboBox)().ToArray()
cmbx.Dispose()
Next
The OfType does the filtering first and then the ToArray creates an array that you can loop over, so you're not enumerating and modifying a collection at the same time. There's no point removing and disposing the controls because disposing will implicitly remove them.

How to change the order controls are read in .Net?

I have a very textbox rich heavy panel (approx ~ 25 textboxes) for which I want to retrieve all my text from.
I've done so using this loop.
Dim AllItemsArray As New ArrayList
For Each txt As Control In Panel2.Controls
If txt.GetType Is GetType(TextBox) Then
AllItemsArray.Add(txt.Text)
End If
Next
However, for some odd reason it reads the textboxes in a completly random order which makes using the information extremely difficult.
I thought that the textboxes were read in the order they are made, but so far it hasn't done so.
Does anyone have any suggestions as to how I can alter it so that it reads the textboxes in order?
IE. textbox1.text, textbox2.text ...etc
and not
textbox5.text, textbox2.text, textbox 20 ....etc
Thanks
This gets the controls in Tab order sequence. It also gets controls that are in containers, i.e. GroupBox.
Dim ctrl As Control = Me.GetNextControl(ctrl, True)
Do While ctrl IsNot Nothing
Debug.WriteLine(ctrl.Name)
ctrl = Me.GetNextControl(ctrl, True)
Loop

vb.net Loop through Controls on Form and if ListView Loop through Columns and Rows

I have 3 ListViews in a UserForm and also a few other items. Currently when I expand the UserForm, the ListViews and other items expand in relation to the increase in size of the UserForm.
What I'm after doing is also expanding the size of the Columns within the ListViews by cycling through all Controls on the UserForm and checking if it is a ListView, then cycling through all the columns and extending as required.
This is where I am currently at...
For Each Ctrl As Control In Me.Controls
If (TypeOf Ctrl Is ListView) Then
' This is where I'm not sure what to do!
' I want to loop through this Ctrl and view its columns
End If
Next
Anyone any ideas?
If Plutonix' suggestion of enabled auto-resizing columns doesn't work, then read on...
To access the control's properties, you'll need to cast it to ListView first (so far you've only checked to see if it is a ListView. Then, you can loop through the rows and columns:
For Each Ctrl As Control In Me.Controls
If TypeOf Ctrl Is ListView Then
Dim currentListView As ListView = DirectCast(Ctrl, ListView)
' Loop over the rows (items) in the view
For Each item As ListViewItem In currentListView.Items
Next
End If
Next
You might also end up needing a recursive control search -- your current loop will only look for controls that are a direct child of Me.
Another idea: simply return controls of the correct type in the outer for-loop:
For Each listViewControl As Control In Me.Controls.OfType(Of ListView)()
For Each item As ListViewItem In listViewControl.Items
Next
Next

Typing filename in ListBox

when I wish to type the name of a listbox item (the listbox is populated by files in a directory), for example, if I type "apples" pressing A would take me to the first object with A in it's name, but typing "p" after will take me to the first item with p as the first letter. Is there any way I can make it so I can type a few characters and it would take me to that specific item? For example, the list might have;
ability
idea
boring
typing "abi" would select ability, rather than "ability", then "boring", then "idea"
Any help is appreciated. Thanks.
I think it's possible to make System.Windows.Forms.ListBox behave like that, but it would take some non-trivial code to make it work. System.Windows.Forms.ListView has this behavior built-in, so I would suggest using a ListView instead of a ListBox.
' Hide the headers to make the ListView look like a ListBox.
Me.ListView1.View = View.Details
Me.ListView1.HeaderStyle = ColumnHeaderStyle.None
Me.ListView1.BeginUpdate()
Try
' System.Windows.Forms.ListView doesn't have data binding capability.
' The listview's items have to be added using its
' Items.Add, Items.AddRange or Items.Insert methods.
For Each filename As String In Directory.GetFiles("C:\Windows").Select(Function(s) Path.GetFileName(s))
Me.ListView1.Items.Add(filename)
Next
Finally
Me.ListView1.EndUpdate()
End Try
' Add the column after adding the items.
' Setting column width to -1 will make
' the column autosize itself to the longest item.
Dim columnHeader As New ColumnHeader
columnHeader.Width = -1
Me.ListView1.Columns.Add(columnHeader)

how to clear all tools in the vb.net from

i have used many of the controls in vb.net forms, including a textbox and combobox, but I want to clear all my text boxes at once, while not typing textbox1.clear() for each one.
Is there any other way to clear all my textboxes?
If I understand you question right, you should be able to loop through all the controls on your form and check to see what Control type they are. Based on their type, either set the textbox Text property to String.Empty, or your ComboBox to the index of a blank ListItem (presumably item zero).
Something like:
For Each ctrl As Control In Me.Controls
If TypeOf ctrl Is TextBox Then
CType(ctrl, TextBox).Text = String.Empty
Else
' do something similar for your ComboBox
End If
Next
You can parse through each control on your form and test what type of control that is and handle each type separately, but it is easier to simply set each control manually.
Consider writing a ClearForm routine that does all of this, that way all you have to do is call the method.