Я очень ценю ответы Томаса Левеска и Лукаса.Они содержали некоторые полезные идеи и примеры.Я публикую это как ответ, потому что хочу предоставить больше информации и пример решения.Как и в случае многих проблем с вычислительной средой / пользовательским интерфейсом, часто приходится идти на компромиссы.Я сделал неудачное открытие, что ни одно из InputScopeNameValues ( MSDN InputScopeNameValue Enumeration ) не переключается между десятичным (.) И запятой (,) при изменении настроек языка + региона (и, да, я дважды проверил, что клавиатурана моем телефоне было установлено использование только Deutsch).
![enter image description here](https://i.stack.imgur.com/uOb9L.png)
Однако, поскольку эти вводы TextBox являются числовыми и должны вводиться быстро, числовые InputScopes по-прежнему лучший способ,Интересно, что даже если пользователь вынужден использовать десятичную точку вместо запятой, как только она вводится в TextBox, формат строки изменяется, например, с «.123» на «, 123», даже если показано «{0».:. # 000}».Таким образом, компромисс и в приведенном ниже коде, обходной путь (проверено до сих пор в en-US и de-DE).
Примечание. Как упоминал Лукас, всегда целесообразно проверять вводимые пользователем данные.Я не использую здесь TryParse (хотя могу), поэтому мне не нужно переписывать много кода.Это смягчается в пользовательском интерфейсе путем выбора числового InputScope и в коде обработки через блоки try / catch, которые даже корректно обрабатывают пользователя, пытающегося обойти числовой ввод, вставляя текст из буфера обмена:
<TextBox x:Name="myTBox" InputScope="Number" Text="{Binding SomeNumber, Mode=TwoWay}" />
И код:
public string SomeNumber
{get {return String.Format ("{0: #. 000}", SomeProfileModel.Instance.SomeProfile.SomeNumber);}
set
{
if (SomeProfileModel.Instance.SomeProfile.SomeNumber.ToString() == value) return;
var oldValue = SomeProfileModel.Instance.SomeProfile.SomeNumber;
try
{
double newValue;
try
{
newValue = Convert.ToDouble(value, CultureInfo.CurrentCulture);
}
catch (Exception)
{
newValue = Convert.ToDouble(value, CultureInfo.InvariantCulture);
}
if (Convert.ToDouble(MyAppParams.SomeNumberMin, CultureInfo.InvariantCulture) > newValue || Convert.ToDouble(MyAppParams.SomeNumberMax, CultureInfo.InvariantCulture) < newValue)
{
// Revert back to previous value
// NOTE: This has to be done here. If done in the catch statement,
// it will never run since the MessageBox interferes with it.
throw new Exception();
}
SomeProfileModel.Instance.SomeProfile.SomeNumber = newValue;
RaisePropertyChanged("SomeNumber", oldValue, newValue, true);
}
catch (Exception err)
{
System.Windows.MessageBox.Show("Value must be a number between " + MyAppParams.SomeNumberMin + " and " + MyAppParams.SomeNumberMax);
}
}
}