locked
Problems with getting CheckBox status in 'For Each...' loop RRS feed

  • Question

  • I've used many variation of the 'For Each .....' loop to try and retrieve the CheckState of each CheckBox. Two different version of the code are as follows:

     '************************************************************************
            'This routine gives erratic results when used in a program with
            'other controls on the form.But works fine in a stand alone program
            For Each cntrl In Me.Controls
                If cntrl.name.StartsWith("Check") Then
                    ListBox1.Items.Add(cntrl.Checkstate)
                End If
            Next
            'The following routine does not work in a program with other controls
            'but does work if the CheckBoxes are the only control
            'Dim index As Integer = 0
            'For Each cntrl In Me.Controls
            '    index += 1
            '    If TypeOf cntrl Is CheckBox Then
            '        If cntrl.name.endswith(index.ToString) Then
            '            ListBox1.Items.Add(cntrl.Checkstate)
            '        End If
            '    End If
            'Next
            '*************************************************************************

    Two images follow: The first is the result from a stand alone program (both routines work)(a button and a listbox are the only other control on the form)

    The second image shows the erratic result from a program with other controls on the form (GroupBoxes with TextBoxes and a ListBox)

    Can someone please explain the erratic result and advise as to how it can be corrected? I thought I was pretty familiar with the use of 'For Each....' loops but this one has me baffled! I've tried using different syntax with the loops but each one gives me erratic results similar to the image immediately above.

    Regards Ron


    • Edited by Ron.Sul Wednesday, May 2, 2012 5:50 AM
    Wednesday, May 2, 2012 5:48 AM

Answers

  • Thanks to everyone who has responded. There is obviously a lot of different methods to do the same thing.

    I haven't worked out what was giving me the erroneous result but I did fix the problem by simply deleting the CheckBoxes then re-inserting them onto the form. The following code allows me to read the CheckState, albeit in ascending order and save it to a text file. But fortunately when I read the Checkstate back from the file it too is read in ascending order subsequently resetting the Checkstate as it was. I chose to use the folowing code to read the CheckState because it is simple and I am more familiar with this method. It is no different to the code I originally used that gave me erratic results. Perhaps it had something to do with the Tab order, although I did check that and all was as it should be. The full code listing of where I use it can be seen on the thread 'Saving textbox values to a file to load again' . BTW I still don't know what gave me the erratic result. I also found that when the CheckState is added to a ListBox it shows as either 'Checked' or 'UnChecked'. But save to the Text file it shows as Boolean values; '1' for checked, '0' for Unchecked.

    The code:

    'Save CheckBox status
            For Each cntrl In Me.Controls 'Or if CheckBoxes are in a Panel: e.g."Me.Panel1.Controls
                If TypeOf cntrl Is CheckBox Then
                    FileString &= cntrl.CheckState & ","
                End If
            Next

    Friday, May 4, 2012 6:37 AM

All replies

  • Ron

    Make it yourself more easy (and the program more stable) by putting the checkboxes first in an array

    Dim theCheckBoxArray = {CheckBox1,CheckBox2...........................}
    For each ctr in theCheck...............................


    Success
    Cor


    Wednesday, May 2, 2012 6:53 AM
  • If the check boxes are in group boxes then you have to go down into the group box controls. Your code only deals with controls in the form's controls collection. Some controls, e.g., also have controls collections. For these you need a loop within the form controls loop (or something that does same thing).

    Regards David R
    ---------------------------------------------------------------
    The great thing about Object Oriented code is that it can make small, simple problems look like large, complex ones.
    Object-oriented programming offers a sustainable way to write spaghetti code. - Paul Graham.
    Every program eventually becomes rococo, and then rubble. - Alan Perlis
    The only valid measurement of code quality: WTFs/minute.

    Wednesday, May 2, 2012 6:54 AM
  • Look at your code, again.

    Step through your code.

    Your first example:

     'This routine gives erratic results when used in a program with
            'other controls on the form.But works fine in a stand alone program
            For Each cntrl In Me.Controls
                If cntrl.name.StartsWith("Check") Then
                    ListBox1.Items.Add(cntrl.Checkstate)
                End If
            Next

    If ANY control name starts with 'Check' then it's going to caues an issue: you need to identify that it's a checkbox, and it's the checkbox you want.

    Your second example:

    'The following routine does not work in a program with other controls
            'but does work if the CheckBoxes are the only control
            'Dim index As Integer = 0
            'For Each cntrl In Me.Controls
            '    index += 1
            '    If TypeOf cntrl Is CheckBox Then
            '        If cntrl.name.endswith(index.ToString) Then
            '            ListBox1.Items.Add(cntrl.Checkstate)
            '        End If
            '    End If
            'Next

    Step through it and you'll see that EVERY control it comes across will increment the index counter, not just the check boxes.

    In both cases, you should get errors: it's possible you don't see the errors, depending on your debug settings. This is where stepping through the code helps you to understand what each and every line is doing.

    Typically, you would do what either Cor or David are suggesting:

    • Put all the check boxes in an array of check boxes (they are going to be strongly typed, so will avoid/reduce errors);
    • Put the check boxes in a panel or group box and iterate through the controls in that group box, uniquely identifying the correct control.


    Stephen J Whiteley

    Wednesday, May 2, 2012 3:02 PM
  • Thanks to everyone who has responded.

    The primary reason for my enquiry was that I was helping another forum member regarding saving settings to file. For further info see MrSGW thread on 'Saving textbox values to a file to load again'. It is a current thread. Even so, I'm still having problems with the simplest of For each loops. The following code still produces eratic results:

     For Each cntrl In Me.Controls
                If TypeOf cntrl Is CheckBox Then
                    ListBox1.Items.Add(cntrl.Checkstate)
                End If
            Next


    There are other controls on the form, namely TextBoxes within GroupBoxes but the above For Each code only addresses CheckBoxes.

    The code is obviously reading the CheckBoxes but not in the sequence that I expected. Although I will probably look more closely at Cor's suggestion I would stil like to know why the outcome is out of sequence. BTW on another attempt at trying to sort the problem out I was returned with '0' and '1' for the Checkstate. I would still prefer that to "Checked" and "Unchecked". Another BTW is that sometimes the controls are read bottom up i.e. the last ordered control was read first. Another anomoly that I would like explained. See the thread on 'Saving textbox values to a file to load again' for further evidence of readings goin awry.

    Ron

    Regards Ron

    Edit: I've just tried Cor's suggestion but am getting an error. There is obviously something wrong with the syntax:

     Dim theCheckBoxArray = {CheckBox1, CheckBox2, CheckBox3, CheckBox4, CheckBox5, CheckBox6}
    
    For Each cntrl In theCheckBoxArray
                ListBox1.Items.Add(cntrl.CheckState)
            Next

    This is the problem I am getting:


    • Edited by Ron.Sul Thursday, May 3, 2012 6:12 AM
    Thursday, May 3, 2012 5:52 AM
  • Try something like this one:

    ListBox1.Items.AddRange(Me.Controls.OfType(Of CheckBox).OrderBy(Function(x) x.Name).Select(Function(c) c.CheckState.ToString).ToArray)

    Cheers :)
    ~Ace


    If a post helps you in any way or solves your particular issue, please remember to use the Propose As Answer option or Vote As Helpful
    Visit the Forum: TechLifeForum



    Thursday, May 3, 2012 4:00 PM
  • Hello Ron.Sul

    another system and talk to the elements with the extension method and order with the second method OrderBy property TabIndex.

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
            ListBox1.Items.Clear()
            For Each myCheckBox As CheckBox In GroupBox1.Controls.Cast(Of CheckBox)().OrderBy(Function(a) a.TabIndex)
                ListBox1.Items.Add(myCheckBox.Text & " " & "Checked Value is" & " " & myCheckBox.Checked.ToString)
            Next
        End Sub

    Regards.

    Thursday, May 3, 2012 7:01 PM
  • Thanks to everyone who has responded. There is obviously a lot of different methods to do the same thing.

    I haven't worked out what was giving me the erroneous result but I did fix the problem by simply deleting the CheckBoxes then re-inserting them onto the form. The following code allows me to read the CheckState, albeit in ascending order and save it to a text file. But fortunately when I read the Checkstate back from the file it too is read in ascending order subsequently resetting the Checkstate as it was. I chose to use the folowing code to read the CheckState because it is simple and I am more familiar with this method. It is no different to the code I originally used that gave me erratic results. Perhaps it had something to do with the Tab order, although I did check that and all was as it should be. The full code listing of where I use it can be seen on the thread 'Saving textbox values to a file to load again' . BTW I still don't know what gave me the erratic result. I also found that when the CheckState is added to a ListBox it shows as either 'Checked' or 'UnChecked'. But save to the Text file it shows as Boolean values; '1' for checked, '0' for Unchecked.

    The code:

    'Save CheckBox status
            For Each cntrl In Me.Controls 'Or if CheckBoxes are in a Panel: e.g."Me.Panel1.Controls
                If TypeOf cntrl Is CheckBox Then
                    FileString &= cntrl.CheckState & ","
                End If
            Next

    Friday, May 4, 2012 6:37 AM
  • If you use OfType() like in my example you can avoid that TypeOf if statement :) Just some perhaps useful advice for you to explore.

    http://msdn.microsoft.com/en-us/library/bb360913.aspx#Y0


    If a post helps you in any way or solves your particular issue, please remember to use the Propose As Answer option or Vote As Helpful
    Visit the Forum: TechLifeForum

    Saturday, May 5, 2012 5:49 AM