user3859356
user3859356

Reputation: 739

Restrict Textbox to 1 decimal place. Winform C#

I am developing a winform application using c# I have successfully implemented a way to restrict textbox to two decimal places. How can I do it to one decimal place. ?

My code for two decimal places.\

private void txtHraRep_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (char.IsNumber(e.KeyChar) || e.KeyChar == '.')
            {
                if (Regex.IsMatch(
                 txtHraRep.Text,
                 "^\\d*\\.\\d{2}$")) e.Handled = true;
            }
            else e.Handled = e.KeyChar != (char)Keys.Back;
        }

Changing to "^\d*\.\d{1}$")) e.Handled = true;

output

This is the output

Upvotes: 0

Views: 4014

Answers (5)

Elegiac
Elegiac

Reputation: 361

try:

List<string> doubleList = new List<string>(new string[]
        {
            "12345",
            "1234.5",
            "123.45",
            "12.345",
            "1.2345",
            "1.2",
            "1.23",
            "1.234",
            "1.23.45",
            "12.3",
            "123.4",
        }) { };

    private void button1_Click(object sender, EventArgs e)
    {
        foreach (var x in doubleList)
        {
            int countNumber = Regex.Matches(x, @"[0-9]").Count;
            int countOfDot = Regex.Matches(x, @"\.").Count;

            if (countOfDot == 1 && countNumber != 0) //contains "." and any digit
            {
                Console.WriteLine(x);
            }
            else if (countOfDot == 0 && countNumber != 0) //not contains "." and any digit
            {
                 Console.WriteLine(x);
            }
            else
            {
               //do nothing . . .
            }
        }
    }

output:

all except for **1.23.45** (2dots)

Upvotes: 0

Mehdi Haghshenas
Mehdi Haghshenas

Reputation: 2447

Create A new TextBox that inherit TextBox like

[DefaultBindingProperty("Text")]
[DefaultProperty("Text")]
[DefaultEvent("ValueChanged")]
public class SpecializedTextBox : TextBox
{
    private bool _allowNegativeSign = false;
    public bool AllowNegativeSign
    {
        get { return _allowNegativeSign; }
        set { _allowNegativeSign = value; }
    }
    public decimal? DecimalValue
    {
        get
        {
            decimal k;
            if (decimal.TryParse(this.Text, out k))
                return k;
            else
                return null;
        }
        set
        {
            if (value.HasValue)
                this.Text = value.Value.ToString();
            else
                this.Text = "";
        }
    }
    private void This_TextChanged(object sender, EventArgs e)
    {
        string s = base.Text;
        int cursorpos = base.SelectionStart;
        bool separatorfound = false;
            for (int i = 0; i < s.Length; )
            {
                if (char.IsNumber(s[i]))
                    i++;
                else if (AllowNegativeSign && i < System.Globalization.CultureInfo.CurrentUICulture.NumberFormat.NegativeSign.Length && s.StartsWith(System.Globalization.CultureInfo.CurrentUICulture.NumberFormat.NegativeSign))
                    i++;
                else if (!separatorfound && s[i].ToString() == System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator)
                {
                    separatorfound = true;
                    i++;
                }
                else
                {
                    s = s.Remove(i, 1);
                    if (i < cursorpos)
                        cursorpos--;
                }
            }
        if (base.Text != s)
        {
            base.Text = s;
            base.SelectionStart = cursorpos;
            base.SelectionLength = 0;
        }
        if (ValueChanged != null)
            ValueChanged(this, EventArgs.Empty);
    }
    public event EventHandler ValueChanged;

    private void InitializeComponent()
    {
        this.SuspendLayout();
        // 
        // SpecializedTextBox
        // 
        this.TextChanged += new System.EventHandler(this.This_TextChanged);
        this.ResumeLayout(false);
    }
    public SpecializedTextBox()
        : base()
    {
        InitializeComponent();
    }
}

now use this text box and use DecimalValue to set or get your value

Upvotes: 0

gottsche
gottsche

Reputation: 83

I just tried

private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
        {
            if (char.IsNumber(e.KeyChar) || e.KeyChar == '.')
            {
                if (Regex.IsMatch(
                 textBox1.Text,
                 "^\\d*\\.\\d{1}$")) e.Handled = true;
            }
            else e.Handled = e.KeyChar != (char)Keys.Back;
        }
    }

and it worked as it should. It restricted the input to one digit after the decimal point. But you could enter more than one decimal point and then also more digits. So you can either try

private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
        if (char.IsNumber(e.KeyChar) || ((e.KeyChar == '.') && (textBox1.Text.IndexOf('.')== -1 )))
        {
            if (Regex.IsMatch(
                textBox1.Text,
                "^\\d*\\.\\d{1}$")) e.Handled = true;
        }
        else e.Handled = e.KeyChar != (char)Keys.Back;
    }

or something like

private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
        if (char.IsNumber(e.KeyChar) || ((e.KeyChar == '.') && (textBox1.Text.IndexOf('.')== -1 )))
        {
            if (textBox1.Text.IndexOf('.') > 0)
            {
                if (textBox1.Text.IndexOf('.') < textBox1.Text.Length - 1)
                    e.Handled = true;
            }
        }
        else e.Handled = e.KeyChar != (char)Keys.Back;
    }

Upvotes: 0

Bernd Linde
Bernd Linde

Reputation: 2152

Instead of using a TextBox control for the input, look at using a MaskedTextbox control for your input. This will alleviate any self validation of the input and can show the users what input can be expected of them with messages as to why their input was not correct.

More information about the MaskedTextbox control:
MaskedTextbox
MaskedTextbox.Mask property
MSDN Walkthrough: Working with the MaskedTextBox Control

Upvotes: 0

Sayse
Sayse

Reputation: 43300

You can do this without regex by just checking where the decimal separator is in your text and then making sure that is 2 less than the length of the string (1 decimal place and 1 less for array length)

var decSeparator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
var idx = txtBasic.Text.IndexOf(decSeparator);
if(idx + 2 >= txtBasic.Text.Length)
    ...

Upvotes: 5

Related Questions