Click here to Skip to main content
15,881,938 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello.

Well, I have a form loaded with lots of (Label/TextBox)s, and i have a color switch option in the form, And I'm using the simple code which is this:
VB
TLab.ForeColor = My.Settings.B
HLine1.BackColor = My.Settings.B
HLine2.BackColor = My.Settings.B
UpdateLog.ForeColor = My.Settings.B

*That's only 4 Controls, I have nearly 90 controls to change.

As you can see I'm not only changing a label's BackColor, But I'm also changing the ForeColor of a diffident label or textbox.

What I have tried:

So i was thinking about a loop or something simple. like the following :D:
VB
Dim Obj = {TLab.ForeColor, HLine1.BackColor, HLine2.BackColor, UpdateLog.ForeColor}
For Each NC In Obj
    NC = My.Settings.B
Next


Thanks in Advance :)
Posted
Updated 14-Aug-20 8:23am

You can enumerate the controls in a form without keeping a separate list of objects.

Probably best done as a recursive function as you can have container controls inside container controls and the example below only goes two deep.

VB
For Each x As Control In form1.Controls
           If x.HasChildren Then
           '
           ' Enumerate a containers controls
           '
               For Each z As Control In x.Controls
                       If TypeOf (z) Is CheckBox Then
                           ' Do what you want with a checkbox
                       ElseIf TypeOf (z) Is TextBox Then
                           ' etc.
                       ElseIf TypeOf (z) Is NumericUpDown Then
                           'etc.
                       ElseIf TypeOf (z) Is ComboBox Then
                           ' etc.
                       End If
           else
           '
           ' Not a container control, handle it
           '
              If TypeOf (z) Is CheckBox Then
                     ' Do what you want with a checkbox
              ElseIf TypeOf (z) Is TextBox Then
                     ' etc.
              ElseIf TypeOf (z) Is NumericUpDown Then
                     'etc.
              ElseIf TypeOf (z) Is ComboBox Then
                     ' etc.
              End If
           end if
 Next
 
Share this answer
 
v2
Comments
Fa3o 2-Mar-16 16:11pm    
Thanks for your time to reply, I'm actually using this code:
For Each ctrl As Control In Controls
ctrl.BackColor = My.Settings.MCB
ctrl.ForeColor = My.Settings.MCF
Next

as you know it will change all controls to the desirable color, But there is a few other labels or textboxes that it shouldn't change, That's why I'm trying to change the color back or to another for the selected controls like this :

Dim Obj = {TLab.ForeColor, HLine1.BackColor, HLine2.BackColor, UpdateLog.ForeColor}

if there isn't a solution that's ok with me, i could just use the old codes.

Thanks again.

Michael_Davies 2-Mar-16 16:13pm    
In which case a few methods:

Use the name of the control to indicate do not touch, use a prefix and test the name before setting colour.

or

Use the Tag field of the control, give the tag a value for fields you do not want to change then test the controls Tag and leave it if the Tag is not nothing.
Fa3o 19-Mar-16 9:56am    
Sorry For not replying early, But i did as you advised i used the "Tag" tip.
For Each ctrl As Control In Controls
If ctrl.Tag = "BCCC" Then ctrl.BackColor = My.Settings.B
If ctrl.Tag = "FCCC" Then ctrl.ForeColor = My.Settings.B
Next

Thanks :D
Michael presents a very good solution. However, you can shorten your code if all of the controls are of a certain type using the OfType(Of Type) parameter. Labels are not Container Controls so the recursive function below is pointless, but you can use it for any control type you want.
VB
' Put function in a sub using the parent control as a parameter so that the routine may be used for other objects. e.g. Pass Panel1 as MainParent and it will only affect the controls inside Panel1
Public Sub ChangeLabelColors(ByRef MainParent as Control)

' Check if there are any controls to change
If Not MainParent.HasChildren Then Exit Sub

'Use OfType to only enumerate Label controls
For Each x as Label in MainParent.Controls.OfType(Of Label)
    ' Recursively call the function for child container controls
    If x.HasChildren Then ChangeLabelColors(x)
    
    ' Assuming you are using Michael's tag suggestion indication not to change that control's color (Very good idea), this will skip controls with the .Tag "Don't Change Me"
    If Not x.Tag = "Don't Change Me" Then 
        x.BackColor = My.Settings.MCB
        x.ForeColor = My.Settings.MCF
    End If
Next

End Sub


Simply call:
VB
ChangeLabelColors(Me)


Alternatively, this can be modified to allow you to filter the type as well. This is basically Michael's solution that now allows recursion. I also used Select Case by choice, I believe it be faster (Not sure about that)

VB
Public Sub ChangeControlColors(ByRef MainParent as Control)
 
If Not MainParent.HasChildren Then Exit Sub
 
For Each x as Control in MainParent.Controls()

    Select Case True
        Case TypeOf x Is Label, TypeOf x is Checkbox, TypeOf x is Panel
            If x.HasChildren Then ChangeControlColors(x) 
            If Not x.Tag = "Don't Change Me" Then
                x.BackColor = My.Settings.MCB
                x.ForeColor = My.Settings.MCF
            End If
    End Select
Next
 
End Sub
 
Share this answer
 
v2
Comments
Fa3o 19-Mar-16 9:58am    
Yes, I did as your and Mr.Michael advice. and it did work, Thanks :D
Dim rnd as New Random

If Label1.ForeColor = Visible Then
Label1.FolorColor = Invisible
Else
Label1.ForColor = Color.FromArgb(rnd.Next(256), rnd.Next(256), rnd.Next(256))
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900