Question

We have a .NET 2.0 Windows Forms application with lots of custom controls. A few years ago, we globalized our application, so users see the appropriate culture-specific symbols and translations.

A French Canadian customer has asked us to change how our application handles the number pad decimal key. Our numeric controls are not doing anything when the user presses this key.

I switched my Windows regional settings to French - Canada and debugged our application. I see the current culture and current UI culture are set to fr-CA.

In OnKeyDown and OnKeyPress I see the difference between the keyboard period (Keys.OemPeriod) and number pad period (Keys.Decimal). The specific keystroke comes across in OnKeyDown. However, in both cases, the OnKeyPress event gives our control a period:

Key               OnKeyDown      OnKeyPress
================= ============== ==========
Main Keyboard     Keys.OemPeriod "." 
Number Pad Period Keys.Decimal   "."

Our numeric controls handle number input in the OnKeyPress event. Since the period is not a decimal separator in the current culture, the control reject this character.

Is the globalization setting supposed to translate Keys.Decimal (number pad ".") into a comma automatically, or is our application supposed to change Keys.Decimal into the culture-specific decimal separator? I expected .NET to make this translation automatically.

Was it helpful?

Solution

The OnKeyDown event is generated by the Windows WM_KEYDOWN event. WM_KEYDOWN is sending our application a Key.Decimal event.

Similarly, the OnKeyPress event is generated directly from the WM_CHAR event. In the case of French - Canadian regional settings (with Canadian French keyboard), Windows sends a WM_CHAR event with a period when the user presses the number pad decimal key. However, in the case of French - Belgian settings with the "Belgian (Comma)" input settings, Windows sends a WM_CHAR event with a comma.

So this is neither a .NET bug nor a bug in our application. The regional input settings affects the behavior of the Decimal key.

However, some applications do respond differently in French - Canadian settings. For example, both Excel and Windows Calculator both translate Keys.Decimal into a comma instead of a period. These applications may have special handling for this case.

We could add code to our application to track a decimal key and handle it differently. For example:

protected override void OnKeyDown(KeyEventArgs e)
{
    if (e.KeyData == Keys.Decimal)
        m_DecimalKey = true;
}

protected override void OnKeyPress(KeyPressEventArgs e)
{
    ...
    if (m_DecimalKey || e.KeyChar == CultureInfo.CurrentUICulture.NumberFormat.NumberDecimalSeparator)
    {
        // this is a decimal separator
    }
}

protected virtual void OnKeyUp(KeyEventArgs e)
{
    if (e.KeyData == Keys.Decimal)
        m_DecimalKey = false;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top