【问题标题】:Validate decimal numbers in a WPF TextBox验证 WPF 文本框中的十进制数字
【发布时间】:2013-08-01 09:48:26
【问题描述】:

我想在 WPF 文本框上实现十进制数字验证。

我找到了WPF TextBox validation on numeric values 的答案,但我想要一个允许十进制值(浮点/双精度)的文本框。

我该怎么做?

public static bool GetIsDecimal(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsDecimalProperty);
    }

    public static void SetIsDecimal(DependencyObject obj, bool value)
    {
        obj.SetValue(IsDecimalProperty, value);
    }

    public static readonly DependencyProperty IsDecimalProperty =
 DependencyProperty.RegisterAttached("IsDecimal", typeof(bool), typeof(TextBoxHelpers), new PropertyMetadata(false, new PropertyChangedCallback((s, e) =>
 {
     TextBox targetTextbox = s as TextBox;
     if (targetTextbox != null)
     {
         if ((bool)e.OldValue && !((bool)e.NewValue))
         {
             targetTextbox.PreviewTextInput -= targetTextbox_PreviewTextInput;

         }
         if ((bool)e.NewValue)
         {
             targetTextbox.PreviewTextInput += targetTextbox_PreviewTextInput;
             targetTextbox.PreviewKeyDown += targetTextbox_PreviewKeyDown;
         }
     }
 })));

    static void targetTextbox_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        e.Handled = (e.Key == Key.Space);
    }

    static void targetTextbox_PreviewTextInput(object sender, TextCompositionEventArgs e)
    {
        Char newChar = e.Text.ToString()[0];
        e.Handled = !(Char.IsNumber(newChar) || (newChar == '.'));
    }
}

我正在使用上面的代码。代码(Char.IsNumber(newChar) || (newChar == '.')) 将检查数字和小数。所以现在 TextBox 只允许数字和小数(。)。但问题是,我可以输入多个小数点(例如,1.01.22.011)。所以我想限制输入多个小数点。

【问题讨论】:

  • 您应该能够对the question you linkedthis other one 的答案中给出的代码进行一些简单的修改。你试过什么吗?请edit您的问题包括您正在使用的代码,以及哪些部分不起作用。

标签: c# .net wpf validation textbox


【解决方案1】:

你可以使用一种行为

    <TextBox MaxLength="17" MinWidth="205" HorizontalContentAlignment="Right"
             Text="{Binding Path=Amount, Mode=TwoWay, UpdateSourceTrigger=LostFocus, ValidatesOnExceptions=true,  ValidatesOnDataErrors=true, NotifyOnValidationError=True,
                             TargetNullValue={x:Static System:String.Empty},
                             Converter={StaticResource MyStringToDecimalConverter},ConverterParameter=#\,##0.00}">            
        <i:Interaction.Behaviors>                
            <Behaviors:TextBoxInputBehavior InputMode="DecimalInput" JustPositivDecimalInput="false"//>
        </i:Interaction.Behaviors>
    </TextBox>

behavior.cs:

public class TextBoxInputBehavior : Behavior<TextBox>
{
    const NumberStyles validNumberStyles = NumberStyles.AllowDecimalPoint |
                                               NumberStyles.AllowThousands |
                                               NumberStyles.AllowLeadingSign;
    public TextBoxInputBehavior()
    {
        this.InputMode = TextBoxInputMode.None;
        this.JustPositivDecimalInput = false;
    }

    public TextBoxInputMode InputMode { get; set; }


    public static readonly DependencyProperty JustPositivDecimalInputProperty =
     DependencyProperty.Register("JustPositivDecimalInput", typeof(bool),
     typeof(TextBoxInputBehavior), new FrameworkPropertyMetadata(false));

    public bool JustPositivDecimalInput
    {
        get { return (bool)GetValue(JustPositivDecimalInputProperty); }
        set { SetValue(JustPositivDecimalInputProperty, value); }
    }

    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 CheckIsDigit(input);

            case TextBoxInputMode.DecimalInput:
                decimal d;
                //wen mehr als ein Komma
                if (input.ToCharArray().Where(x => x == ',').Count() > 1)
                    return false;

                if (input.Contains("-"))
                {
                    //minus einmal am anfang zulässig
                    if (!this.JustPositivDecimalInput && input.IndexOf("-") == 0  && input.Length == 1)
                        return true;
                    else
                    {
                        var result = decimal.TryParse(input, validNumberStyles, CultureInfo.CurrentCulture, out d);
                        return result;
                    }
                }
                else
                {
                    var result = decimal.TryParse(input, validNumberStyles, CultureInfo.CurrentCulture, out d);
                    return result;
                }


            default: throw new ArgumentException("Unknown TextBoxInputMode");

        }
        return true;
    }

    private bool CheckIsDigit(string wert)
    {
        return wert.ToCharArray().All(Char.IsDigit);
    }
}

public enum TextBoxInputMode
{
    None,
    DecimalInput,
    DigitInput
}

【讨论】:

    【解决方案2】:
    <TextBox  Height="36"   PreviewTextInput="NumericTextBoxInput"   Width="235"/>
    

    C# 代码:

     void NumericTextBoxInput(object sender, TextCompositionEventArgs e)
        {
            var regex = new Regex(@"^[0-9]*(?:\.[0-9]*)?$");
            if (regex.IsMatch(e.Text) && !(e.Text == "." && ((TextBox)sender).Text.Contains(e.Text)))
                   e.Handled = false;
    
            else
                e.Handled = true;
        }
    

    【讨论】:

      【解决方案3】:
      <TextBox  Height="36"   PreviewTextInput="NumberDecimalValidationTextbox"   Width="235"/>
      
      
        private void NumberDecimalValidationTextbox(object sender, TextCompositionEventArgs e)
              {
                  var regex = new Regex(@"^[0-9]*(?:\.[0-9]*)?$");
                  if (regex.IsMatch(e.Text) && !(e.Text == "." && ((TextBox)sender).Text.Contains(e.Text)))
                      e.Handled = false;
      
                  else
                      e.Handled = true;
      
              }
      

      【讨论】:

        【解决方案4】:

        我设法使用“。”验证文本框中的浮点输入。与

        void NumericTextBoxInput(object sender, TextCompositionEventArgs e)
            {
                var regex = new Regex(@"^[0-9]*(?:\.[0-9]*)?$");
                if (regex.IsMatch(e.Text) && !(e.Text == "." && ((TextBox)sender).Text.Contains(e.Text)))
                       e.Handled = false;
        
                else
                    e.Handled = true;
            }
        

        现在我尝试做同样的事情,包括一个“,”作为十进制标记。以下正则表达式是可以的,但我不能只允许一个“。”或一个“,”。

        var regex = new Regex(@"^[0-9]*(?:(\.|\,)[0-9]*)?$");
        

        有人知道如何只允许“,”或“。”出现一次吗? 非常感谢

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-12-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-01-30
          • 1970-01-01
          • 2016-09-22
          • 1970-01-01
          相关资源
          最近更新 更多