(Print this page)

The TextBox and the MaskedTextbox controls
Published date: Thursday, June 1, 2006
On: Moer and Éric Moreau's web site

Microsoft provides great enhancements on the TextBox control. It also reintroduces the MaskedTextbox control into your toolbox. I hear you say: I have been using these controls for the last 10 years, why should I read about these basic controls? Are you aware of the changes Microsoft did on the TextBox? Do you know when (and when not) to use the MaskedTextbox?

This article will explore some of new features of the TextBox and introduce you to the newest version of the MaskedTextbox. I will let you decide if you want to keep using this latest control in your project.

Notice that I am talking of the controls available in Visual Studio 2005.

Exploring properties

Just a quick note before starting this column to have you remember that when you want to explore many properties like we will do in this column, I always add a Property Grid control to my form and set the SelectedObject property of this object to the control I want to explore. It allows me to change properties on the fly and continue testing the control without having to continuously stop and restart the test application.

For more information on the Property Grid control, see my article of June 2004.

Figure 1: The test application

The TextBox control

The first thing you might have discovered the first time you placed a TextBox control in a VS 2005 project is that the Text property is now empty by default. It was time.

Another little (but useful under some circumstances) property is called HideSelection. You probably have already seen this property in the Treeview control. This property is False by default and it indicates that the selection should be hidden when the control loses focus.

But the coolest enhancement is the auto-completion feature. To discover this feature easily, set the AutoCompleteMode property to Suggest and set the AutoCompleteSource property to FileSystemDirectories. Run your test and start typing a path (c:\). As soon as you type the backslash, you should see a list of folders in a drop down list. Wow. You haven’t placed any ComboBox on your form. It is a TextBox.

The AutoCompleteMode accepts 4 values:

  • Suggest: displays a drop-down list of values
  • Append: attempts to complete the current input of the user (highlighting the appended characters)
  • SuggestAppend: a mixture of Suggest (drop-down list) and Append (attempts to complete)
  • None: plain old TextBox with no auto-completion.

The AutoCompleteSource specifies the source of the automatic completion functionality and has more choices:

  • FileSystemDirectories: uses directory names
  • FileSystem: uses directory names and files
  • RecentlyUsedList: URLs (mostly file:// and http://) most recently used
  • HistoryList: URLs of the history list
  • AllUrl: equivalent of HistoryList and RecenlyUsedList
  • AllSystemSources: equivalent of AllUrl and FileSystem
  • CustomSource: uses the strings you put yourselft into the AutoCompletionStringCollection (at design time or using the Add method at runtime)
  • None: no automatic completion source

The BackColor property can now be modified even when the control is disabled (Enabled = False) but not the ForeColor. Neither was adjustable in VS.Net 2003. This means that I still have to keep my customization for the visually impaired users who cannot read the text when the control is disabled (see my article of July 2005).

The MaskedTextbox control

Remember the days of VB.Old (at least 5/6)? There was a control named “Microsoft Maked Edit Control” or the MaskEdBox. I never was a big fan of this control because of the many limitations. I heard no one complained that this control was missing! Let me show you some caveats of this control that won’t make me a big fan of this newer version. Under some circumstances, the control might to do a decent job but you need to be able to determine when and I will help you in that.

The purpose of this control is to prevent users entering invalid characters into a field. This is very good thing. It is not validating after the all the characters have been entered. It stops inputting them.

Let’s start by explaining some properties specific to the MaskedTextbox:

  • Mask: the string that dictates allowed characters
  • BeepOnError: indicates whether the control beeps when the user types an invalid character (default is False)
  • PromptChar: the character used as the placeholder for empty spots (default is the underline character)
  • TextMaskFormat: indicates how the Text property returns the value (default is IncludeLiterals). This let you specify if you want the literals (fixed characters from the Mask) and the PromptChar to be visible from the Text property. The values available are IncludePrompt (includes the PromptChar but not the literals), IncludeLiterals (includes literals but not the PromptChar), IncludePromptAndLiterals (includes both), and ExcludePromptAndLiterals (excludes both). This property is very useful when it’s time to send the value to the database because you normally don’t want to store literals into the database.
  • CutCopyMaskFormat: indicates if the value copied to the clipboard will includes literals and/or prompt characters (default is IncludeLiterals). The same 4 values as the TextMaskFormat property are available.

Figure2: Pre-built available mask.

The Mask property comes with some pre-built values like US zip code, date, phone number as shown in figure 2.

If you select the “Phone number” mask, it will easily stop users from entering invalid characters. Users don’t have to mess with the literals neither. Mask like this one work as expected and I don’t have to complain.

If you select the “Short date” mask, only digits will be allowed but the control will not stop entering an invalid date. Values like 33/33/3333 are accepted! Only allowable characters were inputted but the value is not valid date. So better stay with the DateTimePicker for date inputs.

The last mask available is called “Custom” and it let you specify your own mask. The most common characters available to specify a mask are the following:

  • 0: required digit
  • 9: optional digit
  • A: required alphanumeric
  • a: optional alphanumeric
  • #: optional digit or space, or plus or minus symbol
  • L: required letter
  • ?: optional letter
  • . (dot): decimal place holder (as defined by your culture)
  • , (comma): thousands place holder (as defined by your culture)
  • $: currency symbol (as defined by your culture)
  • : (colon): separate time values (as defined by your culture)
  • /: separate date values (as defined by your culture)
  • <: force to lower case
  • >: force to upper case

With these characters, I think that it should be easy to create a mask for entering numerical values like a salary. A mask like ###,##0.00 (combination of optional and required digits and separators) looks good. The problem with a mask like this one is that if you need to enter a value that doesn’t exactly fit your mask, the mask won’t let you go. For example, try to enter 12.34 into this field and you will discover that you have to be correctly place into the field to type the decimal point (otherwise it beeps if the BeepOnError is True). Your users won’t like you if you force them working with a field like this one.

Another example where a mask is very useful but where the control fails is a Canadian postal code (part number might also look like this). The mask should be set as >L0L 0L0 (force uppercase and required letters and digits). If you enter a value like “H0H 0H0” (Santa Clause postal code) it goes well. But what if you entered an invalid first character? You cannot delete the character (neither with the Delete key nor the backspace key) because the following character does not meet the mask. To fix your input, you need to highlight the character to be replaced or switch to overwrite mode. I don’t know about your users but mine would kill me!

So I think you know by now that this control is not validating the value but the keys pressed (or pasting a value) and the mask needs to be quite simple in order to have your users comfortable to work with. I think there are many cases where this control could be used but there are much more where you should find another way to get data from users.

Conclusion

I hope you will add the new abilities of the Textbox to extend your current applications and I also hope you are not discouraged about the MaskedTextbox control. I only want you to know the limitations of it.

I hope you appreciated the topic and see you next month.


(Print this page)