Link to home
Start Free TrialLog in
Avatar of a_anis3000
a_anis3000Flag for Egypt

asked on

Create a WPF TextBox that accepts numbers only

The following C# code is a handler that make sure that a Windows Form TextBox accepts numbers only including decimal point (one only). I want to do the same for a WPF TextBox, unfortunately there is no KeyPress event.
//Allow only numeric input from keyboard and prevent user from typing
 //a decimal point (.) more than once 
        private void resultTextBox_KeyPress(object sender, KeyPressEventArgs e)
        {
            const char Delete = (char)8;            
            if (Char.IsDigit(e.KeyChar))
                e.Handled = false;
            else if (e.KeyChar == Delete)
                e.Handled = false;
            else if (e.KeyChar == '.')
            {
                if (!(resultTextBox.Text.Contains(".")))
                    e.Handled = false;
                else
                {
                    e.Handled = true;
                    SystemSounds.Beep.Play();
                }
 
            }
            else
            {
                e.Handled = true;
                SystemSounds.Beep.Play();
            }

Open in new window

SOLUTION
Avatar of chinu1310
chinu1310
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of a_anis3000

ASKER

The first code is too complex for me to understand, but the second one is more manageable. But has one problem it doesn't allow decimal points to be inserted so I modified the code as following (see code snippet)

It nows allow decimal point, and everything is almost perfect, the only problem now is that it allows more than one decimal point. I have been racking my brain for several hours over solving that little matter but to no success. Any suggestion will be greatly appreciated

 

 private void textBox1_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
 
            e.Handled = !AreAllValidNumericChars(e.Text);            
        }
 
 private bool AreAllValidNumericChars(string str)
        {
            foreach (char c in str)
            {
                if (c != '.')
                {
                    if (!Char.IsNumber(c))
                        return false;
                }
 
            }
 
            return true;
        }

Open in new window

ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I just downloaded and compiled the code and ran it, the program is great the textbox in the program behave in the desired manner allowing only one decimal point and the interface looks pretty fancy. Alas the code is too complicated for me to understand, I am still in the early stages of learning C# along with WPF so my background is not sufficient for me to understand the code.

On the other hand I managed to solve the problem in my own approach. I modified the code above to look as following (see code snippet below). Probably its not the neatest manner of coding but this is the best I could do with my current skill, if someone has a better suggestion (in simple code) you are welcome to share

private void textBox1_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            e.Handled = !AreAllValidNumericChars(e.Text);
        }
 
 
        int numberOfDecimals = 0;
        private bool AreAllValidNumericChars(string str)
        {
            
            foreach (char c in str)
            {
                if (c != '.')
                {
                    if (!Char.IsNumber(c))
                        return false;
                }
                else
                {
                    numberOfDecimals++;
                    if (numberOfDecimals > 1)
                        return false;
                    
                }
            }
 
            return true;
 
            numberOfDecimals = 0;
        }

Open in new window

Wow, I tried doing something like this but then though it will not be a good solution so I searched for this Mast TextBox and replied with new link.

I won't say it is a bad idea or not neat solution. This is near to perfect.
I mean :-> "Mask TextBox" not "Mast TextBox"
I forgot to mention there is a tiny bug in it that the text box accepts a decimal point only once including even after it is deleted. For example if I type 4.5 and try to enter another decimal it won't work and that is the desired behavior, however suppose I deleted the number and want to change it to 3.5 it wouldn't let me type any decimal number anymore even though it has been deleted until the program is restarted. I couldn't fix it so far so any suggestion how to correct this glitch will be appreciated its only one small step to go and I am done

Thanks again in advance
else
                {
                    numberOfDecimals++;
                    if (numberOfDecimals > 1)
                      {
                        numberOfDecimals = 0;
                        return false;
                      }
                   
                }

Can you try changing you code like this and see if that helps, if it doesn't work will create sample app. on this machine as well. The one I made is not on this machine.
This is what I tried already. It doesn't work as the text box allows more than one decimal point to be typed in.