views:

682

answers:

1

I am trying to prevent a user from entering anything into a particular textbox aside from a number or a period in C#. The textbox is supposed to contain an IP address. I have it working such that non-numeric entries are prevented, however I can't seem to get it to allow a period to be entered. How might I accomplish this?

    private void TargetIP_KeyDown(object sender, KeyEventArgs e)
    {
        // Initialize the flag to false.
        nonNumberEntered = false;

        // Determine whether the keystroke is a number from the top of the keyboard.
        if (e.KeyCode < Keys.D0 || e.KeyCode > Keys.D9)
        {
            // Determine whether the keystroke is a number from the keypad.
            if (e.KeyCode < Keys.NumPad0 || e.KeyCode > Keys.NumPad9)
            {
                // Determine whether the keystroke is a backspace.
                if (e.KeyCode != Keys.Back)
                {
                    nonNumberEntered = true;
                    errorProvider1.SetError(TargetIP, FieldValidationNumbersOnly);
                    // A non-numerical keystroke was pressed.
                    // Set the flag to true and evaluate in KeyPress event.
                }
            }
        }

        //If shift key was pressed, it's not a number.
        if (Control.ModifierKeys == Keys.Shift)
        {
            nonNumberEntered = true;
        }
    }


    private void TargetIP_KeyPress(object sender, KeyPressEventArgs e)
    {
        // Check for the flag being set in the KeyDown event.
        if (nonNumberEntered == true)
        {
            // Stop the character from being entered into the control since it is non-numerical.
            e.Handled = true;
        } 

        else
        {
            errorProvider1.Clear();
        }
    }
+8  A: 

You should use a MaskedTextBox control instead of a normal TextBox control. Then just set the Mask property to 990\.990\.990\.990 and you are done.

  • 9 optional digit or space
  • 0 required digit
  • \. escaped dot

UPDATE

While I suggested using MaskedTextBox, I never (at leat I cannot remeber) used it myself. Now I just tried it ... well, forget what I said. I thought it might be a simple solution, but it is an unusable solution, too.

New, more complex, but far better suggestion and the way I usually do it.

  • Create a custom control with four text boxes, three labels with a dot each between them.

  • Analyse the input.

    • Just pass control keys to the control.
    • Move the focus if the user enters a dot, a tab (will be handled by the control), a space, may be a fourth digit.
    • Discard everything that is not a digit.
    • Discard the digit if the number falls out of the range from 0 to 255.
    • Change the text to 0 if the user deletes the last digit.
    • Remove a leading zero if the user enters a non-zero digit.
  • Add a property to the user control that returns the entered address.

  • May be make the proeprty writable and add event handling.

Daniel Brückner
Wow, thanks...now the way I was doing it seems silly. Are there any advantages to doing it the way I was with a regular textbox rather than what you recommended?
transmogrify
how about IPv6 addresses? I think that will get a bit more tricky.
Erich Mirabal
Yes! The MaskedTextBox is usability horror. I should have tried before suggesting that. It works, but ... it works. If you will have many IP address inputs, I really suggest taking the time to build a smart custom control.
Daniel Brückner
ah, this is true. good to know, thanks again!
transmogrify
well, it could be a dynamic swapping of the mask. If it fails on the IPv4 mask, switch to the IPv6 mask? just make sure you don't ping-pong between the masks, and that might work.
Erich Mirabal
Just as a small FYI, when you go to Network Connections, properties on a connection, properties on TCP/IP, the validation for everything but "Subnet mask" (e.g. "IP address" or "Default Gateway") is: (between 1 and 223).(between 0 and 255).(between 0 and 255).(between 0 and 255)
JustLooking