2013-08-01 45 views
-1

我想在WPF文本框上實現十進制數驗證。驗證WPF文本框中的十進制數

我找到了WPF TextBox validation on numeric values的答案,但我想要一個允許十進制值(float/double)的TextBox。

我該怎麼做?

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)。所以我想限制輸入多個小數點。

+1

你應該能夠做一些簡單的修改[您鏈接的問題]的答案中給出的代碼(http:// stackoverf low.com/questions/13251506/wpf-text-box-validation-on-numeric-value)和[this other one](http://stackoverflow.com/questions/5511/numeric-data-entry-in-wpf )。你有嘗試過什麼嗎?請[編輯]您的問題,以包含您正在使用的代碼以及哪些部分無法正常工作。 –

回答

2

可以使用行爲

<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 
} 
0
<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; 
    }