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