If multiple checkboxes are checked then copy the checkbox text and label text

Answered If multiple checkboxes are checked then copy the checkbox text and label text

  • Saturday, April 28, 2012 11:18 PM
     
     

    I would like to know if there was a way to loop through all the checkboxes on a form and if the checkbox is checked then I need it to copy the text from the checkbox and the label. Thera are 23 of these labels with two checkboxes for each.

    such as.

    1.Are you older than 18?                            Yes No

    2.Do you like dogs?                                    Yes No

     and so on.

    I need to be able to paste this in notepad and have it formated as such

    Yes 1. Are you older than 18?

    No 2. Do you like dogs?

All Replies

  • Sunday, April 29, 2012 12:28 AM
     
     Answered Has Code

    Sure there's a way.  Every control has a Controls property which is a collection of Control objects.  Since a form is a control then you only need to loop through the collection to find all the checkboxes.  Beware that all controls will be in the collection so you need to test if the current control in your loop is a checkbox or not.  Once you can determine that then you access all the properties of that checkbox and write the data to the file.  Here is some code to illustrate that:

            For Each c As Control In Me.Controls
                If TypeOf (c) Is CheckBox Then
                    Dim chkbox As CheckBox = CType(c, CheckBox)
                    Debug.WriteLine(String.Format("Checkbox {0} has a checked state of {1}.", chkbox.Name, chkbox.Checked.ToString))
                End If
            Next

    Please remember that not all controls on a form are children directly of the form - so if you have the checkboxes in a panel then you need to loop through the conrols collection of that panel.  If you have the checkboxes across multiple panels then you would need to access each panel's collection independently.  If yu needed to find all the checkboxes across the entire form (including those not related to your questions) and need to look within the controls collection of all nested controls then you would want to use a recursive method.  here's how that might look based on my previous example:

        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            'Begin the search for all checkboxes on the form.
            RecursiveControlSearch(Me)
        End Sub
    
        Private Sub RecursiveControlSearch(ctrl As Control)
    
            If TypeOf (ctrl) Is CheckBox Then
                Dim chkbox As CheckBox = CType(ctrl, CheckBox)
                Debug.WriteLine(String.Format("Checkbox {0} has a checked state of {1}.", chkbox.Name, chkbox.Checked.ToString))
            End If
    
            'Loop through the child controls recursively by calling this method from within itself.
            For Each c As Control In ctrl.Controls
                RecursiveControlSearch(c)
            Next
    
        End Sub

  • Sunday, April 29, 2012 12:46 AM
     
     Answered Has Code

    Hello,

    A better method would be to (if open to this) use a DataGridView, column 1 the question number, column 2 the question text, column 3 yes/no. A comma delimited text file is read in on form load. In the submit button your results are gathered from the underlying data, not the cells in the DataGridView and set to the clipboard. Again, this is an alternate idea which seems easier than it would be for labels and check boxes.

    Form code

    ''' <summary>
    ''' Requires a DataGridView and a Command button
    ''' Set the following in the IDE for the DataGridView
    ''' Enable Add    = False
    ''' Enable Delete = False
    ''' 
    ''' Column 1 DataGridViewTextBox column set to read-only
    ''' Column 2 DataGridViewTextBox column set to read-only, named QuestionTextColumn
    ''' Column 3 DataGridViewCheckBox column
    ''' 
    ''' * You can tweak the DataGridView interface to look less like a DataGridView, i.e.
    '''     - RowHeadersVisible = False
    ''' 
    ''' Data is read from a comma delimited Textfile in the Debug\Bin folder
    ''' 
    ''' The language extension ToDataTable needs to be in a Code Module.
    ''' </summary>
    ''' <remarks></remarks>
    Public Class Form1
        WithEvents bsQuestions As New BindingSource
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            bsQuestions.DataSource = (From line In IO.File.ReadAllLines("Questions.txt") _
                           Where line.Length > 0 _
                           Let Question = line.Split(","c) _
                           Select New With _
                                {.Number = CInt(Question(0)), _
                                 .Question = Question(1) & "?", _
                                 .Answer = CBool(Question(2)) _
                                } _
                            ).ToDataTable
            DataGridView1.DataSource = bsQuestions
            DataGridView1.Columns("QuestionTextColumn").AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells
        End Sub
        Private Sub cmdSubmit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSubmit.Click
            Dim Results =
                (
                    From T In CType(bsQuestions.DataSource, DataTable).AsEnumerable
                    Select IIf(T.Item("Answer").ToString = "True", "Yes", " No").ToString & " " &
                           T.Item("Number").ToString & " " &
                           T.Item("Question").ToString).ToArray
            Windows.Forms.Clipboard.SetText(String.Join(Environment.NewLine, Results))
        End Sub
    End Class

    Code module

    Module Module1
        <System.Diagnostics.DebuggerStepThrough()> _
        <System.Runtime.CompilerServices.Extension()> _
        Public Function ToDataTable(Of T)(ByVal value As IEnumerable(Of T)) As DataTable
            Dim returnTable As New DataTable
            Dim firstRecord = value.First
            For Each pi In firstRecord.GetType.GetProperties
                returnTable.Columns.Add(pi.Name, pi.GetValue(firstRecord, Nothing).GetType)
            Next
            For Each result In value
                Dim nr = returnTable.NewRow
                For Each pi In result.GetType.GetProperties
                    nr(pi.Name) = pi.GetValue(result, Nothing)
                Next
                returnTable.Rows.Add(nr)
            Next
            Return returnTable
        End Function
    End Module

    Text file, Questions.txt

    1,Are you older than 18,False
    2,Do you like dogs,False
    3,Do you like coffee,False


    KSG

  • Sunday, April 29, 2012 1:05 AM
     
     

    A better method would be to (if open to this) use a DataGridView

    Perhaps...  I got the sense this was an assignment (thus restricted to what was asked for) though it is tough to tell sometimes.

    Excellent example all the same :)