Taking Tom's idea you would turn the backcolor red as default, but then not get back to red when a user types 4 characters and afterwards empties the box.
I also don't like a mixture of default setting and code, even though it's no error. I often miss a ResetToDefault() to make sense of the default value, either there is no reset at all or the reset is done to the specific value.
In short, there is a way I think would be most consistent, as all colorc-hanges only happen in one place:
In textbox Init(), InteractiveChange(), and Refresh() have:
In the new RefreshState method have:
Code:
IF LEN( ALLTRIM(This.Value) ) >= 4
This.BackColor = RGB(255,255,255)
ELSE
This.BackColor = RGB(255,96,96)
ENDIF
Perhaps even have an include file defining the colors for sufficient/insufficient input.
And now there are more variants depending on your philosophy of encapsulation. If you look at it from the perspective of the single text box that's encapsulated this way in a decent way to not block the rest, but you could also see it from the perspective of encapsulating all code that handles form validation in one single point, so it's all together. That could be form.validaterecord or part of the cursoradapter or other data access/business logic class object also handling the fetching of data and saving changed data. There4 are good reasons against putting this into the data access, as that's binding it to that specific form, actually indicating wrong data is a frontend job, but knowing the rules indeed is a job of the code to verify correct data before saving completely independent of the form used for the input/editing. So to make this perfect in the sense of good OOP programming the control should not have the rule for correct input encoded, he'll need to ask the business logic if the input is correct:
In the new RefreshState method have:
Code:
IF This.oBizRules.IsValid(This.ControlSource, This.Value)
This.BackColor = VALIDCOLOR
ELSE
This.BackColor = INVALIDCOLOR
ENDIF
Instead of passing both ControlSource and Value only THIS might be passed, but then such an IsValid validation method of a biz rules class would need specific knowledge about what control has which properties, it's sometimes also the RecordSource or Rowsource, that's important. To pass in the Value also is necessary, as the field specified in the ControlSource will only be updated to the display value, when you leave the control, the current value only is in the control.Value property.
In this form of the code this can be put into a data entry textbox used for anything and the rule is checked by whatever business object is set for the textbox. The task of validation is centralized and encapsulated on the level of the whole table in a class that's usable not only in this one form, but any form also used to maintain the same data, in more complex applications that can easily be the case.
To summarize: The native events and methods are not good for a good OOP style of programming, they tempt you to do very local and specific code that's not good on a larger scale. You can complicate it as much as you like or not like and you can set the boundaries of the OOP encapsulation rule differently, that's somewhat a matter of taste, too.
Bye, Olaf.
Olaf Doschke Software Engineering