Click here to Skip to main content
12,887,548 members (28,116 online)
Click here to Skip to main content
Add your own
alternative version


58 bookmarked
Posted 25 Apr 2003

C# MaskedEdit Control

, 26 Apr 2003 CPOL
Rate this:
Please Sign up or sign in to vote.
C# MaskedEdit Control similiar to the MS Access masked edit control

Sample Image - MaskedEdit.gif


Visual Studio.NET and the .NET Framework includes many very useful controls. Unfortunately a MaskedEdit control was not among them. Anyone who has used the VS 6.0 MaskedEdit control knows that Microsoft's last attempt was not without its problems. MS Access developers have always had a useable MaskedEdit control. I wonder sometimes why Microsoft hasn't adapted the Access control to their other tools. Anyway I decided to tackle this very useful but missing control.

After spending a few hours working to handle character selection in the TextBox based control, I began to understand why someone might avoid building this control. Then came setting the MaskedEdit control value which introduced a new set of challenges. The difficulty of building a bullet proof MaskedEdit became apparent very rapidly - so this is fair warning, don't forget to test, test, test.


The MaskedEdit control is loosely based on the Access mask behavior and includes the following features:

  • Standard InputMasks
    • Social Security Number (SSN)
    • Phone Numbers
    • Zip Codes
  • Custom InputMasks
  • Runtime changable InputMask
  • IsValid Property
  • Text Property (includes literals)
  • Value Property (excludes literals)
  • Input Char Property (defaults to '_')

Using the MaskedEdit Control

The following characters have been defined as mask characters for the MaskedEdit control

0 - digit required
9 - digit optional
L - lower case letter (a-z) required
l - lower case letter optional
U - upper case letter (A-Z) required
u - upper case letter optional
A - any case letter required
a - any case letter optional
D - letter or digit required
d - letter or digit optional
C - any char including punctuation

If you are not familiar with mask characters, you can find information in the MSDN library under "InputMask Property"

Regular expressions are used to define each mask char above. So for example '0' and '9' mask characters are coded as:

m_regexps.Add('0', @"[0-9]");        // digit required
m_regexps.Add('9', @"[0-9 ]");        // digit/space not required

You can find all the other mask character RegExp's in the source code for the MaskedEdit control. The space ' ' character is used as the optional character. Validation code in other parts of the MaskedEdit control use the space character to determine if an entry is required. This is a key consideration if you decide to define your own input mask characters.

The input mask chars that I've defined are basically groups of digits, upper and lower case letters along with ANY mask character 'C'. I think these should be suitable for many circumstances but if you have a need for more finely tuned input restrictions, the MaskedEdit control can handle it. For example, suppose you have a need to input hexadecimal values. None of the current input mask chars handle hex digits (0 through 9 plus A through F). So lets add a new mask char for hex digits, which would look like

m_regexps.Add('H', @"[0-9A-F]");        // hex digit required

This regexp would permit any of these characters "0123456789ABCDEF". So an InputMask for a 16 bit hex value might look like "\0xHHHH" would be displayed as 0x____ with 4 positions for hex digit entry. This means that you can adapt the MaskedEdit control to handle new input requirements. Don't forget that if you add an input mask char '-', that the standard InputMasks will be adversely affected.

If you're paying close attention you may have a question about the InputMask above. What is the '\' char? If you need to add a literal char that is already defined as a mask char then you will need to use the escape char '\'. This causes the MaskedEdit control to consider the next InputMask character a literal instead of an input mask character. For example, let suppose we want an InputMask to allow the user to input part numbers in the form


where UL- are literals and 1234 represent required digits. Both 'U' and 'L' are input mask characters for Upper and Lower case characters. Adding literal 'U' or 'L' means that we must add the escape character to designate them as literals instead of input mask characters, so our InputMask would be


Note that the '-' does not need the escape char prefix since it is not defined as a mask char.

MaskedEdit Properties

Next lets look at how to get and set the value contained in the MaskedEdit control.

Text Property - This property sets/gets the entire string contained in the control including literals. So an SSN input mask with data filled in such as


will return "123-45-6789".

Value Property - This property sets/gets ONLY the input chars from the control excluding literals. So the example above would return "123456789". The value prop does NOT return optional chars that have not been entered by the user so for example:

(___) 123-4567

entered into a phone number mask would return "1234567" from the Value prop. Optional input mask chars cause some interesting problems that I have worked to handle. I would recommend using the MaskedEditTest application to test any InputMask you plan to use to make sure it works as you would expect.

The remainder of the MaskedEdit properties are pretty sraight forward.

  • IsValid Property - Returns true if all required input chars have been entered correctly.
  • InputChar Property - Defaulted to '_' underscore char but can be set to any other char except input mask chars or the escape char.
  • ErrorInvalid Property - Defaulted to false. Setting this to true will cause the MaskedEdit control to throw errors if attempts are made to set Text or Value props to an invalid string. Setting this to true during debugging could prove very useful.
  • StdInputMask Property - enum to select a standard input mask including
    • None - makes the MaskedEdit control work like a standard text box
    • SSN
    • Phone
    • Zip
    • Custom - use this to define custom input mask
  • InputMask Property - Use this to set custom InputMasks. The InputMask CAN be changed during runtime. The MaskedEdit control attempts to convert the current text into the new mask. This is LIKELY to cause problems. If you need to reset the mask during runtime, I would recommend setting the Value to an empty string prior to resetting the InputMask.

Usage Considerations

The MaskedEdit should work well for inputting "known" values such as SSN, phone and zip. The important point is that the user must KNOW what is to be entered since the mask doesn't give any clues as to the type of input expected (digits?, alpha chars?, ???). Tool tips or help files might be useful to explain complex input masks. Providing messages when invalid characters are entered by the user is a possible improvement. I am considering adding an InValid event, and an InValidMessage property to allow developers to add customized messages fired during invalid entry. Let me know your thoughts.

Setting the InputMask to only literal chars makes this a label control. I considered adding handling for this possibility but decided against it. If you try this, be prepared to catch errors :-\

Selection of characters in the MaskedEdit control is designed to keep the selection on input chars only and to skip over literals. This causes a somewhat peculiar selection behavior.

The base class TextBox has an extensive number of properties. I have added handling for some of these properties that I know affect the MaskedEdit control. There may be other props that I haven't considered that will cause problems or errors. Please post a note if you find one.


  1. Test, Test, Test I've spent more time than I would like to admit testing this control but as anything with this level of complexity, undiscovered bugs may exist. Please post a note if you find a bug.
  2. Add data binding features. I would anticipate binding the Text, Value, and InputMask properties. Let me know your thoughts on this.
  3. The MS Access has a feature to automatically upper/lower case input '<' = lower case, '>' = uppercase. This feature is not included in the MaskedEdit control. Let me know if you have a need for this feature, and I will work to add it on Rev. 2


  • Released Rev 1.0 4/2/2003


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Oscar Bowyer
Web Developer
United States United States
No Biography provided

You may also be interested in...


Comments and Discussions

GeneralMy vote of 1 Pin
Member 1037036818-Nov-13 23:05
memberMember 1037036818-Nov-13 23:05 
GeneralProblem with download Pin
ArielR30-Oct-08 13:09
memberArielR30-Oct-08 13:09 
GeneralRead-only Pin
AJR 11218-May-06 8:10
memberAJR 11218-May-06 8:10 
GeneralNeed Wildcard Numeric Pin
rmyott19-Jan-06 5:22
memberrmyott19-Jan-06 5:22 
QuestionDate Format ? Pin
fabrice_de3-Jan-06 23:24
memberfabrice_de3-Jan-06 23:24 
AnswerRe: Date Format ? Pin
Oscar Bowyer4-Jan-06 4:34
memberOscar Bowyer4-Jan-06 4:34 
GeneralFixes Pin
Bill Pfeil14-Oct-05 8:50
memberBill Pfeil14-Oct-05 8:50 
GeneralCtrl + arrow keys are bad Pin
tomcat200129-Jun-05 10:27
membertomcat200129-Jun-05 10:27 
AnswerRe: Ctrl + arrow keys are bad Pin
f.colo11-Dec-06 21:43
memberf.colo11-Dec-06 21:43 
GeneralRev 2.0 Pin
gr8Kiwi22-Jun-05 9:34
membergr8Kiwi22-Jun-05 9:34 
GeneralRe: Rev 2.0 Pin
Oscar Bowyer28-Jun-05 16:01
memberOscar Bowyer28-Jun-05 16:01 
QuestionDead link? Pin
GreenWire19-May-05 7:03
memberGreenWire19-May-05 7:03 
GeneralPaste Pin
jab_be25-Oct-04 1:45
memberjab_be25-Oct-04 1:45 
GeneralBug Focus() Pin
Anonymous22-Oct-04 1:48
sussAnonymous22-Oct-04 1:48 
GeneralIP Pin
Taha Zayed24-Sep-04 15:32
memberTaha Zayed24-Sep-04 15:32 
GeneralRe: IP Pin
Oscar Bowyer25-Sep-04 6:41
memberOscar Bowyer25-Sep-04 6:41 
GeneralUsing it for a date Pin
Luis Alonso Ramos3-Sep-04 6:54
memberLuis Alonso Ramos3-Sep-04 6:54 
Generalit crashes when you bind text property to database Pin
lukaszkn15-Jul-04 13:54
memberlukaszkn15-Jul-04 13:54 
GeneralRe: it crashes when you bind text property to database Pin
Annom9-Sep-04 10:18
sussAnnom9-Sep-04 10:18 
GeneralRe: it crashes when you bind text property to database Pin
KAM027-Feb-06 10:37
memberKAM027-Feb-06 10:37 
GeneralAutomatic casing Pin
emelnl8-Jun-04 2:31
memberemelnl8-Jun-04 2:31 
GeneralRe: Automatic casing Pin
kurilka2-Jul-04 1:25
memberkurilka2-Jul-04 1:25 
GeneralA small change Pin
blesch13-Apr-04 6:51
memberblesch13-Apr-04 6:51 
GeneralYour Zip is a trash! Pin
Razor...19-Mar-04 21:22
memberRazor...19-Mar-04 21:22 
GeneralHandling Copy/Cut/Paste/Delete/Undo... Pin
Paul Young11-Mar-04 0:10
sussPaul Young11-Mar-04 0:10 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170424.1 | Last Updated 26 Apr 2003
Article Copyright 2003 by Oscar Bowyer
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid