Click here to Skip to main content
15,867,686 members
Articles / Desktop Programming / Windows Forms
Article

Self Validating TextBox

Rate me:
Please Sign up or sign in to vote.
4.00/5 (6 votes)
17 May 2008CPOL10 min read 38.7K   340   29   8
A self populating and self validating textbox control with business object awareness.

Image 1

Introduction

When it comes to building a client/server application, one of the most time consuming elements is the GUI. Quite often, a developer will get stuck piecing together the visual elements/appearance with control population, data input validation, and then interaction with the business objects. I struck this very problem while working on our in house systems two years ago. The major bottleneck was validating the input from the user, parsing this data into the business objects, and reporting any/all errors that may occur due to a rule violation. This bottleneck was discovered simply because we were on a fairly strict timeline and some of the forms we had to build were quite large.

My solution was to design and build a textbox control that was:

  • Capable of self populating from a business object
  • Capable of self validating user input
  • Simple to use at design time
  • Required very little coding in order to operate

The brief was simple, and it didn't seem too difficult to hit the target...

What was discovered was that with a little bit of perseverance, we actually achieved a suite of controls that are intelligent enough to take care of themselves and allow us developers to get on with the custom coding that actually made the system what it is today.

The SVT control deals with a number of facets of the .NET framework:

  • Reflection
  • Events
  • Shadowing and Overriding

I intend to show the features of this Self Validating TextBox (SVT) control and how its features are implemented and achieved. The article won't actually show how to construct the control as this is not a beginner's article, and this information can be gleaned from the solution example. I have also chosen not to include any screenshots as this control looks no different to a standard TextBox.

Background

Once the requirements were agreed upon, we consciously decided to make use of a User Control as a "host" for our textbox. We came to this decision because we felt that if the need arose for the control to be inherited for any future requirements, a User Control "environment" would allow this to happen easily, i.e., adding additional controls. This was later proved when we needed to build a "smart" RTF control.

We also decided pretty quickly that we should stick with as many "standard" events, prototypes, properties, etc. where we could. i.e. Validated and TextChanged events; Text, MultiLine properties; These events, prototypes, properties, etc. are drawn from the Windows.Forms.TextBox control.

This control (and all subsequent) have a very strong link to the business objects they deal with. This was done purposely because we felt that no matter how many degrees of separation you strive for, ultimately, the UI must interact with the business objects. For this reason alone, we decided to try make the text box as aware of the business objects and as intelligent as possible, therefore reducing hand code in the forms.

The SVT control makes reference to code featured in a previous article on Business Object Property Validation.

Structure

Events: The following public events are defined:

  • Validated(ByVal sender as Object, ByVal e as System.EventArgs)
  • Public Shadows Event TextChanged(ByVal sender as Object, ByVal e as System.EventArgs)
  • Public Shadows IsFocused(ByVal sender as Object, ByVal msg as String)

Public Properties: The following public properties are defined:

  • Public Overridable Shadows Property Text() As String
  • Public Property ScrollBars() as Windows.Forms.ScrollBars
  • Public Property PasswordChar() As String
  • Public Property MultiLine() As Boolean
  • Public Property AcceptsTab() As Boolean
  • Public Property AcceptsReturn() As Boolean
  • Public Overridable Shadows Property ReadOnly() As Boolean
  • Public Property UseCustomReadOnly() As Boolean
  • Public Property BizO() As Object
  • Public Property PropName() As String
  • Public Property SelfValidate() As Boolean
  • Public Property SelfPopulate() As Boolean
  • Public Property SelfValidateAutoEnroll() As Boolean
  • Public ReadOnly Property ErrorMessage() As String
  • Public ReadOnly Property DescriptiveText() As String
  • Public ReadOnly Property DisplayName() As String
  • Public Property ValidateOnChange() As Boolean
  • Public Property ValidateOnPopulate() As Boolean
  • Public Property ValidateOnNoChange() As Boolean

Public Methods: The following public methods are defined:

  • Public Overridable Shadows Sub Validate()
  • Public Sub ValueValidate(ByVal strValue As String)
  • Public Shadows Sub Refresh()
  • Protected Sub ThrowValidated(ByVal sender As Object, ByVal e As System.EventArgs)
  • Public Sub Copy()
  • Public Sub Cut()
  • Public Sub Paste()
  • Public Sub Undo()
  • Public Sub Clear()
  • Public Sub SelectAll()

Mechanics

At design time, the developer adds the control to a form and then sets its properties to suit. So far, no different from any other control. This, however, is where the SVT control differs. The developer has the ability to decide how the SVT control will behave and react. The majority of properties are already set with defaults. At a minimum, the PropName property needs to be set. This allows the control to get/set the nominated property from the business object at runtime.

Dealing with the sample form supplied, there is only a single textbox control that requires coding. Again, this is where the SVT control differs as the only code required is as follows:

VB
UITextBox1.BizO = [MyBusinessObject]

Yes!!! That's right. 1 single line of code, unless there is any need for custom validation code in the UI layer.

At runtime, this single line of code, setting the value of the BizO property, will perform the following actions:

  1. Set the Loading property of the SVT control to True. This allows for the Validate event handler to check the ValidateOnPopulate property and decide whether to continue or not.
  2. Store a reference copy of the business object locally in the SVT control.
  3. Clear any previous references to old business objects in the SVT control.
  4. Check to ensure that the current value is not null/Nothing.
  5. Check to ensure that the PropName property is not String.Empty.
  6. Check the SelfPopulate property. If set to True, read the value from the [PropName] property in the BizO object and populate the control.

Again. 1 single line of code to do it.

When the user input is received, the SVT control will perform the following actions:

  1. Check to ensure the SelfValidate property is set to True and that the BizO is not null/Nothing.
  2. Set the [PropName] property in the BizO object to the value of TextBox.Text.

Description of Properties

From the list of properties above, it is clear that some of the properties are derived from the Windows.Forms.TextBox control. All other properties are clarified below:

Public Property UseCustomReadOnly() As BooleanAfter initial design and construction, it was determined that our own use of the SVT control should have some sort of overriding mechanism to control how the ReadOnly property is controlled. This is due to the fact that our base forms provide further support for business object integration. For the purposes of this article, this property is redundant, but could be used as and when required. This property can be set at design time.
Public Property BizO() As ObjectThe business object. This property stores a local reference copy of the business object being used. This property can only be set at run time.
Public Property PropName() As StringThe name of the property in the business object. This property can be set at design time.
Public Property SelfValidate() As BooleanAllows the SVT control to self validate and parse data into the business object. This property can be set at design time.
Public Property SelfPopulate() As BooleanAllows the SVT control to populate itself from the business object. This property can be set at design time.
Public Property SelfValidateAutoEnroll() As BooleanOur base forms have been extended quite significantly to provide further support for business object integration. As a result, our base forms support a BizO property of their own. When the form BizO property is set, it triggers an iterative process which in turn assigns the BizO property of the controls on the form. This property allows the base form to either assign the value to the control or ignore the control. The property can be set at design time.
Public ReadOnly Property ErrorMessage() As StringIf any errors are encountered during validation, the error message being returned from the business object is stored here. This allows for the control to be more responsible for itself.
Public ReadOnly Property DescriptiveText() As StringThe Description attribute can be applied to properties, and as such, the SVT control can recognise this attribute. So, when the control receives focus, it raises the IsFocused event and parses itself and the value of the Description attribute.
Public ReadOnly Property DisplayName() As StringSimilar to the DescriptiveText property, the DisplayName attribute is defined in the BusinessRules assembly. This allows for the property to be named without having to sacrifice any column/field/property naming convention.
Public Property ValidateOnChange() As BooleanAllows for the SVT control to invoke its validation code when the TextChanged event is raised. This property can be set at design time.
Public Property ValidateOnPopulate() As BooleanAllows for the SVT control to invoke its validation code when the control is populated by way of the BizO property. This property can be set at design time.
Public Property ValidateOnNoChange() As BooleanAllows for the SVT control to invoke its validation code when no changes have been made. This property can be set at design time.

Validation

The main focus of the SVT control initially was the validation aspect.

VB
Protected Overridable Sub EditBox_Validated(ByVal sender As System.Object, _
          ByVal e As System.EventArgs) Handles EditBox.Validated

    If ValidateOnNoChange = False And mBlnHasChanged = False Then Return

    If MyClass.SelfValidate And Not BizO Is Nothing Then

        Dim txt As Windows.Forms.TextBox = CType(sender, Windows.Forms.TextBox)

        Try

            BizoSetValue(txt.Text)

            If mBlnHasChanged = True Then mStrErrMsg = String.Empty

        Catch ex As Exception

            If Not ex.InnerException Is Nothing Then
                mStrErrMsg = ex.InnerException.Message
            Else
                mStrErrMsg = ex.Message
            End If

        Finally

            Dim obj() As Object = {Me, ErrorMessage}
            mObjMeth.Invoke(BizO, obj)

            mBlnHasChanged = False

        End Try


    End If

    RaiseEvent Validated(Me, e)

End Sub

As you can see from the above code, the validation routine checks the ValidateOnNoChange and SelfValidate properties. Once all conditions have been satisfied, the BizoSetValue protected method is then called:

VB
Protected Sub BizoSetValue(ByVal value As Object)

    If BizO Is Nothing Then Return

    If Loading = True Then Return

    If CType(BizO, BusinessBase).UsingCProps Then

        CType(BizO, BusinessBaseCProps).Prop(MyClass.PropName, value)

    Else

        If PropertyObject Is Nothing Then Return
        If PropertyObject.CanWrite Then PropertyObject.SetValue(BizO, value, Nothing)

    End If

End Sub

The BizoSetValue method also checks to ensure that the property in the business object (PropertyObject) being referenced actually exists and can be written to. The method then checks the type of business object in use, and sets the value accordingly. Referenced within is a reference to PropertyObject:

VB
Protected ReadOnly Property PropertyObject() As Object
    Get

        If mObjProp Is Nothing Then

            If BizO Is Nothing Then Return Nothing

            If PropName.Equals(String.Empty) Then Return Nothing

            If CType(BizO, BusinessBase).UsingCProps Then
                mObjProp = CType(BizO, BusinessBaseCProps).VTType.GetField(MyClass.PropName)
            Else
                mObjProp = BizO.GetType.GetProperty(MyClass.PropName)
            End If

        End If

        Return mObjProp

    End Get
End Property

Conclusion

I hope the above has provided you with enough of an insight into the SVT control. After the initial design and construction of this control, it was evident that we needed to extend the idea of a self validating control to other more common controls. This need grew into a CheckBox, NumericBox (textbox with numeric input only), DateCombo, ComboBox, and RichTextBox.

Our base forms were then looked at in the interest of continuity and rapid development. These base forms were modified to include OK, Cancel, and Apply functionality. This functionality makes use of the BizO object, and allows for very minimal code to be written while still providing fully featured forms. The only need for custom coding is where custom functionality is required. Our in house application has now been in production use for more than two years, and is continually being added to, providing further support and enhancements.

Originally, we were a little skeptical about the use of reflection and how it may sluggish performance. Our other major concern was a potentially larger memory footprint and hence further memory related issues. To date, we haven't experienced any performance or memory issues, and some of the forms that have been developed are quite large and complex in nature.

Future Updates

It seems that this article and the Business Object Property Validation article have had a natural flow from each other. With this in mind, I intend to produce additional articles detailing some of the questions that I'm sure will come from these two, like:

  • What does the BusinessRules assembly do?
  • How have the base forms been designed and constructed?
  • What other controls have been produced and how?
  • How does this article relate to a real world n-tier solution?

Please enjoy.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Chief Technology Officer
Australia Australia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralValidation tied to the UI Pin
Liqdfire24-Nov-09 7:07
Liqdfire24-Nov-09 7:07 
GeneralRe: Validation tied to the UI Pin
Edward Steward24-Nov-09 12:29
Edward Steward24-Nov-09 12:29 
GeneralThis is good but 1 question Pin
Sacha Barber17-May-08 21:58
Sacha Barber17-May-08 21:58 
GeneralRe: This is good but 1 question Pin
Edward Steward17-May-08 22:26
Edward Steward17-May-08 22:26 
GeneralRe: This is good but 1 question Pin
Sacha Barber18-May-08 0:17
Sacha Barber18-May-08 0:17 
GeneralRe: This is good but 1 question Pin
Edward Steward18-May-08 0:21
Edward Steward18-May-08 0:21 
GeneralRe: This is good but 1 question Pin
Sacha Barber18-May-08 5:26
Sacha Barber18-May-08 5:26 
GeneralRe: This is good but 1 question Pin
Edward Steward18-May-08 14:04
Edward Steward18-May-08 14:04 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.