Looping through Controls
One of the things that I seem to find myself needing to do with each App that I write is at some point in time I will want to Loop trough the Controls on one of my Forms.
There are plenty of ways of doing this and this is how I ended up going about it.
Chances are when you want to do this you will want to Loop through just one Type of Control to make sure that a certain condition is matched. Let’s say, for instance, that we want to make sure that the User has entered something into all the TextBoxes on a Form.
Coming from a VB6 background I started out thinking that this should not be too hard a thing to do. So I tried the following code in a Test App.
Private Sub cmdButton1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdButton1.Click
Dim MyControl As Control ' Decalre Variable to hold the Controls on the Form
For Each MyControl In Me.Controls ' Loop through the Controls on the Form
If TypeOf MyControl Is TextBox Then ' If the Control is a TextBox
If MyControl.Text = "" Then ' If there is no Text in the TextBox
MessageBox.Show("You can not have an empty Textbox." _
Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Exit Sub ' Exit the Sub
End If
End If
Next
End Sub
When I ran the Text App, putting Text in some of the Textboxs and left others blank, and clicked the Button I got the Message Box as I should have. I entered Text in all the TextBoxes, clicked the Button and was rewarded with no Message Box. Great I thought, works like a charm.
I opened up my real App and popped the code in the appripriate place and ran the App. All worked well until it got to checking the TextBoxes. The code only worked on some of the TextBoxes not all of them. Something was wrong, but what. I realized that the TextBoxes that were not being cleared were in a Panel so I had to do a little more research.
What I needed to do was come up with something that would drill down a little further and take into account the fact that some Controls may be Containers for other Controls. After a little bit of research I found the HasChildren Property of Control.
Armed with my new found knowledge, I set forth once again to my test project and added a couple of Frames to my Form and put a couple of TextBoxes into each Frame. I knew that I once I got the clearing of Controls worked out I would want to use it in several places in my Project so I also decided that I needed to make the code reusable, so I decided to put the code in a Sub and call it when I wanted.
Private Sub ClearTextBoxes(ByVal cc As Control)
Dim ctl As Control ' Declare Variable for the Controls on the Form
For Each ctl In cc.Controls ' Loop through the Controls on the Form
If ctl.HasChildren Then ' If the Control is a Container with Controls
ClearTextBoxes(ctl) ' Call the Sub and Loop through all the Controls in the Container
End If
If TypeOf ctl Is TextBox Then
If ctl.Text = "" Then ' If there is no Text in the TextBox
MessageBox.Show("You can not have an empty Textbox." _
Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Exit Sub ' Exit the Sub
End If
End If
Next
End Sub
Now I can just call the Sub and pass the Name of the Control that I want to Loop through the Controls of. (In my Project I use this to Loop through Controls on one Tab of a TabControl.)
Private Sub cmdButton1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdButton1.Click
ClearTextBoxes(TabControl1.TabPages(0)) ' Call the Sub and pass the Parameter.
End Sub
In the example above, the Parameter of the ClearTextBoxes Sub refers to the first Tab on the TabControl on the Form. You can put the name of any Control, or your Form using the Me Keyword, and the Sub will only Loop through the Controls in the Container.