0

My problem in a nutshell:

I have a WPF TextBox where a user should only be allowed to enter decimal numbers. I have my validation logic in my TextBox's PreviewTextInput event handler.

So fare I have tried:

Using TryParse

double number = 0; bool isSuccessful = double.TryParse(e.Text, out number); e.Handled = !(number >= 0 && isSuccessful); 

Using a Regex: (as per Justin Morgan's response to this question)

string validNumberFormat = @"^[-+]?(\d{1,3}((,\d{3})*(\.\d+)?|([.\s]\d{3})*(,\d+)?)|\d+([,\.]\d+)?)$"; e.Handled = Regex.Matches(e.Text, validNumberFormat).Count < 1; 

Both of the above methods will only allow me to enter numbers, but not the single decimal point.

Any suggestions would be most welcome.

2
  • Have to tried with a comma instead of a dot? Maybe it works with a comma (,) so you can do a replace before to get it work. Commented Jul 6, 2012 at 6:59
  • actually a single decimal point is not a valid number Commented Jul 6, 2012 at 7:05

2 Answers 2

2

is use a behavior(Blend SDK System.Windows.Interactivity) instead of handling PreviewTextInput directly. i do this because of reusability and also you should know that the space is not handled with TextInput and also Pasting is not handled. btw i think Jonathan and Felice Pollano are right, regarding to your "decimal point" problem.

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 } 

using

 <TextBox> <i:Interaction.Behaviors> <MyBehaviors:TextBoxInputBehavior InputMode="DecimalInput"/> </i:Interaction.Behaviors> </TextBox> 
Sign up to request clarification or add additional context in comments.

2 Comments

I tried your solution, but I'm still getting the "decimal point problem".
My mistake, I forgot to pass e.Text to GetText in the PreviewTextInput handler. Everything works perfectly now. Thanks.
0

You can make use of the below free controls. This will make your work easy and simple http://wpftoolkit.codeplex.com/wikipage?title=DecimalUpDown&referringTitle=Home

http://wpftoolkit.codeplex.com/wikipage?title=DoubleUpDown&referringTitle=Home

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.