强制 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 接受小数的主要内容,如果未能解决你的问题,请参考以下文章

WPF TextBox 输入限制小数点后两位

c# 如何让textbox只能输入数字和小数

c#里面使textbox里面只能输入数字,或者小数点的代码

C# textbox只允许小数点后输入两位怎么实现?

WPF TextBox 正则验证 大于等于0 小于等于1 的两位小数

WPF强制设置TextBox的焦点