格式化后奇怪的文本框插入符号行为

时间:2023-01-14 16:10:08

I have written simple WPF custom textbox control for holding decimal values. Here is a very "light" version of its code, without most of methods and properties (but it should be enough for testing):

我编写了简单的WPF自定义文本框控件来保存小数值。这是一个非常“轻”的代码版本,没有大多数方法和属性(但它应该足以进行测试):

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace CustomControls
{
    public class NumericBox : TextBox
    {
        public static readonly DependencyProperty ValueProperty;
        public static readonly DependencyProperty DecimalCountProperty;

        static NumericBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(NumericBox), new FrameworkPropertyMetadata(typeof(NumericBox)));
            ValueProperty = DependencyProperty.Register("Value", typeof (decimal?), typeof (NumericBox),
                new FrameworkPropertyMetadata(0m, OnValueChanged));
            DecimalCountProperty = DependencyProperty.Register("DecimalCount", typeof(int), typeof(NumericBox),
                new FrameworkPropertyMetadata(2, OnDecimalCountChanged));

        }
        public int DecimalCount
        {
            get { return (int)GetValue(DecimalCountProperty); }
            set { SetValue(DecimalCountProperty, value); }
        }
        public decimal? Value
        {
            get { return (decimal?)GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }
        private static void OnValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
        }
        private static void OnDecimalCountChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
        }
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            BindingOperations.ClearAllBindings(this);
            var textBinding = new Binding("Value")
            {
                Converter = new TextToNumericBoxValueConverter(),
                Mode = BindingMode.TwoWay,
                UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
                RelativeSource = new RelativeSource(RelativeSourceMode.Self),
                ConverterParameter = DecimalCount
            };
            SetBinding(TextProperty, textBinding);
        }
    }

    public class TextToNumericBoxValueConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var d = value as decimal?;
            if (d == null) return "";
            var p = parameter is int ? (int)parameter : 0;
            var nf = culture.NumberFormat.Clone() as NumberFormatInfo;
            if (nf == null) return "";
            nf.NumberDecimalDigits = p;
            return d.Value.ToString("N", nf);
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            decimal d;
            var s = value as string;
            if (s == null)
                return null;
            if (decimal.TryParse(s, out d))
                return d;
            return null;
        }
    }
}

And now the oddity begins. If I type several SAME numbers in succession, everything is ok until 10-th numbers is typed. Then the caret jumps to the 5-th position. And this is in case of 2 decimal digits. In case of, say, 3 decimal digits the caret jumps after 11-th keystroke to the 6-th position. If I type different numbers, the caret jumps to the end of text. If there are no decimal digits in format - everything works ok. I've tried to set the format manually - without success. Here is a small illustration: 格式化后奇怪的文本框插入符号行为

现在奇怪的事情开始了。如果我连续输入几个相同的数字,一切都可以,直到输入第10个数字。然后插入符号跳到第5个位置。这是2位小数的情况。在例如3个十进制数字的情况下,插入符号在第11次击键后跳到第6个位置。如果我键入不同的数字,插入符号会跳到文本的末尾。如果格式中没有十进制数字 - 一切正常。我试图手动设置格式 - 没有成功。这是一个小例子:

1 个解决方案

#1


0  

If you want to move the caret right before the decimal, try this:

如果要在十进制之前移动插入符号,请尝试以下操作:

this.CaretIndex = string.Substring(0, this.Text.IndexOf(".")).Length;
  • If the above moves the caret after the decimal, change it to this:

    如果上面的小数点后移动插入符号,请将其更改为:

    this.CaretIndex = string.Substring(0, this.Text.IndexOf(".") - 1).Length;

    this.CaretIndex = string.Substring(0,this.Text.IndexOf(“。”) - 1).Length;

If you want to move the caret to the beginning of the box:

如果要将插入符号移动到框的开头:

this.CaretIndex = 0;

If you want to move the caret to the end of the box:

如果要将插入符号移动到框的末尾:

this.CaretIndex = this.Text.Length;

#1


0  

If you want to move the caret right before the decimal, try this:

如果要在十进制之前移动插入符号,请尝试以下操作:

this.CaretIndex = string.Substring(0, this.Text.IndexOf(".")).Length;
  • If the above moves the caret after the decimal, change it to this:

    如果上面的小数点后移动插入符号,请将其更改为:

    this.CaretIndex = string.Substring(0, this.Text.IndexOf(".") - 1).Length;

    this.CaretIndex = string.Substring(0,this.Text.IndexOf(“。”) - 1).Length;

If you want to move the caret to the beginning of the box:

如果要将插入符号移动到框的开头:

this.CaretIndex = 0;

If you want to move the caret to the end of the box:

如果要将插入符号移动到框的末尾:

this.CaretIndex = this.Text.Length;