本文参考了一个只接受正数的文章,可惜我再查不到那篇的地址了。
我不知道是不是就是这个:www.wpfsharp.com/tag/digitbox/,但是我怎么也打不开这个地址。
然后我本来是以为WPF中会有那种上下箭头按按的TextBox然后只接受数字(类似的控件在Qt里面应该有),不过没搜到然后搜到了我上面提到的那篇文章。
一个简单的思想就是对TextBox的文本进行处理,只留下数字以及第一个小数点
private string LeaveOnlyNumbers(String inString) { occur = false; StringBuilder ans = new StringBuilder(); for (int i = 0; i < inString.Length; ++i) { if (System.Text.RegularExpressions.Regex.IsMatch(inString[i].ToString(), "^[0-9\\.]*$")) { if (inString[i] == '.') { if (!occur) { occur = true; ans.Append(inString[i]); } } else ans.Append(inString[i]); } } return ans.ToString(); }
上面代码中的occur是一个全局变量,记录是否已经有小数点出现过。
然后重定义TextBox.Text
new public String Text { get { return base.Text; } set { base.Text = LeaveOnlyNumbers(value); } }
并监听TextChanged
public DigitBox() { TextChanged += new TextChangedEventHandler(OnTextChanged); KeyDown += new KeyEventHandler(OnKeyDown); } protected void OnTextChanged(object sender, TextChangedEventArgs e) { base.Text = LeaveOnlyNumbers(Text); }
因为TextBox只接受数字和第一个小数点,所以未处理的键盘输入应该不在这层处理,继续按事件流传送,所以我们需要重载KeyDown。值得注意的是,小数点只有在第一次出现的时候才处理,之后出现也应当不处理,所以这里也用到了occur。否则这个TextBox用起来会有一点很不爽,即在出现第二次小数点的时候,TextBox处理了这个事件,但是又得不到显示,于是光标就会移到最前面。
protected void OnKeyDown(object sender, KeyEventArgs e) { e.Handled = !IsNumberKeyOrDot(e.Key) && !IsDelOrBackspaceOrTabKey(e.Key); } private bool IsNumberKeyOrDot(Key inKey) { if (!occur) { if (inKey == Key.Decimal) return true; if (inKey == Key.OemPeriod) return true; } if (inKey < Key.D0 || inKey > Key.D9) { if (inKey < Key.NumPad0 || inKey > Key.NumPad9) { return false; } } return true; } private bool IsDelOrBackspaceOrTabKey(Key inKey) { return inKey == Key.Delete || inKey == Key.Back || inKey == Key.Tab; }
因为需求的原因,这个TextBox只接受正的小数,并不接受负数,其实扩展起来也相当容易,只用判断第一个是不是负号或者正号就可以了,之后的正负号输入全都不处理。