3.5. Validate Input While the User Types
Visual Basic 6 and Access both provide
developers with masked editing controls: text
input controls that automatically format your input as you type it in
based on a specific mask. For example, if you
type 1234567890 into a masked input control that uses a
telephone-number mask, the number is displayed as the string (123)
456-7890.
Note: VB 6 programmers accustomed to the ActiveX MaskedEdit
control were disappointed to find . NET did not include a
replacement. In . NET 2.0, the new MaskedTextBox fills the
gap.
Masked input controls not only improve the presentation of certain
valuesthey also prevent errors. Choosing the right mask
ensures that certain characters will be rejected outright (for
example, a telephone- number mask will not accept letters). Masked
input controls also neatly avoid canonicalization
errors, which occur when there is more than one way of
representing the same information. For example, with the telephone
number mask, the user will immediately realize that an area code is
required, even if you don't specifically explain
this requirement.
3.5.1. How do I do that?
.NET 2.0 includes a new control named
MaskedTextBox that extends the
TextBox control. Once you've
added a MaskedTextBox to a form, you can set the
mask in two ways:You can choose one of the prebuilt masks.You can define your own custom mask.
To set a mask, click the MaskedTextBox smart tag
and select Set Mask. The Input Mask dialog box appears, with a list
of commonly used masks, including masks for phone numbers, zip codes,
dates, and so on. When you select a mask from the list, the mask is
displayed in the Mask text box. You can now customize the mask. You
can also try the mask out using the Try It text box, as shown in
Figure 3-7.
Figure 3-7. Selecting a mask for the MaskedTextBox

Note: Thanks to the wonders of COM Interop, it's
still possible to use the VB 6 MaskedEdit control in . NET. However,
the . NET MaskedTextBox control improves on several limitations and
quirks in the MaskedEdit control, so it's still
superior.
The mask you choose will be stored in the
MaskTextBox.Mask property. Once
you've chosen a mask, it will be applied whenever
the user types in the MaskedTextBox. If you want
to respond to user mistakes (like invalid characters) to provide more
information, you can respond to the
MaskInputRejected event.If you want to build a custom mask, you need to understand a little
more about how masking works. Essentially, a mask is built out of two
types of characters: placeholders, which
designate where the user must supply a character; and
literals, which are
used to format the value. For example, in the phone number mask
(999)-000-000, the hyphens and brackets are literals. These
characters are always present and can't be deleted,
modified, or moved by the user. The number 0 is a placeholder that
represents any number character, while the number 9 is a placeholder
that represents an optional numeric character.Table 3-1 lists and explains all the characters
you can use to create a mask. You can use this as a reference to
build your own masks.
MaskedTextBox provides (and you might want to take
advantage of). These include:BeepOnError
If the user inputs an invalid character
and BeepOnError is TRue, the
MaskedTextBox will play the standard error chime.
PromptChar
When the text box is empty, every
required value is replaced with a prompt character. By default, the
prompt character is the underscore (_), so a mask
for a telephone number will display (_ _ _)-_ _ _-_ _ _
_ while empty.
MaskCompleted
Returns TRue if there
are no empty characters in the text box (meaning the user has entered
the required value).
InputText
InputText returns the data in the
MaskedTextBox without any literal characters. For
example, in a MaskedTextBox that allows the user
to enter a telephone number, the Text property
will return the fully formatted number, like
(123)-456-7890, while InputText
returns just the numeric content, or 1234567890.
3.5.2. What about...
...using masked editing in other input controls? It is possible, but
not easy. The MaskedTextBox relies on a special
MaskedEditProvider
class in the
System.ComponentModel
namespace.To create a different type of masked control, you need to create a
custom control that uses the MaskedEditProvider
internally. When your control receives a key press, you need to
determine the attempted action and pass it on to the
MaskedEditProvider using methods like
Add( ), Insert( ),
Remove( ), and Replace( ).
Then, you can retrieve the new display value by calling
MaskedEditProvider.ToDisplayString( ), and refresh
your custom control appropriately. The hard part is handling all of
this low-level editing without causing flicker or losing the
user's place in the input string. For more
information, you can refer to the full example
that's included with the downloadable code in the
MaskedEditing project.