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