Anyone know how we can cycle through the controls on a form starting left to right ?

dominico

Well-known member
Joined
Mar 9, 2005
Messages
57
Programming Experience
3-5
RESOLVED. Thanks to "jmcilhinney"

Please help me how to cycle through the controls below starting from left to right and then continue to the next row until the end of the form.

The problem is that the controls are not focused in the order from left to right. It starts anywhere on the form. I would like to start with the most left and then one by one toward the right.

Here is my code so far:
Note: I only want to read textboxes and comboboxes.

For I = 1 ToMe.Controls.Count - 1 ' cycle through the controls on the form.
' select only textboxes and comboboxes controls to extract data

If ((TypeOfMe.Controls(I) Is TextBox) Or (TypeOfMe.Controls(I) Is ComboBox)) And (Me.Controls(I).Text <> "") Then

.....

End If


Next I

Thank you everyone,

Dominico
 
Last edited:
If you want to change the order in which the controls are focused, you need to change the TabIndex property of each control. You can do this in the Properties window for each control individually, but the easiest way is to select View -> Tab Order for the main menu. You then click the controls in the order you want them to tab and hit the Escape key when you're done.

What you are asking can be done but it would be a bit fiddly. You would need to get an Array or, preferably, an ArrayList of all the controls that are of the types you want and then compare their Location properties to decide the correct order. The ArrayList class has an overloaded Sort method that you could customise to sort on Location.Y and then Location.X, otherwise you could create your own procedure to apply a sorting algorithm and do the comparisons yourself.
 
jmcilhinney said:
If you want to change the order in which the controls are focused, you need to change the TabIndex property of each control. You can do this in the Properties window for each control individually, but the easiest way is to select View -> Tab Order for the main menu. You then click the controls in the order you want them to tab and hit the Escape key when you're done.

What you are asking can be done but it would be a bit fiddly. You would need to get an Array or, preferably, an ArrayList of all the controls that are of the types you want and then compare their Location properties to decide the correct order. The ArrayList class has an overloaded Sort method that you could customise to sort on Location.Y and then Location.X, otherwise you could create your own procedure to apply a sorting algorithm and do the comparisons yourself.


Thank you jmcilhinney. Looks like I have to create an array like you suggested.

I don't understand why Microsoft couldn't set it up so that we can just use the tab indexes to cycle through controls programatically in any order we want based on the tabindex values. I don't see why they couldn't set it up that way.

Peace,

blumonde
 
You could create a function that would take a control as an argument and return the next control in the tab order. You would have to use the tab indexes of the other controls with the same parent to find the next highest value. If there wasn't one then you would have to look at the parent's sibling controls and so on. Once you've written that function you can just call it whenever you want. You could then cycle through all controls with code like this:
VB.NET:
Dim firstControl As Control = <some control>
Dim currentControl As Control = firstControl

Do
	'Use current control here.

	currentControl = Me.GetNextControl(currentControl)
Loop Until currentControl.Equals(firstControl)
 
jmcilhinney said:
You could create a function that would take a control as an argument and return the next control in the tab order. You would have to use the tab indexes of the other controls with the same parent to find the next highest value. If there wasn't one then you would have to look at the parent's sibling controls and so on. Once you've written that function you can just call it whenever you want. You could then cycle through all controls with code like this:
VB.NET:
Dim firstControl As Control = <some control>
Dim currentControl As Control = firstControl
 
Do
	'Use current control here.
 
	currentControl = Me.GetNextControl(currentControl)
Loop Until currentControl.Equals(firstControl)

Thank you so much jmcilhinney. That is exactly what I was looking foward to do. I guess I wasn't explaining it clearly enough on my first post. My apology.

Your code saves me a lot of time and headaches. Thanks again.

Dominico
 
the same story but different code:
PHP:
PrivateSub Enter_KeyDown(ByVal sender AsObject, ByVal e As System.Windows.Forms.KeyEventArgs) 
If e.KeyCode = Keys.Enter Then 
SendKeys.Send("{TAB}")
 
EndIf
 
EndSub


then in load event just add this:


PHP:
Dim xControl As Control
 
For Each xControl In Me.Controls 
 
AddHandler xControl.KeyDown, AddressOf Enter_KeyDown
 
Next


Aditionally you can check the controls ...
PHP:
If xControl.FieldType.Name.ToLower = "textbox" Or xControl.FieldType.Name.ToLower = "combobox"Then
 
'code from above

Cheers ;)
 
I'm not sure but I didn't get the impression that we actually want to Tab from control to control, but rather do something with each control but in the order defined by the Tab order.
 
oh i see, it seems like i haven't understod well the idea of original threader ... however you can adapt it for the purpose ... i.e.

PHP:
 Dim xControl As Control 
 
For Each xControl In Me.Controls
 
If e.KeyCode = Keys.Enter Then
 
xControl.Text = "something"
 
SendKeys.Send("{TAB}")
 
EndIf
 
Next


Now, if user click Enter (you can change it to be a button or another trigger) it will go through all controls in TabIndex order and change the text .... Cheers ;)
 
kulrom said:
oh i see, it seems like i haven't understod well the idea of original threader ... however you can adapt it for the purpose ... i.e.

PHP:
 Dim xControl As Control 
 
For Each xControl In Me.Controls
 
If e.KeyCode = Keys.Enter Then
 
xControl.Text = "something"
 
SendKeys.Send("{TAB}")
 
EndIf
 
Next


Now, if user click Enter (you can change it to be a button or another trigger) it will go through all controls in TabIndex order and change the text .... Cheers ;)


Hi Kulrom, I will also test out the code above. This is so exciting. There is so much for me to learn from you both. I thank you all for helping me out. You guys are great.

Dominico
 
kulrom said:
oh i see, it seems like i haven't understod well the idea of original threader ... however you can adapt it for the purpose ... i.e.

PHP:
 Dim xControl As Control 
 
For Each xControl In Me.Controls
 
If e.KeyCode = Keys.Enter Then
 
xControl.Text = "something"
 
SendKeys.Send("{TAB}")
 
EndIf
 
Next


Now, if user click Enter (you can change it to be a button or another trigger) it will go through all controls in TabIndex order and change the text .... Cheers ;)


Hi Kurom,

Could you please help me out just a little bit more. I added your code to my button click even and there are 2 problems with the objects in your code. The "e" object doesn't have the method called "Keycode". xControl class doesn't have the "FieldType" method either.

Please advise. Many thanks in advance.

Dominico

Here is my latest code:

Private Sub btGS_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btGS.Click



Dim xControl As Control

For Each xControl In Me.Controls

If e.KeyCode = Keys.Enter Then 'Note: there is no "KeyCode" method to use

'Note: there is no "FieldType" method for the xControl object

If xControl.FieldType.Name.ToLower = "textbox" Or
xControl.FieldType.Name.ToLower = "combobox" Then


xControl.Text = "something"

SendKeys.Send("{TAB}")

End If

End If

Next

End Sub

 
Kulrom's off-line so I'll field this for now.

Notice that Kulrom has put his code in the KeyDown event handler. The "e" argument is of different types for different events. For the Click event, "e" is of type System.EventArgs, which has no KeyCode property. It wouldn't make sense if it did because you have made a mouse-click and not a key-press.

As for FieldInfo, I think Kulrom may have omitted some code because using it is a little more complex than his code suggests. It isn't too difficult, but I'm not sure it would give you exactly what you want anyway. The simplest way to check for specific types would be like this:
VB.NET:
		For Each ctl As Control In Me.Controls
			If TypeOf (ctl) Is TextBox OrElse TypeOf (ctl) Is ComboBox Then
				'Do something here.
			End If
		Next
 
jmcilhinney said:
Kulrom's off-line so I'll field this for now.

Notice that Kulrom has put his code in the KeyDown event handler. The "e" argument is of different types for different events. For the Click event, "e" is of type System.EventArgs, which has no KeyCode property. It wouldn't make sense if it did because you have made a mouse-click and not a key-press.

As for FieldInfo, I think Kulrom may have omitted some code because using it is a little more complex than his code suggests. It isn't too difficult, but I'm not sure it would give you exactly what you want anyway. The simplest way to check for specific types would be like this:
VB.NET:
		For Each ctl As Control In Me.Controls
			If TypeOf (ctl) Is TextBox OrElse TypeOf (ctl) Is ComboBox Then
				'Do something here.
			End If
		Next


Hi Jmcilhinney,

Thanks for letting me know. I used the if statement you posted above. I couldn't test my procedure yet because of the "keycode" problem. Thank you again.

Dominico

ps. I gave you a 100% approval on your rating.
 
Hi Jmcilhinney and Kulrom,

I used the "sendkey(tab)" command and the cursor jumps all over. It doesn't go in the right order I set up in the tab indexes. But when I use the tab key manually, the cursor goes in the right orders.

I am at my wit end.

I don't know if we can accomplish this task because I don't think there is a way for us to do it. Microsoft sucks big time.

If any of you could test it out and see if it can be done, please let me know. Just create a small form with about 5 controls of labels, textboxes and comboboxes. See if you can programatically cycle through them controls in the right orders.

Cheers gentlemen and good luck to us all,

Dominico
 
All SendKeys.Send does is simulate a key press. If you have a TextBox focused and then you click a Button, the Button gets the focus. If the Button's Click event handler then calls SendKeys.Send({TAB}), focus will pass to the control that follows the Button, not the TextBox, in the tab order.
 
Let me get straight exactly what it is that you are trying to accomplish. Are you trying to allow the user to Tab to the next control by pressing a button? If this is the case, here's my advice:

Declare a variable of type Control at class level.
VB.NET:
Private lastFocusedControl As Control
Create an event handler for the LostFocus event and have it handle that event for every control on your form. You can specifically add each control to the Handles clause or you can write a procedure to find every control and add the event handler to them.
VB.NET:
Private Sub Button1_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs)
	Me.lastFocusedControl = DirectCast(sender, Control)
End Sub
Notice that the event handler assigns the control that just lost focus to the lastFocusedControl variable.

In the Click event handler for your button, refocus the control that just lost focus and then send the TAB key press.
VB.NET:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
	If Not Me.lastFocusedControl Is Nothing Then
		Me.lastFocusedControl.Focus()
		SendKeys.Send("{TAB}")
	End If
End Sub

Edit:
Obviously the event handler serves no purpose for controls that cannot be focused, like labels. You can exclude them if you like, and you should for "correctness", but including them will not hurt.
 
Back
Top