2014-11-11 7 views
5

Ich habe einfache WPF benutzerdefinierte Textfeld-Steuerelement für das Halten von Dezimalwerten geschrieben. Hier ist ein sehr „light“ Version des Codes, ohne die meisten Methoden und Eigenschaften (aber es sollte für die Prüfung genug sein):Seltsames Textbox Caret-Verhalten nach der Formatierung

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; 
     } 
    } 
} 

Und nun die Kuriosität beginnt. Wenn ich mehrere SAME-Nummern nacheinander eintippe, ist alles in Ordnung, bis die 10ten Zahlen eingegeben sind. Dann springt der Caret auf die 5. Position. Und das ist im Fall von 2 Dezimalziffern. Im Fall von beispielsweise 3 Dezimalziffern springt das Caret nach dem 11ten Tastenanschlag auf die 6te Position. Wenn ich verschiedene Zahlen eintippe, springt das Caret zum Ende des Textes. Wenn im Format keine Dezimalziffern vorliegen - alles funktioniert einwandfrei. Ich habe versucht, das Format manuell einzustellen - ohne Erfolg. Hier ist eine kleine Illustration: caret problem

Antwort

0

Wenn Sie die Einfügemarke direkt vor dem Komma verschieben möchten, versuchen Sie dies:

this.CaretIndex = string.Substring(0, this.Text.IndexOf(".")).Length; 
  • Wenn die oben bewegt die Einfügemarke nach dem Komma, ändern dazu:

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

Wenn Sie den Cursor an den Anfang der Box bewegen:

this.CaretIndex = 0; 

Wenn Sie den Cursor an das Ende der Box verschieben möchten:

this.CaretIndex = this.Text.Length;