How to write a sub for several checkboxes at once

Hello,

I am brand new to visual basic, so please excuse me if this is an easy question. I have a form with several checkboxes. I want to make it so that if any checkbox is checked, its label goes from gray to black. I have figured out how to do it for one checkbox, but I can't figure out how to handle many at the same time. Here is what I have so far:

Private Sub sidingStyle1Include_cb_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles sidingStyle1Include_cb.CheckedChanged

If (Style1Include_cb.Checked = True) Then

Style1Include_cb.ForeColor = Color.Black

' If CheckBox is unchecked then set text to grey.

ElseIf ( Style1Include_cb.Checked = False) Then

Style1Include_cb.ForeColor = Color.Gray

End If

Thank you for any guidance



Answer this question

How to write a sub for several checkboxes at once

  • TomChung

    Hi ECList,

    You don't need to give the groupbox tag names (atleast not for this purpose). A groupbox is a container control just like a form (and panel control, etc). So, the controls in within your groupbox will be part of the groupbox's Controls collection. Here's how you would do it:

    If chkBox.Checked Then
    chkBox.ForeColor = Color.Black
    For
    Each ctrl As Control In Me.projectType_tab.SelectedTab.Controls
    If TypeOf ctrl Is GroupBox Then
    For Each ctrl2 As Control In ctrl.Controls
    If ctrl2.Tag = chkBox.Tag Then
    ctrl2.ForeColor = Color.Black
    End If
    Next ctrl2
    End If
    'If there are textboxes outside of a groupbox
    If
    ctrl.Tag = chkBox.Tag Then
    ctrl.ForeColor = Color.Black

    End
    If
    Next ctrl
    End If

    Hope that helps,
    Imran.

  • MattMorg

    Imran, Thank you again for helping on this issue. I think your idea is pretty good if there is really no way to dynamically evaluate variables in VB (is that correct ). I still have a problem though.

    I wanted to take your idea of using tags a step further by just looping through all the controls and setting the color of any control that has a matching tag name. The problem I am running into though is that my form has a group of tabs on it and inside the tabs are 8 group boxes. From what I can tell using the code above, only the controls that aren't inside the tab group are looped through. So I added the name of the tab group into the designator for the controls, but then I found that it doesn't look inside the groups--it only loops through the names of the group boxes...and that's where I am stuck. I have given the group boxes the same tags as the controls inside the group boxes, but I still don't know how to tell VB to look at the controls inside of those group boxes OR to look at every control on the entire form:

    If chkBox.Checked Then

    chkBox.ForeColor = Color.Black

    For Each ctrl As Control In Me.projectType_tab.SelectedTab.Controls

    If ctrl.Tag = chkBox.Tag Then

    ctrl.ForeColor = Color.Black

    End If

    Next

    Thank you again


  • Sudeep Ghosh

    That worked great. Thank you again.


  • Lars Kjeldsen

    Hey SJWhiteley,

    On first look, I thought that would be a nice idea. But taking a look again at what the OP is trying to achieve, it may or may not be what the OP's looking for. Even with a second handler for each individual checkbox, you would still need to know what textboxes need to have their color changed. The second event handler doesn't really buy you a whole lot except that it would avoid the if-else (or select case) statement in the single event handler. The OP would still have to "know" what textboxes need to have their color changed for a particular checkbox. By setting the Tag, you'd have a more generic way of handling this since you would not have to do txtBox.ForeColor = Color.Black for all the textboxes that need the color changed. Of course, if there's only say 1 or 2 textboxes, both yours and mine would simply be an added overhead.

    Imran.

  • NJCLC

    Hi ECList,

    One way to accomplish this would be to use the Tag property of the TextBoxes. So, say you have 3 textboxes which need to change color basesd on the whether or not CheckBox1 is checked. Set it's Tag property to "CheckBox1" and then in your code - rather in your CheckedChanged handler, you can do this:

    If Object.ReferenceEquals(chkBox, CheckBox1) Then
    For
    Each ctrl As Control In Me.Controls
    If
    TypeOf ctrl Is TextBox AndAlso _
    CStr
    (ctrl.Tag) = "CheckBox1" Then
    'change color of this textbox
    End
    If
    Next
    End
    If

    That's not a whole lot better but certainly better than doing it all in code.

    hope that helps,
    Imran.

  • AnurRS

    I have a question about this routine:

    Private Sub CheckBox_CheckedChanged(ByVal sender As System.Object, _

                ByVal e As System.EventArgs) Handles CheckBox1.CheckedChanged, _

                CheckBox2.CheckedChanged, CheckBox3.CheckedChanged

      Dim chkBox As CheckBox = DirectCast(sender, CheckBox)

      If chkBox.Checked Then

        chkBox.ForeColor = Color.Black

      Else

        chkBox.ForeColor = Color.Gray

      End If

    End Sub

     

    Is there a way to get the name of which of the checkboxes is being handled   I'd like to change the color of some textbox fields that go along with each checkbox, so I figure if I know which checkbox is being handled by name, I can determine which other fields to work with based on that name.  The thing is, I know I can just reference "chkBox.Name" to get the name of that box, but then how would I go about dynamically creating the names of the related textboxes.

     

    So when

     

    car_Enabled_cb is turned on, I would also want to change car_Name_tb,car_Brand_tb and car_Engine_tb

     

    Do I have to just bite the bullet and use an IF statement to check which one is turned on and then deal with the text boxes or can I somehow do this dynamically

     

    Thanks


  • sunarc

    You are right, Imran.

    The reason I thoughtof it that way is that you only have to look at code to see which checkbox is doing what, and not transition back to the designer to see what each text box tag setting is. Personal preference for me, I suppose. However, having said that, you could set the tags programmatically, too .



  • Manidkn

    Sorry to interrupt, but instead of using the tag property (which is a real nice idea), you can add multiple handlers for events.

    Something like:

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Dim
    ctl As Control
    For Each ctl In Me
    .Controls
    If TypeOf ctl Is CheckBox
    Then
    Debug.WriteLine(ctl.Name)
    AddHandler DirectCast(ctl, CheckBox).CheckedChanged, AddressOf
    ACheckboxChanged
    '
    '---- Add logic here ----
    If ctl.Name = "CheckBox1"
    Then
    AddHandler DirectCast(ctl, CheckBox).CheckedChanged, AddressOf
    CheckBox1Stuff
    End
    If
    End
    If
    Next
    End
    Sub

    Private
    Sub ACheckboxChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
    Debug.WriteLine(DirectCast
    (sender, CheckBox).Name)
    End
    Sub

    Private Sub CheckBox1Stuff(ByVal sender As System.Object, ByVal e As
    System.EventArgs)
    Debug.WriteLine("Checkbox 1 state changed"
    )
    End Sub

    Both event handlers would fire when checkbox1 value changes. Then you can have a routine to set the text values as appropriately (You can even have many event handlers per control - don't know if there's a limit, but it'd be interesting to find out!)



  • quangphuong

    You can keep the routine you have just the way it is. If you have all the checkboxes on the form at design time, you can add each checkbox after the first like this

    ... Handles sidingStyle1Include_cb.CheckedChanged, OtherCheckBox.CheckedChanged, ...

    If not, you will need to add event handlers as part of the code where you make the checkbox. The code for that would look something like this:

    Dim cb As New CheckBox
    AddHandler cb.CheckedChanged, AddressOf sidingStyle1Include_cb_CheckedChanged
    Me.Controls.Add(cb)


  • Clare North

    Hi ECList,

    There are couple of ways to do this. Note that you can have just one handler for multiple events as long as the events have the same method signatures. So, in your case, since you need to write the same handler for all your checkboxes, here's one way you could do it:

    Private Sub CheckBox_CheckedChanged(ByVal sender As System.Object, _

    ByVal e As System.EventArgs) Handles CheckBox1.CheckedChanged, _

    CheckBox2.CheckedChanged, CheckBox3.CheckedChanged

    Dim chkBox As CheckBox = DirectCast(sender, CheckBox)

    If chkBox.Checked Then

    chkBox.ForeColor = Color.Black

    Else

    chkBox.ForeColor = Color.Gray

    End If

    End Sub


    Note the way you can add the events you want handled after the "Handles" keyword by your handler CheckBox_CheckedChanged. Another way to do it is using the AddHanlder keyword. You can attach your handler to the CheckedChanged event of all your checkboxes in the Form_Load. The functionality remains the same. Here's the code for that:

    Private Sub Form1_Load(ByVal sender As System.Object, _

    ByVal e As System.EventArgs) Handles MyBase.Load

    AddHandler CheckBox1.CheckedChanged, AddressOf CheckBox1_CheckedChanged

    AddHandler CheckBox2.CheckedChanged, AddressOf CheckBox1_CheckedChanged

    AddHandler CheckBox3.CheckedChanged, AddressOf CheckBox1_CheckedChanged

    End Sub

    Private Sub CheckBox1_CheckedChanged(ByVal sender As System.Object, _

    ByVal e As System.EventArgs)

    Dim chkBox As CheckBox = DirectCast(sender, CheckBox)

    If chkBox.Checked Then

    chkBox.ForeColor = Color.Black

    Else

    chkBox.ForeColor = Color.Gray

    End If

    End Sub

    If you have a lot of checkboxes and you're sure you need to add the same handler for all of them, you could something like this:

    For Each ctrl As Control In Me.Controls

    If TypeOf ctrl Is CheckBox Then

    AddHandler DirectCast(ctrl, CheckBox).CheckedChanged, _

    AddressOf CheckBox1_CheckedChanged

    End If

    Next


    If you have a panel (or some other container control) on which those checkboxes are placed, make sure to recursively look through its child controls as well (that is, only if you need to attach the handler).


    hope that helps,

    Imran.


  • How to write a sub for several checkboxes at once