简体   繁体   中英

What is the best way to implement input restrictions on a TextBox in C#?

What is the most elegant way of restricting the input of a TextBox control (or anything else that comes standard with .NET 3.5) to floating point numbers?

Currently, I'm doing all the heavy lifting myself by inheriting from TextBox and overriding OnKeyPress . However, I can't help but wonder if I'm reinventing the wheel.

Don't forget the following issues/corner-cases that you will be facing if you go down your proposed route:

  • Users can use Ctrl - V or Shift - Insert to paste "invalid" values in (That second one is a little trickier to catch)... but users probably should be allowed to paste legal values into the control
  • Users can right click, paste invalid values in using the default context-menu
  • Even if you've tried to fix the previous issue by giving the textbox its own context menu, users can right-click outside your control, hold down the right button, drag over your textbox and let go to access the default context-menu (and paste in invalid values)
  • Whatever key processing you do shouldn't disable key combinations like Alt - F4 , etc. (And yes, you will break this if you set SuppressKeyPress for everything that isn't a valid digit)
  • Users should probably be able to enter partial values (eg "-." , as they begin to type "-.23" ) without your textbox punishing them
  • Numbers like "-.1e-2" could be considered legal
  • A user could feasibly enter a value which contains only digits, but which would overflow a float
  • The worst one of all: Some other mysterious corner case that your users will find after you've shipped (!!)

The moral? It's can be very tricky to do what you're suggesting.

You probably either want to do a combination of the following:

  • Use a control that someone that knows all the corner cases built (like microsoft)
  • Do basic validation in the TextChanged event (and doing something passive, like changing the textbox background color)
  • Save the validation until you actually try to use the value they've typed in
  • Use the system libraries to Parse the user's value for you

Take a look at the MaskedTextBox control. It also inherits from TextBoxBase and probably has the functionality you're building into yours.

What about using a NumericUpDown?

I don't think the wheel's been invented yet (at least in the .NET framework). I'm sure there's something on CodeProject or the like, doing similar to what you are though, so it may be worth a Google.

The heavy lifting shouldn't be too incredibly bad though. There is a little bit more to it than at first glance.

The overly simplified example is you can handle OnKeyPress , do a Float.TryParse with the new character appended in. If true, keep the keypress; if false, cancel it ( e.Handled = true ).

The hard part is what if they delete, cut, or paste a selection. The other thing is when they're just starting out (you might want to accept "-" as partial valid input)...

Or check for match using

void TextBox_KeyUp(object sender, KeyEventArgs e)
{
  if(..) // your condition
  {
    e.SuppressKeyPress = false;
  }
  else
  {
    e.SuppressKeyPress = true;
  }
}

or

void TextBox_KeyUp(object sender, KeyEventArgs e)
{
   e.SuppressKeyPress = CheckInput(e.KeyValue); // where CheckInput is boolean method
}

I discovered the ValidatingType property of a maskedTextBox:

maskedTextBox1.ValidatingType = typeof(System.Double);

It does indeed tell you whether it's valid or not. Unfortunately, it only seems to validate when focus changes (and even then it doesn't actually do anything); but perhaps there's some way of using this.

Is it necessary to do the validation during data entry, or can you afford to check the final value entered once focus is lost?

If the latter, you can also use an ErrorProvider control to help restrict functionality until the input is resolved.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM