强制 TextBox 接受小数
Posted
技术标签:
【中文标题】强制 TextBox 接受小数【英文标题】:Force TextBox to accept decimal 【发布时间】:2012-07-06 14:52:37 【问题描述】:简而言之我的问题:
我有一个 WPF 文本框,应该只允许用户输入十进制数字。我的 TextBox 的 PreviewTextInput 事件处理程序中有我的验证逻辑。
我试过了:
使用 TryParse
double number = 0;
bool isSuccessful = double.TryParse(e.Text, out number);
e.Handled = !(number >= 0 && isSuccessful);
使用正则表达式: (as per Justin Morgan's response to this question)
string validNumberFormat = @"^[-+]?(\d1,3((,\d3)*(\.\d+)?|([.\s]\d3)*(,\d+)?)|\d+([,\.]\d+)?)$";
e.Handled = Regex.Matches(e.Text, validNumberFormat).Count < 1;
以上两种方法都只允许我输入数字,不能输入一个小数点。
欢迎提出任何建议。
【问题讨论】:
必须用逗号代替点吗?也许它可以与逗号 (,) 一起使用,因此您可以在之前进行替换以使其正常工作。 实际上一个小数点不是有效数字 【参考方案1】:使用行为(Blend SDK System.Windows.Interactivity)而不是直接处理 PreviewTextInput。我这样做是因为可重用性,而且您还应该知道,TextInput 没有处理空间,也没有处理粘贴。顺便说一句,关于您的“小数点”问题,我认为 Jonathan 和 Felice Pollano 是对的。
public class TextBoxInputBehavior : Behavior<TextBox>
public TextBoxInputMode InputMode get; set;
public TextBoxInputBehavior()
this.InputMode = TextBoxInputMode.None;
protected override void OnAttached()
base.OnAttached();
AssociatedObject.PreviewTextInput += AssociatedObjectPreviewTextInput;
AssociatedObject.PreviewKeyDown += AssociatedObjectPreviewKeyDown;
DataObject.AddPastingHandler(AssociatedObject, Pasting);
protected override void OnDetaching()
base.OnDetaching();
AssociatedObject.PreviewTextInput -= AssociatedObjectPreviewTextInput;
AssociatedObject.PreviewKeyDown -= AssociatedObjectPreviewKeyDown;
DataObject.RemovePastingHandler(AssociatedObject, Pasting);
private void Pasting(object sender, DataObjectPastingEventArgs e)
if (e.DataObject.GetDataPresent(typeof(string)))
var pastedText = (string)e.DataObject.GetData(typeof(string));
if(!this.IsValidInput(this.GetText(pastedText)))
System.Media.SystemSounds.Beep.Play();
e.CancelCommand();
else
System.Media.SystemSounds.Beep.Play();
e.CancelCommand();
private void AssociatedObjectPreviewKeyDown(object sender, KeyEventArgs e)
if (e.Key == Key.Space)
if (!this.IsValidInput(this.GetText(" ")))
System.Media.SystemSounds.Beep.Play();
e.Handled = true;
private void AssociatedObjectPreviewTextInput(object sender, TextCompositionEventArgs e)
if (!this.IsValidInput(this.GetText(e.Text)))
System.Media.SystemSounds.Beep.Play();
e.Handled = true;
private string GetText(string input)
var txt = this.AssociatedObject;
var realtext = txt.Text.Remove(txt.SelectionStart, txt.SelectionLength);
var newtext = realtext.Insert(txt.CaretIndex, input);
return newtext;
private bool IsValidInput(string input)
switch (InputMode)
case TextBoxInputMode.None:
return true;
case TextBoxInputMode.DigitInput:
return input.CheckIsDigit();
case TextBoxInputMode.DecimalInput:
//minus einmal am anfang zulässig
if (input == "-")
return true;
decimal d;
return decimal.TryParse(input, out d);
default: throw new ArgumentException("Unknown TextBoxInputMode");
return true;
public enum TextBoxInputMode
None,
DecimalInput,
DigitInput
使用
<TextBox>
<i:Interaction.Behaviors>
<MyBehaviors:TextBoxInputBehavior InputMode="DecimalInput"/>
</i:Interaction.Behaviors>
</TextBox>
【讨论】:
我尝试了您的解决方案,但我仍然遇到“小数点问题”。 我的错误,我忘记在 PreviewTextInput 处理程序中将 e.Text 传递给 GetText。现在一切正常。谢谢。【参考方案2】:您可以使用以下免费控件。这将使您的工作轻松简单 http://wpftoolkit.codeplex.com/wikipage?title=DecimalUpDown&referringTitle=Home
http://wpftoolkit.codeplex.com/wikipage?title=DoubleUpDown&referringTitle=Home
【讨论】:
以上是关于强制 TextBox 接受小数的主要内容,如果未能解决你的问题,请参考以下文章