Пользовательский числовой текстовый блок WPF с StringFormat N2 и десятичной привязкой - странная проблема - PullRequest
0 голосов
/ 24 февраля 2019

Я создал текстовое поле ниже, чтобы принимать только обнуляемые десятичные числа.Когда пользователь нажимает на десятичный разделитель, курсор переходит на десятичные дроби.Я также создал конвертер только для того, чтобы изменить пустую строку на null.

она работает нормально, но после 999.999.999,99 срабатывает какая-то странная функциональность.Когда я пытаюсь установить другое число, курсор переходит на случайные позиции в текстовом поле, и иногда вместо числа, которое нажимается, к концу добавляется ноль (0).

вот мой код, Текстовое поле:

    public class NumericTextBox : TextBox
{
    char decimalSeperator;

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        decimalSeperator = Convert.ToChar(Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator);
        DataObject.AddPastingHandler(this, PasteHandler);

        this.KeyUp += NumericTextBox_KeyUp;
        this.PreviewKeyDown += NumericTextBox_PreviewKeyDown;
        this.PreviewTextInput += NumericTextBox_PreviewTextInput;
    }

    void NumericTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
    {
        if (!e.Text.IsDigitsOnly())
            e.Handled = true;
    }

    void NumericTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        HandleWhiteSpace(e);
    }

    void NumericTextBox_KeyUp(object sender, KeyEventArgs e)
    {
        if (IsDecimalSeperator(e))
        {
            if (TextExists() && HasDecimalSeperator())
                Select(Text.IndexOf(decimalSeperator) + 1, 0);
        }
    }

    void PasteHandler(object sender, DataObjectPastingEventArgs e)
    {
        e.CancelCommand();
    }

    void HandleWhiteSpace(KeyEventArgs e)
    {
        if (e.Key == Key.Space)
            e.Handled = true;
    }

    bool TextExists()
    {
        return !String.IsNullOrEmpty(Text) && Text.Length > 0;
    }

    bool IsDecimalSeperator(KeyEventArgs e)
    {
        return e.Key == Key.Decimal || e.Key == Key.OemComma;
    }

    bool HasDecimalSeperator()
    {
        return Text.IndexOf(decimalSeperator) > 0;
    }
}

Расширение IsDigitsOnly:

public static class StringExtensions
{
    public static bool IsDigitsOnly(this string str)
    {
        foreach (char c in str)
            if (c < '0' || c > '9')
                return false;

        return true;
    }
}

Конвертер:

public class EmptyStringToNullNumericConverter : 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 as string == string.Empty)
            value = null;

        return value;
    }
}

и мой XAML:

<cc:NumericTextBox Grid.Row="8" Text="{Binding Cost, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, StringFormat='N2', Converter={StaticResource EmptyStringToNullNumericConverter}}"/>

Свойство "Стоимость"является обнуляемым десятичным числом.

...