When, Valid
These two events are just about the only carryovers from FoxPro 2.x's READ that are still useful. When fires when a control is offered focus. If When returns .T., the control can have the focus and its GotFocus event fires. (When also fires at a few other times—see below.) A good rule of thumb is for textual controls (text box, edit box, spinner), Valid fires whenever the control loses focus and determines whether it's allowed to lose focus. If so, the control's LostFocus fires. For non-textual controls, Valid fires when the user does something that could change the control's Value.
Usage |
PROCEDURE oObject.When | oObject.Valid [ LPARAMETERS nIndex ] |
The nIndex parameter is passed when oObject is a control array. That's as it should be. What isn't as it should be is that, when some types of controls are placed in a control array, the When and Valid for the control array fire only if a procedure actually exists for the same event in the class definition for the control. That's right—it's not enough to define When and Valid for the control array. At least some of the time, you have to do so for the types of objects in the array, too, even though that code never executes. (ErrorMessage and Message have the same weird behavior. We haven't tested every type of control in this scenario, but the problem occurs at least for text boxes, edit boxes, spinners and check boxes.) |
Valid is trickier. It can return either a logical or a numeric value. Many controls ignore most of the return values. Only textual controls (text box, edit box, spinner and combo box with Style = 0) pay attention to a return value of .F. or 0. For other controls, despite Help to the contrary, no matter what you return, focus is permitted to leave the object. Since the other controls present only valid options in the first place, this is appropriate behavior—it's just documented wrong. |
Watch out for this one. The Valid and the LostFocus of a control don't fire if the user action doesn't cause the control to lose focus. We know that sounds obvious, but what might not be so obvious is the list of things that don't take focus from a control. For example, clicking a button on a toolbar doesn't take focus from the control that had it. Neither does making a menu selection. So why don't we have a bug icon on this one? Because it's not a bug. Some of the things that are on menus and toolbars shouldn't change the focus. Think of choosing, say, Edit-Cut from the menu or clicking a Cut button. Do you want the focus to leave the control you're on? Of course not. But if you're coding toolbar buttons to close forms, or menu options to bring up other forms, you may want to consider forcing the last item's Valid to fire to ensure that you're not leaving invalid data behind. See "It's a Feature, Not a Bug" for more on this issue. |
Using WAIT WINDOW in the When of some controls interferes with the control's operation. For example, a WAIT WINDOW in a check box's When prevents the check box from changing value when you click it (though it does get focus). We think that the action needed to clear the WAIT WINDOW fouls things up. WAIT WINDOW NOWAIT is fine, though. |
Example |
* See if user input is acceptable in a text box for grade entry PROCEDURE txtGrade.Valid IF BETWEEN(This.Value,"A","F") RETURN .T. ELSE WAIT WINDOW "Invalid grade. Try again" NOWAIT RETURN .F. ENDIF |
See Also |
Control Arrays, ErrorMessage, GotFocus, LostFocus, Set KeyComp, Set Notify |