Click here to Skip to main content
16,021,211 members
Articles / Programming Languages / C#
Article

Masked C# TextBox Control

Rate me:
Please Sign up or sign in to vote.
4.10/5 (38 votes)
21 Jan 20042 min read 728.3K   8.5K   128   76
A control that can be used for date, IP address, phone number, SSN, digit and decimal format input

Introduction

The TextBox control is the most used control in a Windows program. It also cause a lot of problem either from QA or the user because of invalid data that was entered. Using a masked control will save a lot of time for the developer and reduce the complaints and bugs.

This masked intelligent user control enhances the function of the TextBox control, which can mask the Date, IP Address, SSN, Phone numbers, digits, decimal and checks the validation, and automatically set the delimiter location.

The property Masked is set to None by default and the control works like a normal TextBox control.
If setting the property to DateOnly, the control is masked to Date format.

It is intelligent.

What the user enters

What is Displayed

12 12/

124

12/04/

13

01/3

3

03/

34

03/04/

14

01/04/

1/

01/

Using the ErrorProvider to handle the invalidate input:

Creating Control:

  1. Start the Visual Studio.NET Windows Forms designer.
  2. Select a new C# project by clicking New from the File menu.
  3. Click Windows control library template on the templates.
  4. Set the Name MaskedTextBox

Then open the maskedTextBox.cs to Change the base class to the System.Windows.Forms.TextBox.

Adding a Property:

C#
public enum Mask {None, DateOnly, PhoneWithArea, IpAddress, 
                  SSN, Decimal, Digit };
private Mask m_mask;
public Mask Maked
{
    get { return m_mask;}
    set {
        m_mask = value;
        this.Text="";
    }
}

Override the OnKeyPress function

C#
this.KeyPress += new
              KeyPressEventHandler(this.OnKeyPress);

private void OnKeyPress(object sender, KeyPressEventArgs e)
{
      MaskedTextBox sd = (MaskedTextBox) sender;
      if (sd.m_IPAddrOnly)
            sd.MaskIpAddr(e);
      if (sd.m_digitOnly)
            sd.MaskDigit(e);
      if(sd.m_ssn)
            sd.MaskPhoneSSN(e, 3, 2);
      if(sd.m_phoneOnly)
            sd.MaskPhoneSSN(e, 3, 3);
      if(sd.m_dateOnly)
            sd.MaskDate(e);
      if(sd.m_decimalOnly)
            sd.MaskDecimal(e);
}

Unboxing the sender and using it to call these function is very important for multiple properties and when more than one control is used in one form, otherwise different controls may share the same variable with another control, which will cause unexpected results.

Double check the masked format:

C#
private void OnLeave(object sender, EventArgs e)            
{                                                           
    MaskedTextBox sd = (MaskedTextBox) sender;            
    Regex regStr;                                         
    switch(m_mask)                                        
    {                                                     
        case Mask.DateOnly:                             
            regStr = new Regex(@"\d{2}/\d{2}/\d{4}"); 
            if(!regStr.IsMatch(sd.Text))              
                errorProvider1.SetError(this, "*"); 
            break;                                    

        case Mask.PhoneWithArea:                        
            regStr = new Regex(@"\d{3}-\d{3}-\d{4}"); 
            if(!regStr.IsMatch(sd.Text))              
                errorProvider1.SetError(this,"**"); 
            break;                                    

        case Mask.IpAddress:                            
            short cnt=0;                              
            int len = sd.Text.Length;                 
            for(short i=0; i<len;i++)                 
                if(sd.Text[i] == '.')               
                {                                   
                    cnt++;                        
                    if(i+1 < len)                 
                        if(sd.Text[i+1] == '.') 
                        {                       
                            errorProvider1.SetError(this, "*"); 
                            break;            
                        }                       
                    }                                   
                    if(cnt < 3 || sd.Text[len-1] == '.')      
                        errorProvider1.SetError(this, "*"); 
                    break;        
                                                
        case Mask.SSN:                                  
            regStr = new Regex(@"\d{3}-\d{2}-\d{4}"); 
            if(!regStr.IsMatch(sd.Text))              
                errorProvider1.SetError(this, "*"); 
            break;     
                                           
        case Mask.Decimal:                              
            break;                                    

        case Mask.Digit:                                
            break;                                    
    }                                                     
}   

Usage

After creating the DLL program, you should add the component into ToolBox. By:

  1. Right click the mouse in the ToolBox, and then select Customize Toolbox to open a dialog.
  2. Select the tab .Net framework component,
  3. Use the browser to find your DLL, check it, then click Ok.

The control should be in the ToolBox and it is ready to use.

That is all. I hope you enjoy it.

History:

Update at 03/04/2002.
Using enum to set the properties.
Add Onleave function to check the invalidation of the controls.
Add Leap year check for Date mask in the CheckDayOfMonth funcrion.

12 July 2002 - updated source download

9 Nov 2003 - updated source download

If you have any comments or find some bugs, I would love to hear about it and make it better. You can reach me at Jibin Pan.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Questionhow to input the text Pin
jirigala29-Nov-02 21:21
jirigala29-Nov-02 21:21 
GeneralDate Format (Avoiding Time) Pin
PNeufeld8-Nov-02 20:27
PNeufeld8-Nov-02 20:27 
GeneralVery Nice Control - Small Bug Pin
Mike Turnbull26-Sep-02 15:41
Mike Turnbull26-Sep-02 15:41 
GeneralRe: Very Nice Control - Small Bug Pin
Jibin Pan16-Oct-02 4:46
Jibin Pan16-Oct-02 4:46 
GeneralNice Work, One suggestion Pin
Nick Chang26-Sep-02 8:12
Nick Chang26-Sep-02 8:12 
GeneralAnother suggestion. Pin
TBombadil18-Jul-02 4:55
TBombadil18-Jul-02 4:55 
GeneralRe: Another suggestion. Pin
Jibin Pan19-Jul-02 9:55
Jibin Pan19-Jul-02 9:55 
GeneralRe: Another suggestion. Pin
James T. Johnson1-Aug-02 18:35
James T. Johnson1-Aug-02 18:35 
Jibin Pan wrote:
The sender parameter contains the information about the instance of the textBox. If the member function is called without the instance of each textbox, it will cause the problem when multiple TextBox in the same form.

On the contrary, when you use the OnKeyPress method the control class works like any other; non-static method calls on it are for the current instance of the object (ie the this reference holds the current instance).

When you override an event in the base class you are placing your code at the top of the execution chain for the event. When you attach an event handler your code doesn't get called until the particular On* method fires the event (usually it starts at the class then proceeds down to the base class where the event is fired).

Read the documentation for OnKeyPress and you'll see the global recommendation of overriding the event method (if possible) instead of attaching a separate event handler.

James
"Java is free - and worth every penny." - Christian Graus
GeneralDate formats.. Pin
Ray Hayes12-Jul-02 6:55
Ray Hayes12-Jul-02 6:55 
QuestionHow to deal with the customers' pasting text behavior Pin
18-Mar-02 18:57
suss18-Mar-02 18:57 
AnswerRe: How to deal with the customers' pasting text behavior Pin
vinny26-Jun-02 14:04
vinny26-Jun-02 14:04 
GeneralRe: How to deal with the customers' pasting text behavior Pin
Anonymous12-Jul-02 6:50
Anonymous12-Jul-02 6:50 
GeneralSuggestion: Custom Validation Pin
James T. Johnson15-Mar-02 18:46
James T. Johnson15-Mar-02 18:46 
QuestionTIME mask? hh:mm:ss? Pin
21-Feb-02 10:21
suss21-Feb-02 10:21 
AnswerRe: TIME mask? hh:mm:ss? Pin
Harald Rafetseder11-Jul-02 20:48
Harald Rafetseder11-Jul-02 20:48 
GeneralLeap year Pin
TigerNinja_3-Feb-02 16:22
TigerNinja_3-Feb-02 16:22 
QuestionTest Harness? Pin
Odis Wooten30-Dec-01 23:31
Odis Wooten30-Dec-01 23:31 
AnswerRe: Test Harness? Pin
31-Dec-01 9:23
suss31-Dec-01 9:23 
GeneralNice work! One suggestion Pin
5-Nov-01 11:37
suss5-Nov-01 11:37 
GeneralRe: Nice work! One suggestion Pin
16-Dec-01 2:32
suss16-Dec-01 2:32 
GeneralLink broken Pin
Matthew Adams4-Nov-01 23:45
professionalMatthew Adams4-Nov-01 23:45 

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.