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: