Working with the .NET MaskedTextBox in VB.NET

The .NET MaskedTextBox control provides a mechanism to validate user input on a Form. For example, if you need a TextBox that should accept dates in a certain format, you should set the masking in the MaskedTextBox. The MaskedTextBox uses the MaskedTextProvider mask syntax. The mask is used to distinguish between proper and improper user input. More on the Mask Syntax later.

Key Properties of a MaskedTextBox


The MaskedTextBox.AllowPromptAsInput Property determines whether PromptChar can be entered as valid data by the user. More on the PromptChar Property later.


The MaskedTextBox.AsciiOnly Property determines if a MaskedTextBox control accepts characters outside of the ASCII character set. If you do not know what ASCII is, please visit this link.


The MaskedTextBox.BeepOnError Property raises the system beep for each key stroke that it rejects.


The MaskedTextBox.CutCopyMaskFormat Property determines if literals and prompt characters are copied to the Clipboard.


The MaskedTextBox.HidePromptOnLeave Property indicates whether the prompt characters in the input mask are hidden when the MaskedTextBox loses focus.


The MaskedTextBox.InsertKeyMode Property controls the character insertion behavior of a MaskedTextBox control. The InsertKeyMode state is defined by the InsertKeyMode enumeration.


The MaskedTextBox.Mask Property gets or sets the input mask to use at run time. This is the default property of MaskedTextBox. As stated earlier: The masking language used by a MaskedTextBox control is defined by a MaskedTextProvider, which I will cover in detail later.


The MaskedTextBox.MaskCompleted Property determines if all required inputs have been entered.


The MaskedTextBox.MaskFull Property determines whether all required and optional inputs have been entered.


The MaskedTextBox.PromptChar Property sets the character that will be displayed in the MaskedTextBox for any mask position that was not filled in.


The MaskedTextBox.RejectInputOnFirstFailure Property indicates if the parsing of user input should stop after the first invalid character is reached.


The MaskedTextBox.ResetOnSpace Property determines how a space input character should be handled:

  • If the input character is a space, and does not match the current non-editable character, the masking engine skips ahead to the next character in the mask.
  • If the input character is not a space, and does not match the current non-editable character, the masking engine will remain at the current mask position.


The MaskedTextBox.SkipLiterals Property indicates if you are allowed to re-enter literal values.

Key Events of a MaskedTextBox


The MaskedTextBox.MaskChanged Event occurs after the input mask has been changed.


The MaskedTextBox.MaskInputRejected Event (the default of the MaskedTextBox control) takes place when the input does not match the corresponding format element of the input mask. The MaskInputRejected event is raised in the following situations:

  • An input character does not match the corresponding format element
  • The user is trying to input extra characters beyond the end of the mask
  • A paste operation inserts a character that does not match its associated format element


The MaskedTextBox.TypeValidationCompleted Event after the MaskedTextBox has finished parsing the current value with the help of the ValidatingType property. The MaskedTextBox.ValidatingType Property gets or sets the data type used to verify the data input.

MaskedTextProvider Syntax

MaskedTextProvider supplies a mask-parsing service that can be used by controls that support masking.

Following is a list and description of masking characters.

  • 0: Digit, required. Value between 0 and 9.
  • 9: Digit or space, optional.
  • #: Digit or space, optional. If this position is blank in the mask, it will be rendered as a space in the Text property.
  • L: Letter, required. Restricts input to ASCII letters a-z and A-Z.
  • ?: Letter, optional. Restricts input to ASCII letters a-z and A-Z.
  • &: Character, required.
  • C: Character, optional. Any non-control character.
  • A: Alphanumeric, required.
  • a: Alphanumeric, optional.
  • .: Decimal placeholder.
  • ,: Thousands placeholder.
  • :: Time separator.
  • /: Date separator.
  • $: Currency symbol.
  • <: Shift down. Converts all characters that follow to lowercase.
  • >: Shift up. Converts all characters that follow to uppercase.
  • |: Disable a previous shift up or shift down.
  • \: Escape. Escapes a mask character, turning it into a literal. "\\" is the escape sequence for a backslash.
  • All other characters: Literals.
  • All non-mask elements will appear as themselves within MaskedTextBox.
  • Literals will always occupy a static position in the mask at run time. The user cannot delete them.

Practical Application

You will create a small project now. Create a new Visual Basic Windows Forms application. Once the Form has loaded, add a few MaskedTextBoxes to your form; I have added five. Your design should resemble Figure 1.

Figure 1: Design

You may notice that the MaskedTextBoxes shown in Figure 1 looks different from yours. This is because I have set up masks on each. To set up a mask, select the Mask property in the Properties Window, as shown in Figure 2:

Mask Property
Figure 2: Mask Property

Click the Ellipses button. The Input Types dialog box will appear displaying a list of predefined formats (see Figure 3), and an option to add your own custom format:

Input Types
Figure 3: Input Types

Add the following code to one of your MaskedTextBoxes:

   Private Sub MaskedTextBox1_MaskInputRejected(sender As Object, _
         e As MaskInputRejectedEventArgs) Handles _

      MessageBox.Show("Error: " + e.RejectionHint.ToString())
   End Sub

This code simply informs the user that he/she has typed in the wrong data, as in the case of Figure 4 where I have entered letters instead of numbers.

Figure 4: Error


The MaskedTextBox is a very handy tool to have at your disposal, especially when dealing with user input.

This article was originally published on September 15th, 2017

About the Author

Hannes DuPreez

Hannes du Preez is a self-taught developer who started learning to program in the days of QBasic. He has written several articles over the years detailing his programming quests and adventures. .NET is his second love, just after his wife and kid. He has always been an avid supporter of .NET since the beginning and is an expert in VB and C#. He was given the Microsoft Most Valuable Professional Award for .NET (2008–2017). He has worked as a moderator and an article reviewer on online forums and currently works as a C# developer and writes articles for CodeGuru.com, Developer.com, DevX.com, and the Database journal.
His first book Visual Studio 2019 In Depth is currently on sale on Amazon and Bpb Publications.

You could reach him at: ojdupreez1978[at]gmail[dot]com

Related Articles


Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date