Как обнаружить NumberDecimalSeparator в событии KeyDown (C#)

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

NumberdecimalSeparator возвращает 46 или '.' в моей системе США. Во многих других странах в качестве разделителя используется ",". Событие KeyDown устанавливает KeyValue на 190, когда я нажимаю точку.

Я просто продолжу искать запятые / точки или есть способ лучше?

Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
0
9 306
3

Ответы 3

Вызов

CultureInfo.CurrentUICulture.NumberFormat.NumberDecimalSeparator

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


РЕДАКТИРОВАТЬ

Из 166 культур, представленных в моей системе (CultureInfo.GetCultures(CultureTypes.SpecificCultures).Count()), кажется, что используются только два разделителя: точка и запятая. Вы можете попробовать это в своей системе:

var seps = CultureInfo.GetCultures(CultureTypes.SpecificCultures)
            .Select(ci => ci.NumberFormat.NumberDecimalSeparator)
            .Distinct()
            .ToList();

Предполагая, что это правда, этот метод может быть полезным (обратите внимание, что keyCode объединяется с помощью OR с флагом modifiers, чтобы исключить недопустимые комбинации):

    private bool IsDecimalSeparator(Keys keyCode, Keys modifiers)
    {
        Keys fullKeyCode = keyCode | modifiers;
        if (fullKeyCode.Equals(Keys.Decimal))          // value=110
            return true;

        string uiSep = CultureInfo.CurrentUICulture.NumberFormat.NumberDecimalSeparator;
        if (uiSep.Equals("."))
            return fullKeyCode.Equals(Keys.OemPeriod); // value=190
        else if (uiSep.Equals(","))
            return fullKeyCode.Equals(Keys.Oemcomma);  // value=188
        throw new ApplicationException(string.Format("Unknown separator found {0}", uiSep));
    }

Последнее замечание: согласно Перечисление ключей, значение 46, которое вы упомянули, соответствует клавише DEL (Удалить) (то есть точке, когда Num Lock выключен).

Это не дает ответа на вопрос, если учесть: «NumberdecimalSeparator возвращает значение 46 или '.' в моей системе в США. Во многих других странах в качестве разделителя используется символ ",". Событие KeyDown устанавливает для KeyValue значение 190, когда я нажимаю точку ". ... как написано в вопросе.

Jeff Yates 16.10.2008 07:26

Проблема здесь в том, что значения в KeyEventArgs являются кодами клавиш, а не символами. Если вместо этого вы будете обрабатывать KeyPress, вы получите символ в KeyPressEventArgs, который вы можете использовать для сравнения.

Примечание. Вам действительно следует сравнивать символы NumberDecimalSeparator, поскольку это строка, а не отдельный символ, поэтому вам необходимо учитывать сценарии, в которых в строке содержится более одного символа.

Если вам нужно знать, является ли нажатый символ десятичным разделителем:

private void Control_KeyPress(object sender, KeyPressEventArgs e)
{
    char separator = System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator[0];
    if (e.KeyCahr == separador)
    {
        // true
    }
    else
    {
        // false
    }
}

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

    private bool decimalSeparator = false;
    private void Control_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.Decimal)
            decimalSeparator = true;
    }

    private void Control_KeyPress(object sender, KeyPressEventArgs e)
    {
        if (decimalSeparator)
        {
            e.KeyChar = System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator[0];
            decimalSeparator = false;
        }
    }

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