2014-11-11 10 views
5

Ho scritto un semplice controllo di casella di testo personalizzato WPF per contenere i valori decimali. Ecco una versione molto "leggera" del suo codice, senza la maggior parte dei metodi e proprietà (ma dovrebbe essere sufficiente per i test):Comportamento del comportamento corretto della casella di testo dopo la formattazione

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

E ora la stranezza inizia. Se digito diversi numeri SAME in successione, tutto va bene fino a quando non viene digitato il numero 10. Quindi il cursore salta alla 5a posizione. E questo è nel caso di 2 cifre decimali. In caso, ad esempio, di 3 cifre decimali, il punto di inserimento salta dopo la battuta dell'11 ° giro fino alla 6 ° posizione. Se digito numeri diversi, il cursore passa alla fine del testo. Se non ci sono cifre decimali in formato - tutto funziona ok. Ho provato a impostare il formato manualmente, senza successo. Ecco un piccolo dell'illustrazione: caret problem

risposta

0

Se si desidera spostare il cursore a destra prima del decimale, provate questo:

this.CaretIndex = string.Substring(0, this.Text.IndexOf(".")).Length; 
  • Se quanto sopra si sposta il cursore dopo la virgola, cambiarlo a questo:

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

Se si desidera spostare il cursore all'inizio della scatola:

this.CaretIndex = 0; 

Se si desidera spostare il cursore alla fine della casella:

this.CaretIndex = this.Text.Length; 
Problemi correlati