简体   繁体   English

在 C# 中对 TextBox 实施输入限制的最佳方法是什么?

[英]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?TextBox控件(或 .NET 3.5 标准的其他任何东西)的输入限制为浮点数的最优雅的方法是什么?

Currently, I'm doing all the heavy lifting myself by inheriting from TextBox and overriding OnKeyPress .目前,我正在通过从TextBox继承并覆盖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:如果您沿着建议的路线走 go,请不要忘记以下问题/极端情况:

  • 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用户可以使用Ctrl - VShift - Insert将“无效”值粘贴到其中(第二个有点难以捕捉)......但用户可能应该被允许将合法值粘贴到控件中
  • 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)即使您尝试通过为文本框提供自己的上下文菜单来解决上一个问题,用户也可以在您的控件之外右键单击,按住右键,拖动您的文本框并让 go 访问默认的上下文菜单(并粘贴无效值)
  • 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)无论您做什么键处理都不应该禁用诸如Alt - F4等键组合(是的,如果您为所有不是有效数字的内容设置SuppressKeyPress ,您将打破这一点)
  • Users should probably be able to enter partial values (eg "-." , as they begin to type "-.23" ) without your textbox punishing them用户应该能够输入部分值(例如"-." ,因为他们开始输入"-.23" )而您的文本框不会惩罚他们
  • Numbers like "-.1e-2" could be considered legal"-.1e-2"这样的数字可以被认为是合法的
  • A user could feasibly enter a value which contains only digits, but which would overflow a float用户可以输入一个仅包含数字但会溢出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)TextChanged事件中进行基本验证(并做一些被动的事情,比如更改文本框背景颜色)
  • 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使用系统库为你Parse用户的价值

Take a look at the MaskedTextBox control.看一下MaskedTextBox控件。 It also inherits from TextBoxBase and probably has the functionality you're building into yours.它还继承自 TextBoxBase 并且可能具有您正在构建的功能。

What about using a NumericUpDown?使用 NumericUpDown 怎么样?

I don't think the wheel's been invented yet (at least in the .NET framework).我认为轮子还没有被发明出来(至少在 .NET 框架中)。 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.我敢肯定 CodeProject 或类似的东西有一些东西,做的和你一样,所以它可能值得谷歌。

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;过于简化的示例是您可以处理OnKeyPress ,执行Float.TryParse并附加新字符。如果为真,请保持按键; if false, cancel it ( e.Handled = true ).如果为假,则取消它( 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:我发现了一个 maskedTextBox 的 ValidatingType 属性:

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.如果是后者,您还可以使用ErrorProvider控件来帮助限制功能,直到输入被解析。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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