Here's an alternative requiring only the attached property and the following code. First, the code:
public enum InputType { PositiveInteger, PositiveDecimal, PositiveNullableInteger, PositiveNullableDecimal, } public static class Input { public static readonly DependencyProperty TypeProperty = DependencyProperty.RegisterAttached("Type", typeof(InputType), typeof(TextBox), new PropertyMetadata(default(InputType), OnTypeChanged)); public static void SetType(TextBox element, InputType value) { element.SetValue(TypeProperty, value); } public static InputType GetType(TextBox element) { return (InputType)element.GetValue(TypeProperty); } private class TextSelection { public string Text { get; private set; } public int SelectionStart { get; private set; } public int SelectionLength { get; private set; } public TextSelection(string text, int selectionStart, int selectionLength) { Text = text; SelectionStart = selectionStart; SelectionLength = selectionLength; } } private static readonly DependencyProperty PreviousTextSelectionProperty = DependencyProperty.RegisterAttached("PreviousTextSelection", typeof(TextSelection), typeof(TextBox), new PropertyMetadata(default(TextSelection))); private static void SetPreviousTextSelection(TextBox element, TextSelection value) { element.SetValue(PreviousTextSelectionProperty, value); } private static TextSelection GetPreviousTextSelection(TextBox element) { return (TextSelection)element.GetValue(PreviousTextSelectionProperty); } private static void OnTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (UIApplication.DesignMode) return; var textBox = (TextBox)d; textBox.TextChanged += OnTextChanged; textBox.SelectionChanged += OnSelectionChanged; }
Then use it in your xaml code (the "ui:" namespace needs permission, but hey, you still have to do your homework :)):
<TextBox Text="{Binding MyText, Mode=TwoWay}" ui:Input.Type="PositiveNullableDecimal" />
Basically, the expander remembers the last valid state (text + selection) and returns it if the new result is invalid. The enumerated type InputType can, of course, be extended.
source share