Results 1 to 10 of 10

Thread: [RESOLVED] Passing multiple controls to a function

  1. #1

    Thread Starter
    Addicted Member riechan's Avatar
    Join Date
    Feb 2008
    Location
    Japan
    Posts
    254

    Resolved [RESOLVED] Passing multiple controls to a function

    I use this code to display errors in the form:

    Code:
        Public Sub CheckIndex(ByRef _Control As ComboBox)
            If _Control.SelectedIndex = -1 Then
                HighlightError(_Control, errMissing)
                blnMissing = True
            End If
        End Sub
    And as you guys might already know just send in the combo boxes one by one to the function for validation. I have at least 30 combo boxes to validate, and validating them one by one is tedious and quite frankly, lengthy. Is there any way I can pass them to the function for validation? They're named like so:

    - cboT1Combo1, cboT1Combo2...
    - cboT2Combo1, cboT2Combo2...

    and so on and so forth. Another question I'd like to ask is, I've already set the SelectedIndex property of each combo box to 0 on load, will the SelectedIndex of those combo box possibly become -1 anytime during runtime?
    ====================
    ほんとにどもありがとう!

    Rie Ishida

  2. #2
    Hyperactive Member
    Join Date
    Sep 2004
    Posts
    482

    Re: Passing multiple controls to a function

    You could add all of the controls to a List object and then just pass in the List and iterate though that with a For loop. Alternatively, you could also just have the Sub look though all of the combo boxes instead of passing anything in.

  3. #3

    Thread Starter
    Addicted Member riechan's Avatar
    Join Date
    Feb 2008
    Location
    Japan
    Posts
    254

    Re: Passing multiple controls to a function

    Quote Originally Posted by Maverickz View Post
    You could add all of the controls to a List object and then just pass in the List and iterate though that with a For loop. Alternatively, you could also just have the Sub look though all of the combo boxes instead of passing anything in.
    Okay, so I tried it like this:

    Code:
        Public Sub CheckIndexes()
            For Each ctrl As Control In PatientRecord.Controls
                If TypeOf ctrl Is ComboBox Then
                    If CType(ctrl, ComboBox).SelectedIndex = -1 Then
                        HighlightError(CType(ctrl, ComboBox), errMissing)
                        blnMissing = True
                    End If
                End If
            Next
        End Sub
    
        Private Sub HighlightError(ByRef _Control As Control, ErrorString As String, Optional _Label As Control = Nothing)
            ...
        End Sub
    Something seems to be off as ctrl doesn't pass through the If TypeOf condition. It just looped 9 times - which I believe corresponds to the 9 tabs I have in the form (which is odd because I'm very much sure that I don't have just 9 controls in the form). The controls are inside a group box, placed on a tab control PatientRecords with different tab names.

    Edit: Looking up the control names for each loop, Me.Controls only passed the 5 controls (the Tab control, a label and 3 buttons), PatientRecord.Controls only passed the 9 tabs and not the controls inside the tab, and tabPatient (first tab) only got the group boxes and other controls not inside the group boxes. How can I access the controls in the form which is inside a group box on a tab page? I thought that Me.Controls would have access to all the controls in the active form.
    Last edited by riechan; Mar 20th, 2016 at 12:36 PM.
    ====================
    ほんとにどもありがとう!

    Rie Ishida

  4. #4
    Hyperactive Member
    Join Date
    Sep 2004
    Posts
    482

    Re: Passing multiple controls to a function

    Your problem is that "X.Controls" is non-recursive so it will only find the controls that are directly in "X" (whatever X is) and not any controls that are nested in Tabs, Panels or GroupBoxes. "GetNextControl" is recursive so that is what we need to use in this case.

    Try this:
    Code:
        Public Sub CheckIndexs()
            Dim ctl As Control = Me.GetNextControl(Me, True)
            Do Until ctl Is Nothing
                If ctl.GetType.Name = "ComboBox" Then
                    If ctl.SelectedIndex = -1 Then
                        HighlightError(ctl, errMissing)
                        blnMissing = True
                    End If      
                End If
                ctl = Me.GetNextControl(ctl, True)
            Loop
        End Sub
    Last edited by Maverickz; Mar 20th, 2016 at 03:08 PM.

  5. #5

    Thread Starter
    Addicted Member riechan's Avatar
    Join Date
    Feb 2008
    Location
    Japan
    Posts
    254

    Re: Passing multiple controls to a function

    Thank you for the help. I tried your suggested code and sadly it only reiterated the Tab control. I made a couple more searches using the list method you mentioned and found a set of code here which accomplishes what I needed.

    Code:
        Dim _list As New List(Of Control)
        Public Sub GetChildren(container As Control)
            For Each child As Control In container.Controls
                _list.Add(child)
                If (child.HasChildren) Then
                    GetChildren(child)
                End If
            Next
        End Sub
    
        Public Sub CheckIndexes()
            GetChildren(Me)
    
            For Each ctrl As Control In _list
                If ctrl.GetType.Name = "ComboBox" Then
                    If CType(ctrl, ComboBox).SelectedIndex = -1 Then
                        HighlightError(ctrl, errMissing)
                        blnMissing = True
                    End If
                End If
            Next
        End Sub
    Unfortunately, I'm not too familiar with using lists. Can you help explain the code to me so I can get a better understanding of it? The gist, if I'm not mistaken, is that the GetChildren() sub gets all of the controls in the active form and lists them down, checks if it has child controls and calls the same sub from within the sub (this is what recursive means, yes?) until such time that the parent control no longer has any child controls?

    Also, what's the significance of the _ in _list? Is this a naming convention pertaining to something?
    ====================
    ほんとにどもありがとう!

    Rie Ishida

  6. #6
    Hyperactive Member
    Join Date
    Sep 2004
    Posts
    482

    Re: Passing multiple controls to a function

    Quote Originally Posted by riechan View Post
    Thank you for the help. I tried your suggested code and sadly it only reiterated the Tab control. I made a couple more searches using the list method you mentioned and found a set of code here which accomplishes what I needed.

    Unfortunately, I'm not too familiar with using lists. Can you help explain the code to me so I can get a better understanding of it? The gist, if I'm not mistaken, is that the GetChildren() sub gets all of the controls in the active form and lists them down, checks if it has child controls and calls the same sub from within the sub (this is what recursive means, yes?) until such time that the parent control no longer has any child controls?

    Also, what's the significance of the _ in _list? Is this a naming convention pertaining to something?
    Glad you found something that worked for you.

    Think of a List is just a special type of single dimensional array that has methods to add items, remove items etc. and it will automatically adjust it's size as needed. There is also the Dictionary object which is like a List but supports name/value pairs and finally there is a Collection which is similar to a Dictionary and there are advantages and disadvantages to each. That can be some light research for you.

    Yes that is what recursive means.

    Some people use _ as the first character of variable name to make variables easier to spot when reading the code and to avoid a conflict with a reserved word or method. You don't have to use it as long as you make sure your variables don't have any conflicts. For instance you cannot have a variable named "Integer" because Integer already has meaning to VB. You can however, use _Integer if you wanted. I have also seen people indicate variables by using "v" or "var" to start variable names.

    I have never gotten into that habit with variables but I do with Controls. I usually name my controls with a 3 char prefix to designate the type of control and then a Descriptive name. For example txtEmail would indicate a TextBox to collect Email Address and cmbState would be a ComboBox to select State and btnSubmit is a button to Submit the form and so forth. This makes it easier when reading my code to understand what each object is
    Last edited by Maverickz; Mar 20th, 2016 at 11:14 PM.

  7. #7
    Hyperactive Member
    Join Date
    Sep 2004
    Posts
    482

    Re: Passing multiple controls to a function

    Oh if this is resolved, don't forget to edit the original post and mark it as such.

  8. #8
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Passing multiple controls to a function

    Validation is built into Windows Forms. Every control has a Validating event and you can handle that. Just like any event, you can use a single method to handle the event for multiple objects and access the object that raised the event via the 'sender' parameter in the event handler. The Validating event is generally raised when the user tries to leave a control and you can also force it to be raised by calling the form's Validate method to validate the last unvalidated control or the ValidateChildren method to validate all controls. ValidateChildren ensures that even controls that have never received focus will be validated.

    By the way, I can't see any reason for your _Control parameter to be declared ByRef. ByVal is the default for a reason. Don't change it unless you have a reason to. The only reason in this case would be if you were assigning a new ComboBox to the parameter inside the method and wanted that to affect the caller. I trust that that's not the case here. ByRef was used by default in VB6 for a reason and that reason does not apply to VB.NET unless you're using large structures, which itself is bad practice.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  9. #9

    Thread Starter
    Addicted Member riechan's Avatar
    Join Date
    Feb 2008
    Location
    Japan
    Posts
    254

    Re: Passing multiple controls to a function

    Quote Originally Posted by Maverickz View Post
    Think of a List is just a special type of single dimensional array that has methods to add items, remove items etc. and it will automatically adjust it's size as needed. There is also the Dictionary object which is like a List but supports name/value pairs and finally there is a Collection which is similar to a Dictionary and there are advantages and disadvantages to each. That can be some light research for you.

    Yes that is what recursive means.

    Some people use _ as the first character of variable name to make variables easier to spot when reading the code and to avoid a conflict with a reserved word or method. You don't have to use it as long as you make sure your variables don't have any conflicts. For instance you cannot have a variable named "Integer" because Integer already has meaning to VB. You can however, use _Integer if you wanted. I have also seen people indicate variables by using "v" or "var" to start variable names.

    I have never gotten into that habit with variables but I do with Controls. I usually name my controls with a 3 char prefix to designate the type of control and then a Descriptive name. For example txtEmail would indicate a TextBox to collect Email Address and cmbState would be a ComboBox to select State and btnSubmit is a button to Submit the form and so forth. This makes it easier when reading my code to understand what each object is
    Thank you for the detailed explanation. None of these were taught to us back in college 6 years ago so this is all new to me. Didn't really work in the industry and am trying to get back to this is a great help!

    Quote Originally Posted by jmcilhinney View Post
    Validation is built into Windows Forms. Every control has a Validating event and you can handle that. Just like any event, you can use a single method to handle the event for multiple objects and access the object that raised the event via the 'sender' parameter in the event handler. The Validating event is generally raised when the user tries to leave a control and you can also force it to be raised by calling the form's Validate method to validate the last unvalidated control or the ValidateChildren method to validate all controls. ValidateChildren ensures that even controls that have never received focus will be validated.

    By the way, I can't see any reason for your _Control parameter to be declared ByRef. ByVal is the default for a reason. Don't change it unless you have a reason to. The only reason in this case would be if you were assigning a new ComboBox to the parameter inside the method and wanted that to affect the caller. I trust that that's not the case here. ByRef was used by default in VB6 for a reason and that reason does not apply to VB.NET unless you're using large structures, which itself is bad practice.
    Thanks J! I'm currently watching a video about the Validating event. I'm currently using a validation function, hopefully I get to implement the Validating event in my project. I've corrected the ByRef argument after reading the KB article on ByVal/ByRef.
    ====================
    ほんとにどもありがとう!

    Rie Ishida

  10. #10
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Passing multiple controls to a function

    Quote Originally Posted by riechan View Post
    I'm currently using a validation function, hopefully I get to implement the Validating event in my project.
    It shouldn't be a big change. You can probably just call your existing function from the Validating event handler.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width