我们有一个带有大量自定义控件的.NET 2.0 Windows窗体应用程序。几年前,我们将应用程序全球化,因此用户可以看到适当的特定文化符号和翻译。
加拿大法国客户要求我们更改应用程序处理数字键小数键的方式。当用户按下此键时,我们的数字控件没有执行任何操作。
我将Windows区域设置切换为法语 - 加拿大并调试了我们的应用程序。我看到当前的文化和当前的UI文化被设置为fr-CA。
在OnKeyDown和OnKeyPress中,我看到键盘周期(Keys.OemPeriod)和数字键盘周期(Keys.Decimal)之间的差异。 OnKeyDown中出现了特定的击键。但是,在这两种情况下,OnKeyPress事件都会为我们的控件提供一段时间:
Key OnKeyDown OnKeyPress
================= ============== ==========
Main Keyboard Keys.OemPeriod "."
Number Pad Period Keys.Decimal "."
我们的数字控件处理OnKeyPress事件中的数字输入。由于句点不是当前文化中的小数分隔符,因此控件将拒绝此字符。
全球化设置是否应该自动将Keys.Decimal(数字键盘“。”)转换为逗号,或者我们的应用程序是否应将Keys.Decimal更改为特定于文化的小数分隔符?我希望.NET自动进行这种翻译。
答案 0 :(得分:1)
OnKeyDown事件由Windows WM_KEYDOWN事件生成。 WM_KEYDOWN正在向我们的应用程序发送一个Key.Decimal事件。
类似地,OnKeyPress事件直接从WM_CHAR事件生成。对于法语 - 加拿大区域设置(使用加拿大法语键盘),Windows会在用户按下数字键盘十进制键时发送WM_CHAR事件。但是,对于带有“比利时(逗号)”输入设置的法语 - 比利时设置,Windows会发送带有逗号的WM_CHAR事件。
因此,这既不是.NET错误,也不是我们应用程序中的错误。区域输入设置会影响Decimal键的行为。
但是,某些应用程序在法语 - 加拿大设置中的反应不同。例如,Excel和Windows Calculator都将Keys.Decimal转换为逗号而不是句点。对于这种情况,这些应用程序可能有特殊处理。
我们可以在应用程序中添加代码来跟踪小数键并以不同方式处理它。例如:
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;
}