Как ограничить текстовое поле в С# только для получения чисел и (точка или запятая) после . или , разрешается использовать только 2 числовых символа

Я пытаюсь разработать код для ограничения TextBox с помощью С#, чтобы разрешить ввод только чисел + запятая ("") или точка ("") + только 2 числа после точки или запятой. Таким образом, можно увидеть возможные числа, которые могут вводиться:

3213,04 = OK
3211,664 = Not
32.31 = OK
32.3214 = Not
334,,00 = Not
3247,.00 = Not
214.,00 = Not
32.. = Not
8465,0 = Ok
654.0 = Ok

Понял мою цель? Я разработал код ниже

private void txtValormetrocubico_KeyPress(object sender, KeyPressEventArgs e)
{
    if (txtValormetrocubico.TextLength >= 0 && (e.KeyChar == (char)Keys.OemPeriod || e.KeyChar == (char)Keys.Oemcomma))
    {
        //tests 
    }
    else
    {
        if (!char.IsControl(e.KeyChar)
            && !char.IsDigit(e.KeyChar)
            && e.KeyChar != '.' && e.KeyChar != ',')
        {
            e.Handled = true;
        }
        // only allow one decimal point
        if (e.KeyChar == '.' && (sender as TextBox).Text.IndexOf('.') > -1)
        {
            e.Handled = true;
        }

        if (e.KeyChar == ','  && (sender as TextBox).Text.IndexOf(',') > -1)
        {
            e.Handled = true;
        }
    }
}

person felipe Salomao    schedule 17.04.2013    source источник
comment
как насчет этого номера без каких-либо '.' или ',' это нормально или нет 123456879   -  person saeed    schedule 17.04.2013


Ответы (4)


Попробуйте этот код! Надеюсь, это поможет. Дайте мне знать, если я могу помочь вам в дальнейшем.

Это вспомогательная функция, которую я написал

private bool alreadyExist(string _text , ref char KeyChar)
        {
            if (_text.IndexOf('.')>-1)
            {
                KeyChar = '.';
                return true;
            }
            if (_text.IndexOf(',') > -1)
            {
                KeyChar = ',';
                return true;
            }
            return false;
        }

Это ваш обработчик событий нажатия клавиши

 private void txtValormetrocubico_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!char.IsControl(e.KeyChar)
                    && !char.IsDigit(e.KeyChar)
                    && e.KeyChar != '.' && e.KeyChar != ',')
            {
                e.Handled = true;
            }

            //check if '.' , ',' pressed
            char sepratorChar='s';
            if (e.KeyChar == '.' || e.KeyChar == ',')
            {
                // check if it's in the beginning of text not accept
                if (txtValormetrocubico.Text.Length == 0) e.Handled = true;
                // check if it's in the beginning of text not accept
                if (txtValormetrocubico.SelectionStart== 0 ) e.Handled = true;
                // check if there is already exist a '.' , ','
                if (alreadyExist(txtValormetrocubico.Text , ref sepratorChar)) e.Handled = true;
                //check if '.' or ',' is in middle of a number and after it is not a number greater than 99
                if (txtValormetrocubico.SelectionStart != txtValormetrocubico.Text.Length && e.Handled ==false)
                {
                    // '.' or ',' is in the middle
                    string AfterDotString = txtValormetrocubico.Text.Substring(txtValormetrocubico.SelectionStart);

                    if (AfterDotString.Length> 2)
                    {
                        e.Handled = true;
                    }
                }
            }
            //check if a number pressed

            if (Char.IsDigit(e.KeyChar))
            {
                //check if a coma or dot exist
                if (alreadyExist(txtValormetrocubico.Text ,ref sepratorChar))
                {
                    int sepratorPosition = txtValormetrocubico.Text.IndexOf(sepratorChar);
                    string afterSepratorString = txtValormetrocubico.Text.Substring(sepratorPosition + 1 );
                    if (txtValormetrocubico.SelectionStart > sepratorPosition && afterSepratorString.Length >1)
                    {
                        e.Handled = true;
                    }

                }
            }


        }
person saeed    schedule 17.04.2013
comment
Это сработало как шарм, большое спасибо за это, изучу то, что вы сделали. +1 для вас. - person felipe Salomao; 18.04.2013
comment
Только одно сомнение, у меня есть около 10 текстовых полей, которые будут использовать этот код в одной и той же форме окна, нужно будет создавать копирование и вставку для каждого события нажатия клавиши, этот большой код заменяет текстовое имя в коде? или я могу сделать это по-другому, ссылаясь на этот код (но я не знаю, как решить проблему с текстовым именем). Спасибо еще раз - person felipe Salomao; 18.04.2013
comment
@felipeSalomao Это, вероятно, уже не имеет для вас значения, вы можете просто назвать метод чем-то общим, например TextBoxValidate, и назначить его для всех ваших 10 текстовых полей KeyPress-Events, чтобы все текстовые поля вызывали один и тот же метод. Следующим шагом является использование переменной sender, которая передается методу, вместо txtValormetrocubico. Таким образом, вы использовали бы ((TextBox)sender). Он содержит соответствующий TextBox, поэтому остальная часть кода должна нормально работать с любым TextBox, которому он назначен. - person Hexo; 14.01.2015

Я думаю, вам нужно что-то вроде элемента управления Masked Textbox, здесь у вас есть несколько ссылок

http://msdn.microsoft.com/en-us/library/kkx4h3az.aspx http://www.c-sharpcorner.com/uploadfile/mahesh/maskedtextbox-in-C-Sharp/

Другой способ сделать то, что вы хотите, — использовать регулярные выражения.

person Sergio Guillen Mantilla    schedule 17.04.2013
comment
Спасибо, но мне не нравится maskedtexbox. Я предпочитаю использовать пользовательский код, потому что он не отображается - или $ до заполнения поля. Я уже все работаю, только нужно решить эту небольшую проблему, чтобы решить ее полностью. В любом случае спасибо за информацию - person felipe Salomao; 17.04.2013

Ну, вы можете создать общую функцию и вызвать ее в событии keypress, этот код является общим экземпляром.

validate_textBox — это общая функция

private void validate_textBox(TextBox _text, KeyPressEventArgs e)
        {
            if (!char.IsControl(e.KeyChar)
                    && !char.IsDigit(e.KeyChar)
                    && e.KeyChar != '.' && e.KeyChar != ',')
            {
                e.Handled = true;
            }
            if (!char.IsControl(e.KeyChar)
        && !char.IsDigit(e.KeyChar)
        && e.KeyChar != '.' && e.KeyChar != ',')
            {
                e.Handled = true;
            }

            //check if '.' , ',' pressed
            char sepratorChar = 's';
            if (e.KeyChar == '.' || e.KeyChar == ',')
            {
                // check if it's in the beginning of text not accept
                if (_text.Text.Length == 0) e.Handled = true;
                // check if it's in the beginning of text not accept
                if (_text.SelectionStart == 0) e.Handled = true;
                // check if there is already exist a '.' , ','
                if (alreadyExist(_text.Text, ref sepratorChar)) e.Handled = true;
                //check if '.' or ',' is in middle of a number and after it is not a number greater than 99
                if (_text.SelectionStart != _text.Text.Length && e.Handled == false)
                {
                    // '.' or ',' is in the middle
                    string AfterDotString = _text.Text.Substring(_text.SelectionStart);

                    if (AfterDotString.Length > 2)
                    {
                        e.Handled = true;
                    }
                }
            }
            //check if a number pressed

            if (Char.IsDigit(e.KeyChar))
            {
                //check if a coma or dot exist
                if (alreadyExist(_text.Text, ref sepratorChar))
                {
                    int sepratorPosition = _text.Text.IndexOf(sepratorChar);
                    string afterSepratorString = _text.Text.Substring(sepratorPosition + 1);
                    if (_text.SelectionStart > sepratorPosition && afterSepratorString.Length > 1)
                    {
                        e.Handled = true;
                    }

                }
            }
        } 

Затем вы можете вызвать функцию, подобную этому коду, для каждого текстового поля, которое у вас есть в форме

        private void txtValormetrocubico_KeyPress(object sender, KeyPressEventArgs e)
        {
            validate_textBox(sender as TextBox, e);
        }
        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            validate_textBox(sender as TextBox, e);
        }
person saeed    schedule 18.04.2013
comment
Еще раз спасибо, парень. Это очень поможет мне в этом коде и во всем моем проекте. У меня пока мало знаний о C#, но многое, что я узнал, касалось переполнения стека. Спасибо за это. - person felipe Salomao; 18.04.2013

Я не знаю, кто ищет это в 2021 году, но вот одно решение, переопределяющее событие ontextchange! Ваше здоровье

  protected override void OnTextChanged(EventArgs e)
    {
   
        base.OnTextChanged(e);
        String text = "";

        Char[] chars = this.Text.ToString().ToCharArray();

        int total_dots = 0;
        int dot_pos = 0;

        int char_pos = 0;

        foreach (Char c in chars )
        {
            char_pos++;
           
            if (Char.IsDigit(c))
            {

                if(dot_pos > 0) { //dot already exists
                    
                    if (char_pos <= dot_pos + 2)  //only accept two numbers after dot (3.99)
                    {
                        text += c.ToString();
                    }

                }
                else
                {
                    text += c.ToString();
                }

               
            }

            if(c == '.' || c == ',')
            {
                total_dots++;

                if (char_pos > 1 && total_dots <=1)   //only accept one dot and if the dot is not in first position
                {
                    text += c.ToString();
                    dot_pos = char_pos;
                }
            }

        }

        this.Text = text;
        this.SelectionStart = this.Text.Length;

    }
person Jusman Swedish    schedule 19.07.2021