views:

40

answers:

2

I have a WPF application in which I have a hook at PreviewTextInput, through that I get the currently entered character and I have the string already entered. Given this I need to write the following function :

bool ShouldAccept(char newChar,string existingText)

existingText can be comma seperated valid numbers(including exponential) and it should just return false when invalid characters are pressed.

My code(if else based) currently has a lot of flaws, I wanted to know if there is any smart way to do it.

+2  A: 

I would recommend doing this in two cheks:

First check: find if new character is valid. You probably should accept only numbers, comma, dot, +- marks and letter e. Every other character should cause it return false

Second check: append new character to string, split it on commas using split method and for every separate string perform TryParse method from float/double. You probably should treat the last string from splitted elements differently, as the input can be still in progress (i.e. a string that will end with dot will not probably be parsed.

Just remember, that you will need to "tell" the parser, that dots and other characters are allowed and how they should be processed. For me, following settings work fine:

System.Globalization.CultureInfo info = new System.Globalization.CultureInfo("en-GB");
System.Globalization.NumberStyles styl = System.Globalization.NumberStyles.AllowDecimalPoint;
double.TryParse(someString, styl, info, out number);`

And one thing: If you can, change the separation mark from comma to semicolon. Comma in some cultures is used to indicate decimal point.

Gacek
I like you idea for a 2 pass parser, let me munch on it
Nitin Chaudhari
@Nitin: If you think it solved your problem, please accept the answer. If you have any other questions, feel free to ask, I will gladly help. Cheers.
Gacek
Sure, I will mark it as answer if I don't get anything better, I am trying out another approach.. will post more details once I have concrete implementation. I have already voted you since I liked your answer.
Nitin Chaudhari
A: 

I finally did it using Regex,

private readonly List<Regex> ValidNumberRegex = new List<Regex>
                                {
                                    new Regex(@"^-?$"),
                                    new Regex(@"^-?\d+$"),
                                    new Regex(@"^-?\d+\.$"),
                                    new Regex(@"^-?\d+\.\d+$"),
                                    new Regex(@"^-?\d+\.\d+[eE]$"),
                                    new Regex(@"^-?\d+\.\d+[eE]-?$"),
                                    new Regex(@"^-?\d+\.\d+[eE]-?\d+$"),
                                    new Regex(@"^-?\d+[eE]-?$"),
                                    new Regex(@"^-?\d+[eE]-?\d+$"),
                                };

So basically my ShouldAccept looks like this :

  1. If the input is the first character then only allow "-" or 0-9
  2. Else if input is "," then split existingText by "," and validate all existing numbers
  3. For all other input, figure out the current number (it can be an edit of existing number or continuation of last number), after figuring it out, validate the number with newchar

In all its just 50 lines of code. I could have combined all the regex but this is much easier to read.

Nitin Chaudhari