TextBox только с числами

Мне нужно создать TextBox только с числами, но я не мог этого сделать. Я пытался поставить: InputScope = "Numbers", но это работает только на мобильных устройствах. Также я пробовал на TextChanging это:

private void textBox1_TextChanged(object sender, EventArgs e)
{
    if (System.Text.RegularExpressions.Regex.IsMatch(textBox1.Text, "[^0-9]"))
    {

        textBox1.Text = textBox1.Text.Remove(textBox1.Text.Length - 1);
    }
}

@CodeCaster Это абсолютно не дубликат. Отмеченный вопрос относится к технологии WPF, и решение не применяется в UWP.

Martin Zikmund 03.10.2018 12:32

Спасибо @CodeCaster, я опубликовал полный ответ.

Martin Zikmund 03.10.2018 13:16
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
2
7 036
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Ответ принят как подходящий

Вы можете либо запретить любой нечисловой ввод вообще, либо просто отфильтровать цифры в тексте.

Предотвращение нецифрового ввода

Используйте событие BeforeTextChanging:

<TextBox BeforeTextChanging = "TextBox_OnBeforeTextChanging" />

А теперь обработайте вот так:

private void TextBox_OnBeforeTextChanging(TextBox sender,
                                          TextBoxBeforeTextChangingEventArgs args)
{
    args.Cancel = args.NewText.Any(c => !char.IsDigit(c));
}

Это выражение LINQ вернет true и, следовательно, Cancel - изменение текста в случае, если во входных данных встретится какой-либо нецифровой символ.

Фильтрация нецифрового ввода

Используйте событие TextChanging:

<TextBox TextChanging = "TextBox_OnTextChanging" /> 

И поступайте так:

private void TextBox_OnTextChanging(TextBox sender, TextBoxTextChangingEventArgs args)
{
    //Save the position of the selection, to prevent the cursor to jump to the start
    int pos = sender.SelectionStart;
    sender.Text = new String(sender.Text.Where(char.IsDigit).ToArray());
    sender.SelectionStart = pos;
}

Этот запрос LINQ отфильтрует нецифровые символы и создаст новый string только с цифрами на входе.

Предпочтительно использовать TextChanging и BeforeTextChanging, потому что TextChanged возникает слишком поздно, поэтому пользователь будет сбит с толку, увидев символы, временно отображаемые на экране и немедленно исчезающие.

Использование linq для этого отлично.

peterincumbria 12.11.2018 12:59

Обратите внимание, что событие BeforeTextChanging доступно только в контракте API v5 (Windows v10.0.16299.0) и более поздних версиях. Если вместо этого вы работаете с TextChanging, вам следует восстановить (и отрегулировать) текущий выбор. В противном случае вы увидите, как курсор прыгает, создавая очень плохой пользовательский опыт.

IInspectable 02.11.2019 09:54

Если вы привязываете Text к int, это решение вызывает исключения, потому что пустая строка не преобразуется автоматически в 0. Если вы этого не хотите, вам нужно заменить «» на «0» в TextChanging.

Benni 01.05.2020 18:08

Вы можете сделать что-то еще вместо функции TextBox.Text.Remove, которая является функцией Substring, и также вы должны исправить это, пока они копируют серию символов, которая включает буквы в центре строки: -

private void textBox1_TextChanged(object sender, EventArgs e)
{
    var txt = textBox1.Text;

        if (System.Text.RegularExpressions.Regex.IsMatch(txt, "[^0-9]"))
        {
            for (int i = 0; i < txt.Length; i++)
                if (!char.IsDigit(txt[i]))
                    if (i != txt.Length - 1)
                    {
                        //If he pasted a letter inclusive string which includes letters in the middle
                        //Remove the middle character or remove all text and request number as input
                        //I did the second way
                        textBox1.Text = "";
                        break;
                    }
                    else
                    {
                        //If he just typed a letter in the end of the text
                        textBox1.Text = txt.Substring(0, txt.Length - 1);
                        break;
                    }
        }
}

Вот решение O (1) без сопоставления строк

    bool textCanceled = false;

    private void TextBox_KeyDown(object sender, KeyRoutedEventArgs e)
    {
        if (!Char.IsDigit((char)e.Key))
            textCanceled = true;
        else
            textCanceled = false;

    }

    private void TextBox_BeforeTextChanging(TextBox sender, TextBoxBeforeTextChangingEventArgs args)
    {
        args.Cancel = textCanceled;
    }

возможно, придется обрабатывать символ обратного пробела как особый случай

Надежная стратегия решения проблем: 1 Заставить работать. 2 По желанию сделать быстро. Этот ответ кажется обратным: 1 Сделайте это быстро. 2 При желании заставить работать. Это не учитывает вставку текста пользователем с помощью клавиатуры или мыши. Этот предложенный ответ не может быть исправлен, чтобы решить эту проблему.

IInspectable 02.11.2019 10:00

На основании ответа https://stackoverflow.com/a/52624310/13814517 на этот вопрос.

Если вы хотите также разрешить ввод типа 100,0, у вас может быть проблема с десятичной точкой. так

  1. включить частное событие OnBeforeTextChanging в текстовом поле
  2. в обработчике:
private void TextBox_OnBeforeTextChanging(TextBox sender,
                                          TextBoxBeforeTextChangingEventArgs args)
{
    double tempDouble;
    args.Cancel  = !(double.TryParse(args.NewText, out tempDouble) | args.NewText == "");

}

Основываясь на принятом решении ответа для текста фильтрация out, если вам нужно использовать событие TextChanged:

private void HexTextBox_TextChanged(object sender, EventArgs e)
{
    if (!(sender is TextBox txt))
        return;

    // Filter out any invalid chars that are typed/pasted and leave the cursor where it was (or reasonably close).
    int pos = txt.SelectionStart;
    txt.Text = string.Concat(txt.Text.Where(c => "0123456789abcdefABCDEF".IndexOf(c) != -1));
    txt.SelectionStart = pos;
}

Это делает так, что кто-то не может вводить нежелательные символы в TextBox. И если они их вставляют, их игнорируют. Например. для приведенного выше, если вы попытаетесь вставить «12 # 45 ^», вы получите «1245» в текстовом поле.

Другие вопросы по теме