]>
Commit | Line | Data |
---|---|---|
1 | \section{wxValidator overview}\label{validatoroverview} | |
2 | ||
3 | Classes: \helpref{wxValidator}{wxvalidator}, \helpref{wxTextValidator}{wxtextvalidator}, | |
4 | \helpref{wxGenericValidator}{wxgenericvalidator} | |
5 | ||
6 | The aim of the validator concept is to make dialogs very much easier to write. | |
7 | A validator is an object that can be plugged into a control (such as a wxTextCtrl), and | |
8 | mediates between C++ data and the control, transferring the data in either direction | |
9 | and validating it. It also is able to intercept events generated | |
10 | by the control, providing filtering behaviour without the need to derive a new control class. | |
11 | ||
12 | You can use a stock validator, such as \helpref{wxTextValidator}{wxtextvalidator} (which does text | |
13 | control data transfer, validation and filtering) and | |
14 | \helpref{wxGenericValidator}{wxgenericvalidator} (which does data transfer for a range of controls); | |
15 | or you can write your own. | |
16 | ||
17 | \wxheading{Example} | |
18 | ||
19 | Here is an example of wxTextValidator usage. | |
20 | ||
21 | \begin{verbatim} | |
22 | wxTextCtrl *txt1 = new wxTextCtrl(this, VALIDATE_TEXT, "", | |
23 | wxPoint(10, 10), wxSize(100, 80), 0, | |
24 | wxTextValidator(wxFILTER_ALPHA, &g_data.m_string)); | |
25 | \end{verbatim} | |
26 | ||
27 | In this example, the text validator object provides the following functionality: | |
28 | ||
29 | \begin{enumerate}\itemsep=0pt | |
30 | \item It transfers the value of g\_data.m\_string (a wxString variable) to the wxTextCtrl when | |
31 | the dialog is initialised. | |
32 | \item It transfers the wxTextCtrl data back to this variable when the dialog is dismissed. | |
33 | \item It filters input characters so that only alphabetic characters are allowed. | |
34 | \end{enumerate} | |
35 | ||
36 | The validation and filtering of input is accomplished in two ways. When a character is input, | |
37 | wxTextValidator checks the character against the allowed filter flag (wxFILTER\_ALPHA in this case). If | |
38 | the character is inappropriate, it is vetoed (does not appear) and a warning beep sounds. | |
39 | The second type of validation is performed when the dialog is about to be dismissed, so if | |
40 | the default string contained invalid characters already, a dialog box is shown giving the | |
41 | error, and the dialog is not dismissed. | |
42 | ||
43 | \wxheading{Anatomy of a validator} | |
44 | ||
45 | A programmer creating a new validator class should provide the following functionality. | |
46 | ||
47 | A validator constructor is responsible for allowing the programmer to specify the kind | |
48 | of validation required, and perhaps a pointer to a C++ variable that is used for storing the | |
49 | data for the control. If such a variable address is not supplied by the user, then | |
50 | the validator should store the data internally. | |
51 | ||
52 | The \helpref{wxValidator::Validate}{wxvalidatorvalidate} member function should return | |
53 | TRUE if the data in the control (not the C++ variable) is valid. It should also show | |
54 | an appropriate message if data was not valid. | |
55 | ||
56 | The \helpref{wxValidator::TransferToWindow}{wxvalidatortransfertowindow} member function should | |
57 | transfer the data from the validator or associated C++ variable to the control. | |
58 | ||
59 | The \helpref{wxValidator::TransferFromWindow}{wxvalidatortransferfromwindow} member function should | |
60 | transfer the data from the control to the validator or associated C++ variable. | |
61 | ||
62 | There should be a copy constructor, and a \helpref{wxValidator::Clone}{wxvalidatorclone} function | |
63 | which returns a copy of the validator object. This is important because validators | |
64 | are passed by reference to window constructors, and must therefore be cloned internally. | |
65 | ||
66 | You can optionally define event handlers for the validator, to implement filtering. These handlers | |
67 | will capture events before the control itself does. | |
68 | ||
69 | For an example implementation, see the valtext.h and valtext.cpp files in the wxWindows library. | |
70 | ||
71 | \wxheading{How validators interact with dialogs} | |
72 | ||
73 | For validators to work correctly, validator functions must be called at the right times during | |
74 | dialog initialisation and dismissal. | |
75 | ||
76 | When a \helpref{wxDialog::Show}{wxdialogshow} is called (for a modeless dialog) | |
77 | or \helpref{wxDialog::ShowModal}{wxdialogshowmodal} is called (for a modal dialog), | |
78 | the function \helpref{wxWindow::InitDialog}{wxwindowinitdialog} is automatically called. | |
79 | This in turn sends an initialisation event to the dialog. The default handler for | |
80 | the wxEVT\_INIT\_DIALOG event is defined in the wxWindow class to simply call | |
81 | the function \helpref{wxWindow::TransferDataToWindow}{wxwindowtransferdatatowindow}. This | |
82 | function finds all the validators in the window's children and calls the TransferToWindow | |
83 | function for each. Thus, data is transferred from C++ variables to the dialog | |
84 | just as the dialog is being shown. | |
85 | ||
86 | \normalbox{If you are using a window or panel instead of a dialog, you will need to | |
87 | call \helpref{wxWindow::InitDialog}{wxwindowinitdialog} explicitly before showing the | |
88 | window.} | |
89 | ||
90 | When the user clicks on a button, for example the OK button, the application should | |
91 | first call \helpref{wxWindow::Validate}{wxwindowvalidate}, which returns FALSE if | |
92 | any of the child window validators failed to validate the window data. The button handler | |
93 | should return immediately if validation failed. Secondly, the application should | |
94 | call \helpref{wxWindow::TransferDataFromWindow}{wxwindowtransferdatafromwindow} and | |
95 | return if this failed. It is then safe to end the dialog by calling EndModal (if modal) | |
96 | or Show (if modeless). | |
97 | ||
98 | In fact, wxDialog contains a default command event handler for the wxID\_OK button. It goes like | |
99 | this: | |
100 | ||
101 | \begin{verbatim} | |
102 | void wxDialog::OnOK(wxCommandEvent& event) | |
103 | { | |
104 | if ( Validate() && TransferDataFromWindow() ) | |
105 | { | |
106 | if ( IsModal() ) | |
107 | EndModal(wxID_OK); | |
108 | else | |
109 | { | |
110 | SetReturnCode(wxID_OK); | |
111 | this->Show(FALSE); | |
112 | } | |
113 | } | |
114 | } | |
115 | \end{verbatim} | |
116 | ||
117 | So if using validators and a normal OK button, you may not even need to write any | |
118 | code for handling dialog dismissal. | |
119 | ||
120 | If you load your dialog from a resource file, you'll need to iterate through the controls | |
121 | setting validators, since validators can't be specified in a dialog resource. | |
122 |