Validating controls on a user control

cmgarnett
cmgarnett used Ask the Experts™
on
To set an OK button's enabled state depending on the validity of all the controls on a form I use "btnOK.Enabled = fValidateForm(Me)".

fValidateForm then uses "For Each myControl in myForm" to read through the form's controls and validate them. This works fine.

I would like to do something similar for all of the controls on a user control, something like "btnOK.Enabled = fValidateUserControl(ucName)".

When I declare fValidateUserControl to recieve a parameter of type UserControl, I get a type mismatch. When I declare it with a parameter type of Object and try to use "For Each myControl In myUserControl" I get a method not available for this object error.

Is it possible to read through all of the controls in a user control?
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
   For Each oControl In Controls
        Debug.Print oControl.Name
    Next
Sorry, it sent off before I could finish.  Put this in the usercontrol's fValidateForm.  Once you validate all the controls in the

public property get IsUserControlValid() as boolean

    IsUserControlValid = fValidateForm()

end property

private function fValidateForm () as boolean
   For Each oControl In Controls
       'test for validity
   Next
   'Return true/false depending on your tests

end function
I want the fValidateForm (or fValidateUserControl) function to be a public function in a common functions module so that it can be used for several different UserControls.

This is the real problem I am getting. My application has about 20 different UserControls and the basic validation rules are held in each constituent control's Tag property. I would rather not have to write a separate validation routine for each UserControl.
Ensure you’re charging the right price for your IT

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

I see.  You will want to read the VB Help file article called: "Exposing Properties of Constituent Controls"

Basically the principal is to expose those properties of the constituent controls you want to test as properties of the UserControl itself.  I tried something I was sure wasn't going to work, and I was right.  I tried to expose a property on the usercontrol that would return the intrinsic Controls collection to no avail.

What you COULD do to automate this process instead is to expose a public method in the Usercontrol.  This public method would make a call to your public method of fValidateForm in your bas module passing in a new collection of your usercontrol's constituent controls.  This method would pass all the constituent controls as a collection and fValidateForm would accept a collection as an argument.  SO this would look like:

Usercontrol:
Public oControlsCollection - filled when usercontrol is loaded with all the controls on the form like:

  for each oControl in controls
    oControlsCollection.add oControl    
  next

public sub ValidateMe()

    fValidateForm oControlsCollection

end sub

In your module where fValidateForm resides, a new function called fValidateUserControl would perform the following
public sub fValidateUserControl(byval oUserControl as control)
  oUserControl.ValidateMe
end sub

Function fValidate(Controls As Object) As Boolean
    Dim ctl As Control
   
    For Each ctl In Controls
        'do check
    Next
End Function

'call in form
    fValidate(Me.Controls)
'Call in UserControl
    fValidate(Usercontrol.Controls)
TigerZhao

I want to use a solution to the one you describe but when I add

  btnApply.Enabled = f_tagValidateUC(ucParm.Controls)

to the txtName_Change event for a text box on ucParm, I get an error message "Variable not defined" and ucParm is highlighted as being the problem.
At the moment I have added the following function to each UserControl. The fValidateControl function resides in a global .bas file.

Private Function fValidateMe() As Boolean

   Dim myCtl As Control
   
   For Each myCtl In Controls
      If Not fValidateControl(myCtl) Then _
         Exit Function
   Next
   
   fValidateMe = True
   
End Function

I can't say I'm fond of the way I've done it as I feel it could be more generic than this and I would rather have fValidateMe in the global .bas file too.

I'll hang on to the points back for a short while but at the moment I think that twalgrave is closest to describing what I have done.
if txtName is in ucParm, just call
    btnApply.Enabled = f_tagValidateUC(UserControl.Controls)

if txtName is out of ucParm, tow solution:
#1
'add a property in UserControl ucParm
Property Get Controls() As Object
    Set Controls = UserControl.Constrols
End Property
'call in txtName_Change
    btnApply.Enabled = f_tagValidateUC(ucParm.Controls)

#2 (suggested)
'add a function in UserControl
Function Validate() As Boolean
    Validate = f_tagValidateUC(UserControl.Controls)
End Function
'call in txtName_Change
    btnApply.Enabled = ucParm.Validate()
Yep, that's the cookie.

I was passing my UserControlName.Controls rather than UserControl.Controls, and I was trying to receive Controls into the validation function rather than Object.

Thanks for your help.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial