Vignesh
Vignesh

Reputation: 1518

How to restrict values in Winforms MaskedTextbox

My requirement is that the user will enter a time ("HH:mm:ss") in masked text box and based on that time i am doing some functionalities. My problem is i can mask the time but i can't restrict the user to enter up to 23 for hours,59 for minutes and 59 for seconds. How to fix this.

C# Code

private void Form1_Load(object sender, EventArgs e)
 {
    maskTxtAlert1.Mask = "00:00:00";
        maskTxtAlert1.CutCopyMaskFormat = MaskFormat.ExcludePromptAndLiterals;
 }

 private void maskTxtAlert1_MaskInputRejected(object sender, MaskInputRejectedEventArgs e)
 {
            if (e.Position == maskTxtAlert1.Mask.Length)
           {
               string errorMessage = "You cannot add extra characters";
               toolTip1.ToolTipTitle = "Input Rejected - No more inputs allowed";
               toolTip1.Show(errorMessage, maskTxtAlert1, 12, 24, 2000);
               errorProvider1.BlinkStyle = ErrorBlinkStyle.AlwaysBlink;
               errorProvider1.SetError(maskTxtAlert1, errorMessage);
           }
           else
           {
               toolTip1.ToolTipTitle = "Input Rejected";
               string errorMessage = "You can only add numeric characters (0-9).";
               toolTip1.Show(errorMessage, maskTxtAlert1, 12, 24, 2000);
               errorProvider1.BlinkStyle = ErrorBlinkStyle.AlwaysBlink;
               errorProvider1.SetError(maskTxtAlert1, errorMessage);
           }
   }

 private void maskTxtAlert1_TypeValidationCompleted(object sender, TypeValidationEventArgs e)
 {
           MessageBox.Show("Enter Valid as One");
 }

Upvotes: 4

Views: 6950

Answers (4)

KyleMit
KyleMit

Reputation: 30287

Using a DateTimePickerFormat with .CustomFormat = "HH:mm:ss" is probably the best out of the box approach, but can be restrictive in terms of UI interaction.

For people coming here looking for adding validation to a MaskedTextBox, there are several good options.

Type Validation

If you still want automatic parsing, you can can add a ValidatingType and tap into the TypeValidationCompleted Event like this:

Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
        MaskedTextBox1.Mask = "00:00"
        MaskedTextBox1.ValidatingType = GetType(DateTime)
End Sub

Private Sub MaskedTextBox1_TypeValidationCompleted(sender As Object, e As TypeValidationEventArgs) _
    Handles MaskedTextBox1.TypeValidationCompleted
    If Not e.IsValidInput Then
        Me.validationToolTip.ToolTipTitle = "Invalid Time"
        Me.validationToolTip.Show("The time you supplied must be a valid time in the format HH:mm", sender)
    End If
End Sub

ValidatingType will tap into the public static Object Parse(string) method for each type it's passed. You can even pass in your own custom classes as long as they implement this signature

Custom Validation:

To provide your own custom validation, you can tap into the Validating Event like this:

Private Sub MaskedTextBox1_Validating(sender As System.Object, e As System.ComponentModel.CancelEventArgs) _
    Handles MaskedTextBox1.Validating
    Dim senderAsMask = DirectCast(sender, MaskedTextBox)
    Dim value = senderAsMask.Text
    Dim parsable = Date.TryParse(value, New Date)

    If Not parsable Then
        e.Cancel = True
        Me.validationToolTip.ToolTipTitle = "Invalid Time"
        Me.validationToolTip.Show("The time you supplied must be a valid time in the format HH:mm", sender)
    End If
End Sub

In this case, the validation implementation is still rather naive, but you could implement whatever logic you want to determine validity.

Notes:
If the CausesValidation property is set to false, the Validating and Validated events are suppressed.
If the Cancel property of the CancelEventArgs is set to true in the Validating event delegate, all events that would usually occur after the Validating event are suppressed.

For Bonus Points, hide the tooltip when the user starts typing again:

Private Sub MaskedTextBox1_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs) _
    Handles MaskedTextBox1.KeyDown
    Me.validationToolTip.Hide(sender)
End Sub

Upvotes: 1

Mohammad abumazen
Mohammad abumazen

Reputation: 1286

I think its better to use DateTimePicker as tezzo said and no validation required

dateTimePicker1.Format = DateTimePickerFormat.Custom;
//For 24 H format
dateTimePicker1.CustomFormat = "HH:mm:ss";
//For 12 H format
dateTimePicker1.CustomFormat = "hh:mm:ss tt";
dateTimePicker1.ShowUpDown = true; 

Upvotes: 4

Chibueze Opata
Chibueze Opata

Reputation: 10044

The MaskedTextbox class is not built to handle this type of validation and you will have to do add some manual validation to the Validation Complete event.

e.g.

string[] timedetails = FormattedDate.Split(':');
int hours = Int32.Parse(timedetails[0].Trim());
int minutes = Int32.Parse(timedetails[1].Trim());
int seconds = Int32.Parse(timedetails[2].Trim());

if(hours > 23)
{
   //error message here, etc.
}

However, you may be much better off using a formatted DateTime control probably set to long time format. See full listing of formats on MSDN.

Upvotes: 0

No Idea For Name
No Idea For Name

Reputation: 11597

if you don't have to use maskedTextBox as tezzo said, but that might be less convenient. i would chose a simpler way: instead of poping a messageBox on TypeValidationCompleted you can change invalid user values. if the user wrote a value higher then 23 in hours for example, change it to 23

Upvotes: 0

Related Questions