在C#中实现文本框输入限制的最佳方法是什么?

在C#中实现文本框输入限制的最佳方法是什么?,c#,winforms,C#,Winforms,将文本框控件(或.NET 3.5标准附带的任何其他控件)的输入限制为浮点数的最优雅的方式是什么 目前,我通过继承TextBox并覆盖OnKeyPress来完成所有繁重的工作。然而,我不禁想知道我是否在重新发明轮子。看看控制。它还继承了TextBoxBase,可能具有您正在构建的功能 我认为轮子还没有发明出来(至少在.NET框架中是这样)。我相信CodeProject或类似的网站上也有类似的东西,做着与你相似的事情,所以它可能值得谷歌一试 不过,负重不应该太糟糕。这比乍一看要复杂得多 过于简化的示

文本框
控件(或.NET 3.5标准附带的任何其他控件)的输入限制为浮点数的最优雅的方式是什么


目前,我通过继承
TextBox
并覆盖
OnKeyPress
来完成所有繁重的工作。然而,我不禁想知道我是否在重新发明轮子。

看看控制。它还继承了TextBoxBase,可能具有您正在构建的功能

我认为轮子还没有发明出来(至少在.NET框架中是这样)。我相信CodeProject或类似的网站上也有类似的东西,做着与你相似的事情,所以它可能值得谷歌一试

不过,负重不应该太糟糕。这比乍一看要复杂得多

过于简化的示例是,您可以在键盘上处理
OnKeyPress
,执行
Float.TryParse
,并添加新字符。如果为真,则保持按键;如果为false,则取消它(
e.Handled=true


最难的部分是,如果他们删除、剪切或粘贴一个选择,会发生什么。另一件事是当它们刚开始时(您可能希望接受“-”作为部分有效输入)..

或使用

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


使用数字向上向下怎么样?

不要忘记,如果您沿着建议的路线走,您将面临以下问题/困境:

  • 用户可以使用Ctrl-V或Shift Insert将“无效”值粘贴到中(第二个值更难捕捉)。。。但是应该允许用户将合法值粘贴到控件中
  • 用户可以使用默认上下文菜单在中单击鼠标右键,粘贴无效值
  • 即使您试图通过为文本框提供自己的上下文菜单来修复以前的问题,用户也可以在您的控制之外右键单击,按住右键,拖动文本框,然后放开以访问默认上下文菜单(并粘贴无效值)
  • 无论您执行何种按键处理,都不应禁用Alt-F4等组合键(是的,如果您为所有无效数字设置
    SuppressKeyPress
    ,则会破坏此功能)
  • 用户应该能够输入部分值(例如,当他们开始键入
    “-.23”
    )时,您的文本框不会惩罚他们
  • “-.1e-2”
    这样的数字可以被认为是合法的
  • 用户可以输入一个仅包含数字的值,但该值会溢出
    浮点值
  • 最糟糕的一个:你的用户在你发货后会发现的一些神秘的角落案例(!!)
道德?按照你的建议去做可能会很棘手

您可能需要执行以下操作的组合:

  • 使用一个知道所有角落案例的人创建的控件(如microsoft)
  • TextChanged
    事件中执行基本验证(并执行一些被动操作,如更改文本框背景颜色)
  • 保存验证,直到您实际尝试使用他们键入的值为止
  • 使用系统库为您解析用户的值

我发现了maskedTextBox的ValidatingType属性:

maskedTextBox1.ValidatingType = typeof(System.Double);

它确实告诉你它是否有效。不幸的是,它似乎只在焦点改变时才进行验证(即使这样,它实际上也没有做任何事情);但是也许有某种方法可以使用它。

是否有必要在数据输入期间进行验证,或者一旦焦点丢失,您是否可以检查输入的最终值


如果是后者,您还可以使用控件来帮助限制功能,直到输入得到解决。

谢谢您的快速响应,Mike。事实上,在使用人工之前,我确实研究过MaskedTextBox控件,但是,我无法让它像我想要的那样使用浮点数。也许我做了一些愚蠢的事情,但是…我不认为MaskedTextBox在这里可以做任何好事,因为它似乎不允许无限(用户定义)数量的字符。谢谢你的建议,但它不是那么简单。如果用户更改插入符号的位置怎么办?据我所知,你不能盲目追加。谢谢你的链接virualblackbox。我一定会看一看。这一点很好,但是你不能用SelectionStart和SelectionLength获得当前的选择吗?顺便说一句,我不认为只限制输入很好,复制粘贴案例本身就是一个问题,因为一些用户希望能够在输入开始时粘贴一个数字并(手动)删除旧文本使其有效…lc,我越是考虑你的建议,它就越有吸引力。。。问题是,当我在词汇上检查浮点数时,我不关心浮点数的顺序。因此,新添加字符的位置是不相关的。如果我没有遗漏任何东西,尝试解析应该可以工作。@ecarF:不是开玩笑;这就是为什么像OP所要求的那样真正构建一个健壮的输入控件是如此痛苦的原因。是的,等待用户完成他们正在做的事情(按OK),然后用正则表达式点击值,然后继续或抛出MessageBox。比覆盖OnKeyPress好多了。谢谢你的努力。;)@卡尔:MessageBox是邪恶的,应该死了。禁用ok并在某个保留区域或无效文本框周围提供原因对于较差的用户来说要容易得多。+1 VirtualBlackBox。我可能会闪现输入控件的背景并使用工具提示。谢谢,我想我应该解释得更好。我正在数据输入期间验证用户输入。您可以随时调用“ValidateText”方法。因此,要摆脱焦点更改限制,请为TextChanged设置一个处理程序,并说if(maskedTextBox1.MaskCompleted){maskedTextBox1.ValidateText();}
maskedTextBox1.ValidatingType = typeof(System.Double);