Двойной десятичный разделитель WPF

При использовании TextBox в WPF у меня проблема в том, что если я использую ',' вместо '.' каждый раз, когда я пытаюсь получить значение, текст внутри TextBox преобразуется с тем же номером без запятой.

Как я могу отключить это автоматическое преобразование?

<TextBox 
    x:Name="XValue" 
    Text="{Binding XInitValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
    Width="80" VerticalAlignment="Center" 
    TextChanged="XValue_TextChanged" 
</TextBox>

private void XValue_TextChanged(object sender, TextChangedEventArgs e)
{
    double a = XInitValue;
}

1 ответ

Это действительно работает! Благодаря!

Я немного изменил его, чтобы он был более общим, не использовать CurrentCulture в самом конвертере и возвращать ошибку, если введенное значение заканчивается десятичным разделителем. Без последней части я вообще не мог ввести десятичный разделитель, если UpdateSourceTrigger=PropertyChanged.

public class DecimalConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
        {
            return null;
        }
        if (value is string stringValue && targetType == typeof(decimal))
        {
            var decSeparator = culture.NumberFormat.NumberDecimalSeparator;
            var normString = decSeparator == "."
                ? stringValue.Replace(",", ".")
                : stringValue.Replace(".", ",");
            if (!normString.EndsWith(decSeparator) && decimal.TryParse(normString, out var decResult))
            {
                return decResult;
            }
        }
        return DependencyProperty.UnsetValue;
    }
}

Конечно, CurrentCulture должен быть установлен в App.xml.cs или где-то еще при запуске приложения:

    var culture = CultureInfo.GetCultureInfo("de-DE");
    Thread.CurrentThread.CurrentCulture = culture;
    Thread.CurrentThread.CurrentUICulture = culture;
    FrameworkElement.LanguageProperty.OverrideMetadata(
        typeof(FrameworkElement),
        new FrameworkPropertyMetadata(
            XmlLanguage.GetLanguage(culture.IetfLanguageTag)));

Я решил это с помощью конвертера

public class DecimalConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator == ".")
                return value.ToString().Replace(",", ".");
            else
                return value.ToString().Replace(".", ",");
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator == ".")
                return value.ToString().Replace(".", ",");
            else
                return value.ToString().Replace(",", ".");
        }

    }
Другие вопросы по тегам