Strict behavior in the text box after formatting

I wrote a simple WPF text box control to store decimal values. Here is a very "light" version of its code without most of the methods and properties (but this is enough for testing):

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 weirdness begins. If I dial several APPLICABLE numbers in a row, everything will be fine until the 10th number is printed. Then the carriage moves to the 5th position. And this is the case with 2 decimal digits. In the case of, say, 3 decimal places, the carriage jumps after the 11th keystroke to the 6th position. If I type different numbers, the carriage jumps to the end of the text. If there are no decimal digits in the format, everything works fine. I tried to set the format manually - without success. Here is a small illustration: caret problem

+5
source share
1 answer

If you want to move the carriage just before the decimal point, try the following:

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

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

If you want to move the cursor to the beginning of the field:

 this.CaretIndex = 0; 

If you want to move the cursor to the end of the window:

 this.CaretIndex = this.Text.Length; 
0
source

Source: https://habr.com/ru/post/1206636/


All Articles