简体   繁体   中英

How do I detect a NumberDecimalSeparator in a KeyDown event (C#)

I'm trying to see if the user has pressed a decimal separator in a text box, and either allow or suppress it depending on other parameters.

The NumberdecimalSeparator returns as 46, or '.' on my US system. Many other countries use ',' as the separator. The KeyDown event sets the KeyValue to 190 when I press the period.

Do I just continue to look for commas/periods, or is there a better way?

The call

CultureInfo.CurrentUICulture.NumberFormat.NumberDecimalSeparator

gets the decimal separator for the current user interface culture. You can use other cultures to get the separator for other languages.


EDIT

From the 166 cultures that are reported in my system ( CultureInfo.GetCultures(CultureTypes.SpecificCultures).Count() ), it seems that only two separators are used: period and comma. You can try this in your system:

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

Assuming that this is true, this method may be helpful (note that the keyCode is OR'ed with the modifiers flag in order to eliminate invalid combinations):

    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));
    }

A last note: According to Keys enumeration , the value 46 that you mention corresponds to the DEL (Delete) key (ie the point when Num Lock is OFF).

The problem here is that the values in the KeyEventArgs are key codes, not characters. If you handle KeyPress instead, you will get a char in the KeyPressEventArgs which you can use for the comparison.

Note: You should really compare the NumberDecimalSeparator characters as it is a string, not a single character so you need to consider scenarios where there is more than one character in the string.

If you need know if the char pressed is decimal separator:

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

But, if you need acept decimal numpad key as decimal separator of any culture:

    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;
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM