Click here to Skip to main content
15,890,438 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I am trying to validate a textbox in windows form to accept user input in certain format
I need user input as first 3 digits as number 405 & 505 followed by year ranging 1950-current year, followed by six digit unique identifier.

I need to validate textbox with leave event, such that it verifies user input matches the format on tab button click, mouse click to other field.

Textbox is 13 digit.

private void txtsfn_Leave(object sender,EventArgs e)
{
// need help with this part
}

Any suggestions and help is appreciated.
Posted
Updated 6-Nov-15 8:19am
v2
Comments
ZurdoDev 6-Nov-15 14:40pm    
You could easily parse the string and check to make sure it matches, or you can use RegEx. There are online tools to help you build a regex statement.
Member 12076824 6-Nov-15 15:04pm    
Thanks for response, I am not expert with regex and had been trying to avoid using regex. It gets somewhat complicated in my case.
ZurdoDev 6-Nov-15 15:08pm    
In that case use SubString() to make sure each section is what you expect.
BillWoodruff 6-Nov-15 14:54pm    
Read the documentation on the Masked TextBox.
ZurdoDev 6-Nov-15 15:09pm    
Masking won't actually give the OP what they need. For example, it won't ensure a year is entered in digits 4-7.

If you want to use a MaskedTextBox:
C#
// the character here should be whatever you set
// as the PromptChar property of the MaskedTextBox
private char[] splitchar = new char[1] {'-'};
private string[] fields;

private void resetMTB()
{
    // for debugging only
    Console.WriteLine("bad input: ", maskedTextBox1.Text);

    maskedTextBox1.Clear();
    maskedTextBox1.Focus();
    maskedTextBox1.Capture = true;
}

private void maskedTextBox1_Leave(object sender, EventArgs e)
{
    if(maskedTextBox1.Text.Length != 15)
    {
        resetMTB();
        return;
    }

    fields = maskedTextBox1.Text.Split(splitchar);

    int field1;

    if (fields.Length == 3)
    {
        if (fields[0].Length == 3
            && fields[1].Length == 4
            && fields[2].Length == 6)
        {
            if (Int32.TryParse(fields[1], out field1))
            {
                if (field1 >= 1950 && field1 <= DateTime.Now.Year) return;
            }
        }
    }

    resetMTB();
}
Note: this code was written quickly, and tested with only a small range of inputs; be sure and test thoroughly before you use this in "production" code.
 
Share this answer
 
Comments
George Jonsson 6-Nov-15 18:34pm    
The length of the string is supposed to be 13.
BillWoodruff 6-Nov-15 19:57pm    
Hi George, when you use a MaskedTextBox, the Prompt Character is inserted between fields: in this case there are two places where the Prompt is inserted resulting in a string length of #15 when you read out the Text in the MaskedTextBox. Checking for length == #15 first eliminates the case where the user has not filled in every field with the expected number of characters.
George Jonsson 6-Nov-15 20:00pm    
Ah OK. I have to admit I have only used that component once or twice.
One learn something new every day.
Thanks Bill.
Member 12076824 7-Nov-15 14:04pm    
Thanks Geoge, I tested this worked fine.
This is pretty easy to do with a regular expression.
To learn about that you can use this site as a starting point: Regular Expression Info[^]

And why not use the Validating event[^] for the text box? It is kind of made for this purpose. And it will trigger when the focus leaves the control.

Make sure to add
C#
using System.Text.RegularExpressions;

also add this as a member of your class
C#
private static Regex exprNumber = new Regex("^(405|505)(19[5-9][0-9]|[2-9][0-9]{3})[0-9]{6}$");

* The ^ anchor will make sure that you start the evaluation at the start of the string
* (405|505) means either 405 or 505
* 19[5-9][0-9] means 19 followed by a digit >=5 followed by 1 digit in the range of 0-9.
* 2[0-9]{3} means 2 - 9 followed by 3 digits in the range of 0-9. 2000 - 9999
* (19[5-9][0-9]|2[0-9]{3}) means either a number between 1950-1999 or between 2000-9999
* [0-9]{6} means exactly 6 digits in the range 0-9
* The $ anchor means that no extra characters can be matched.
* The total number of allowed characters is 13
Note: [0-9] can be replaced by \d, which is shorter but can be more difficult to read

In the event you can do something like this
C#
private void txtsfn_Validating(object sender, CancelEventArgs e)
{
    if (!exprNumber.IsMatch(txtsfn.Text))
    {
        // Show an error message or something
        e.Cancel = true;    // Prevents the user from leaving the form
        txtsfn.Focus();     // Set focus to the control that should be edited
    }
}


[UPDATE]
I don't know a way to check for current year in pure regular expression, but you can do it with some extra coding.
(Maybe there is a way to do it in regex only, but in that case you better ask separate question)

First change the expression a bit
C#
private static Regex exprNumber = new Regex("^(405|505)(?<year>19[5-9][0-9]|[2-9][0-9]{3})[0-9]{6}$");

(?<year>19...) represents a named group that makes it easy to extract the year part later

Then change your validation code a little:
C#
private void txtsfn_Validating(object sender, CancelEventArgs e)
{
    Match m = exprNumber.Match(txtsfn.Text);
    int testedYear = 0;

    // m.Groups["year"].Value will contain the year upon success
    // and be empty if the match fails
    int.TryParse(m.Groups["year"].Value, out testedYear);

    int currentYear = DateTime.Now.Year;
    
    if (!m.Success || testedYear > currentYear)    
    {
        // Show an error message or something
        e.Cancel = true;    // Prevents the user from leaving the form
        txtsfn.Focus();     // Set focus to the control that should be edited
    }
}
 
Share this answer
 
v4
Comments
Member 12076824 6-Nov-15 20:11pm    
Thanks for response I will try this.
Member 12076824 9-Nov-15 17:06pm    
Hi George,

Thanks for all your help. I was wondering is there way to restrict year to current year in regular expression and need not make changes to code for next year?
George Jonsson 9-Nov-15 20:39pm    
I don't know a way to do it in pure regular expression, but I updated my solution with some extra code that takes care of that problem.
Member 12076824 10-Nov-15 11:26am    
Thanks for all your help.
George Jonsson 10-Nov-15 17:34pm    
Your welcome.

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900