Author Topic: Error checking controls on form  (Read 6639 times)

0 Members and 2 Guests are viewing this topic.

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4076
Error checking controls on form
« on: January 06, 2009, 10:28:17 AM »
What is the best way to error check that a user has populated all controls on a form?  I have 4 controls that I wish to make sure are populated, and the best I can come up with is nested IFs which are a huge pain in the neck.  Any ideas or suggestions that you guys use?
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4076
Re: Error checking controls on form
« Reply #1 on: January 06, 2009, 10:28:48 AM »
Forgot to mention, written in C#
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

sinc

  • Guest
Re: Error checking controls on form
« Reply #2 on: January 06, 2009, 10:41:42 AM »
You might want to look at the ErrorProvider component.  Simply add it to your form, and you get a variety of controls.  Then add code to handle the "Validating" and "Validated" events for various fields as-necessary.  This functionality is built-in to Designer.

There are also some downloads that can make this easier, so you don't have to manually create the "Validating" and "Validated" event handlers, and can instead simply set properties in Designer.  I'm not sure what's best among those, though.

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4076
Re: Error checking controls on form
« Reply #3 on: January 06, 2009, 10:53:54 AM »
thanks
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

Ken Alexander

  • Newt
  • Posts: 61
Re: Error checking controls on form
« Reply #4 on: January 06, 2009, 11:17:34 AM »
The ErrorProvider Class implements IExtenderProvider; you might look into this Interface if the ErrorProvider Class doesn't meet your needs.
Ken Alexander

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4076
Re: Error checking controls on form
« Reply #5 on: January 06, 2009, 01:49:37 PM »
the error provider is working, but my question is do I have 1 for each control or can I tie 4 controls to 1 provider
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

sinc

  • Guest
Re: Error checking controls on form
« Reply #6 on: January 06, 2009, 02:28:14 PM »
One provider for each form.

Then create "Validating" and/or "Validated" event handlers for each field you want to validate - in designer, you can switch to "Events" in properties view and double-click on an event to create the code stub-out.  In the event handlers, use the errorProvider.SetError() method to control the error indicator to display in the form.

If you want to keep the user from leaving a field until a correct value is entered, set the "Cancel" property in the EventArgs for the "Validating" event handler.

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4076
Re: Error checking controls on form
« Reply #7 on: January 06, 2009, 04:03:35 PM »
OK, that makes sense, now to see if I can do it.
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

Spike Wilbury

  • Guest

TonyT

  • Guest
Re: Error checking controls on form
« Reply #9 on: January 07, 2009, 12:19:31 PM »
The ErrorProvider Class implements IExtenderProvider; you might look into this Interface if the ErrorProvider Class doesn't meet your needs.

I'm not sure what you're getting at.

IExtenderProvider is for dynamically adding 'pseudo-properties' to
controls in the designer, like the ones the ErrorProvider adds.

It has nothing to do with validation.

Ken Alexander

  • Newt
  • Posts: 61
Re: Error checking controls on form
« Reply #10 on: January 07, 2009, 04:07:29 PM »
The ErrorProvider Class implements IExtenderProvider; you might look into this Interface if the ErrorProvider Class doesn't meet your needs.

I'm not sure what you're getting at.

IExtenderProvider is for dynamically adding 'pseudo-properties' to
controls in the designer, like the ones the ErrorProvider adds.

It has nothing to do with validation.

My point is that you can create your own robust “ErrorProvider” or “ValidationTool”, whatever you want to call it, by using IExtenderProvider.  I created a simple down and dirty example called TextBoxValidator.

When using the ErrorProvider you have to write each control’s validation logic in the controls validation event or somewhere else.  By using the IExtenderProvider you can create a component that you can drop on a form that adds your ‘pseudo-properties’ to each control that this extender can extend.  With these properties you can then set each control’s validation at design time and your custom Validator knows what to do with it.

The sample below demonstrates a custom TextBoxValidator.  After droping this component onto a form, all textboxes will have a new property called “ValidationType on TextBoxValidator1”

You could also very easily extend .NETs ErrorProvider class using the TextBoxValidator code so the little icon and error messages are displayed.

Code: [Select]

Imports System.ComponentModel

<ProvideProperty("ValidationType", GetType(TextBox))> _
Public Class TextBoxValidator
    Inherits Component
    Implements IExtenderProvider

    Private _Validations As New Dictionary(Of TextBox, ValidationType)
    Private _AllowValidation As Boolean = True

    Public Property AllowValidation() As Boolean
        Get
            Return _AllowValidation
        End Get
        Set(ByVal value As Boolean)
            _AllowValidation = value
        End Set
    End Property

    Public Function CanExtend(ByVal extendee As Object) As Boolean Implements System.ComponentModel.IExtenderProvider.CanExtend
        If TypeOf extendee Is TextBox Then
            Return True
        End If
    End Function

    Public Function GetValidationType(ByVal txtBox As TextBox) As ValidationType
        If _Validations.ContainsKey(txtBox) Then
            Return _Validations(txtBox)
        Else
            Return ValidationType.None
        End If
    End Function

    Public Sub SetValidationType(ByVal txtBox As TextBox, ByVal value As ValidationType)
        Dim ValidationType As ValidationType = value
        If _Validations.ContainsKey(txtBox) Then
            _Validations(txtBox) = value
        Else
            _Validations.Add(txtBox, value)
        End If
        Select Case ValidationType
            Case ValidationType.None
                RemoveHandler txtBox.Validating, AddressOf TextBoxValidating
            Case Else
                AddHandler txtBox.Validating, AddressOf TextBoxValidating
        End Select
    End Sub

    Private Sub TextBoxValidating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs)
        Dim Flag As Boolean
        Dim txtBox As TextBox = DirectCast(sender, TextBox)
        If AllowValidation Then
            Select Case _Validations(txtBox)
                Case ValidationType.RequireInput
                    If txtBox.Text.Trim = "" Then
                        Flag = True
                    Else
                        Flag = False
                    End If
                Case ValidationType.RequireInteger
                    Dim Result As Integer
                    If Integer.TryParse(txtBox.Text, Result) Then
                        Flag = False
                    Else
                        Flag = True
                    End If
                Case Else
                    Flag = False
            End Select
            If Flag Then
                txtBox.BackColor = Color.Red
            Else
                txtBox.BackColor = Color.White
            End If
        End If
    End Sub
End Class

Public Enum ValidationType
    None
    RequireInput
    RequireInteger
End Enum


« Last Edit: January 07, 2009, 07:04:59 PM by Ken Alexander »
Ken Alexander

TonyT

  • Guest
Re: Error checking controls on form
« Reply #11 on: January 08, 2009, 10:27:26 AM »
Well yes, you can do that, but I can't see any useful purpose
to it, because the use of data binding eliminates the need for it,
and allows you to do much more with little work.

I routinely use data binding to bind controls to properties of a
class, which gives me much greater control over validation and
formatting.

This sample shows that, and why there's no need for taking
the kind of approach you suggest:

  http://www.caddzone.com/DataBindingSample.zip

If you download and run the sample app and type 'ABC' in the
'Effective Height' TextBox and press the TAB key, you'll see why
IExtenderProvider is not needed to do robust validation.


The ErrorProvider Class implements IExtenderProvider; you might look into this Interface if the ErrorProvider Class doesn't meet your needs.

I'm not sure what you're getting at.

IExtenderProvider is for dynamically adding 'pseudo-properties' to
controls in the designer, like the ones the ErrorProvider adds.

It has nothing to do with validation.

My point is that you can create your own robust “ErrorProvider” or “ValidationTool”, whatever you want to call it, by using IExtenderProvider.  I created a simple down and dirty example called TextBoxValidator.

When using the ErrorProvider you have to write each control’s validation logic in the controls validation event or somewhere else.  By using the IExtenderProvider you can create a component that you can drop on a form that adds your ‘pseudo-properties’ to each control that this extender can extend.  With these properties you can then set each control’s validation at design time and your custom Validator knows what to do with it.

The sample below demonstrates a custom TextBoxValidator.  After droping this component onto a form, all textboxes will have a new property called “ValidationType on TextBoxValidator1”

You could also very easily extend .NETs ErrorProvider class using the TextBoxValidator code so the little icon and error messages are displayed.

Code: [Select]

Imports System.ComponentModel

<ProvideProperty("ValidationType", GetType(TextBox))> _
Public Class TextBoxValidator
    Inherits Component
    Implements IExtenderProvider

    Private _Validations As New Dictionary(Of TextBox, ValidationType)
    Private _AllowValidation As Boolean = True

    Public Property AllowValidation() As Boolean
        Get
            Return _AllowValidation
        End Get
        Set(ByVal value As Boolean)
            _AllowValidation = value
        End Set
    End Property

    Public Function CanExtend(ByVal extendee As Object) As Boolean Implements System.ComponentModel.IExtenderProvider.CanExtend
        If TypeOf extendee Is TextBox Then
            Return True
        End If
    End Function

    Public Function GetValidationType(ByVal txtBox As TextBox) As ValidationType
        If _Validations.ContainsKey(txtBox) Then
            Return _Validations(txtBox)
        Else
            Return ValidationType.None
        End If
    End Function

    Public Sub SetValidationType(ByVal txtBox As TextBox, ByVal value As ValidationType)
        Dim ValidationType As ValidationType = value
        If _Validations.ContainsKey(txtBox) Then
            _Validations(txtBox) = value
        Else
            _Validations.Add(txtBox, value)
        End If
        Select Case ValidationType
            Case ValidationType.None
                RemoveHandler txtBox.Validating, AddressOf TextBoxValidating
            Case Else
                AddHandler txtBox.Validating, AddressOf TextBoxValidating
        End Select
    End Sub

    Private Sub TextBoxValidating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs)
        Dim Flag As Boolean
        Dim txtBox As TextBox = DirectCast(sender, TextBox)
        If AllowValidation Then
            Select Case _Validations(txtBox)
                Case ValidationType.RequireInput
                    If txtBox.Text.Trim = "" Then
                        Flag = True
                    Else
                        Flag = False
                    End If
                Case ValidationType.RequireInteger
                    Dim Result As Integer
                    If Integer.TryParse(txtBox.Text, Result) Then
                        Flag = False
                    Else
                        Flag = True
                    End If
                Case Else
                    Flag = False
            End Select
            If Flag Then
                txtBox.BackColor = Color.Red
            Else
                txtBox.BackColor = Color.White
            End If
        End If
    End Sub
End Class

Public Enum ValidationType
    None
    RequireInput
    RequireInteger
End Enum



Ken Alexander

  • Newt
  • Posts: 61
Re: Error checking controls on form
« Reply #12 on: January 08, 2009, 06:22:05 PM »
If you don’t see any useful purpose in a component that implements IExtenderProvider as a validation tool, then why are you using one in your data binding example? 

In reality data binding has absolutely nothing to do with Form validation and IExtenderProvider is the KEY to it.  Your sample is a data binding example that shows appropriate business logic validation not a re-usable, extendable Form validation tool.

If you take the sample component I provided and drop it on ANY form you may have and select ANY TextBox then go to the properties window and set that TextBox’s ValidationType to “RequireInteger”, that TextBox is going to require an integer, no class to make, no data source to set up, no matching Properties to worry about, no Property mapping to do, just one simple property to change at design time and you’re done.  My sample turns the TextBox red if it isn’t an Integer though I could have just as easily forced focus on the TextBox.  Each TextBox validation can behave in as many different ways as you have EXTENDED their capabilities.  To me, that’s the makings of a robust Form validation tool. And better yet, down the road, if you end up with data bound controls, it’ll work with them too.
Ken Alexander

TonyT

  • Guest
Re: Error checking controls on form
« Reply #13 on: January 09, 2009, 03:07:51 PM »
If you don’t see any useful purpose in a component that implements IExtenderProvider as a validation tool, then why are you using one in your data binding example? 


I'm not using any IExtenderProviders that do validation.

Where did you get that idea from? 

ErrorProvider is an IExtenderProvider, but it does not do
any kind of validation.

You seem to have misunderstood what I typed, so let me be
more specific:

I don't see any useful purpose to using IExtenderProvider to
do what your example does.  If you do things the correct way,
via the mechanisms provided by the framework, rather than
take a 'roll-your-own' approach, then point in fact is that the
example you show serves no purpose, because the information
that it associates with each control is already inferred by the
type of the property which the control is bound to.

If I databind a control to a property whose type is an integer,
the framework knows that the input must be convertable to an
integer, and it will do the conversion for me, and raise the error
that occurs if the contents of the text box is not convertable
to an integer.  So, given that the framework does all of that for
me when I do things the right way (data binding), why do I need
to associate another 'extended property' with a control that does
nothing other than indicate that the control requires an integer?

In the case of using data binding to an integer property of an
object, the framework already knows the control requires an
integer, because that is the type of the property the control
is bound to. Additional data validation is done by the setter of
the bound property, because in most cases, that validation is
something that applies not only to user-input, but also to any
value the property is set to, via any means, including consumer
code.


Quote

In reality data binding has absolutely nothing to do with Form
validation...


That's simply not true.

I don't see how anyone can make a statement like that, given
that the data binding sample that I posted the link to contains
no code that performs the basic validation required in order to
convert the user-supplied text to the required data type (ints
and doubles). That is (the most basic) form of 'validation'.

Your example IExtenderProvider is absurd, because you still
have to do the basic validation/conversion yourself in code,
rather than allowing the framework to do it for you, as it
does when using data binding.

At this point I have to bow out of this conversation, because
it's beginning to resemble a dead horse-beating contest.

« Last Edit: January 09, 2009, 05:02:38 PM by TonyT »

Ken Alexander

  • Newt
  • Posts: 61
Re: Error checking controls on form
« Reply #14 on: January 09, 2009, 07:57:57 PM »
Fair enough.  I will bow out with my final words.

You are right; the ErrorProvider does not do any validation.  It requires you to re-enter validation code for every control in every form you want to validate.  Your data binding method requires basically the same.

To say that the data binding is a better approach because the framework is handling basic validation (String to Integer).  Come on, that’s casting/converting not validation.  Whether the binding casts it for me or I use a TryParse, it’s still casting (I wonder what the IL code would show?)  Both of our methods require us to write our own validation, who else is going to?

Bottom line is my method isn't in theory, its in practice, works quite nicely, and is as handy as a shirt pocket.

Ken Alexander