Silverlight digital text box?

I tried to create my own numeric text box, here is my code:

public class NumericTextBox : TextBox { public NumericTextBox() : base() { this.Text = "0"; } private void HandleKeyEvent(KeyEventArgs e) { e.Handled = true; if ((Keyboard.Modifiers & ModifierKeys.Alt) != 0) { return; } if (e.Key == Key.Back || e.Key == Key.Delete || e.Key == Key.Left || e.Key == Key.Right || e.Key == Key.D0 || e.Key == Key.D1 || e.Key == Key.D2 || e.Key == Key.D3 || e.Key == Key.D4 || e.Key == Key.D5 || e.Key == Key.D6 || e.Key == Key.D7 || e.Key == Key.D8 || e.Key == Key.D9 || e.Key == Key.NumPad0 || e.Key == Key.NumPad1 || e.Key == Key.NumPad2 || e.Key == Key.NumPad3 || e.Key == Key.NumPad4 || e.Key == Key.NumPad5 || e.Key == Key.NumPad6 || e.Key == Key.NumPad7 || e.Key == Key.NumPad8 || e.Key == Key.NumPad9) { e.Handled = false; } else if ((e.Key == Key.Subtract || (e.Key == Key.Unknown && e.PlatformKeyCode == 189)) && base.SelectionStart == 0 && (base.Text.Length == 0 || base.Text[0] != '-')) { e.Handled = false; } } protected override void OnKeyDown(KeyEventArgs e) { HandleKeyEvent(e); base.OnKeyDown(e); } protected override void OnKeyUp(KeyEventArgs e) { HandleKeyEvent(e); base.OnKeyUp(e); } } 

everything works as intended, but if you press alt and some numbers, it creates an ascii character corresponding to the number .. is there any way to block the combination "alt + number"? it seems that the alt + key is just entered without accessing OnKeyUp or OnKeyDown ...

+2
source share
6 answers

I got it using the TextChanged event, here is my code ...

 public class NumericTextBox : TextBox { int value; public NumericTextBox() : base() { this.Text = "0"; this.TextChanged += new TextChangedEventHandler(NumericTextBox_TextChanged); } void NumericTextBox_TextChanged(object sender, TextChangedEventArgs e) { int selectionStart = base.SelectionStart; bool changed = false; List<char> charList = new List<char>(); for (int i = 0; i < base.Text.Length; i++) { if (IsValidChar(base.Text[i], i)) { charList.Add(base.Text[i]); } else { if (selectionStart >= i) { selectionStart--; } changed = true; } } if (changed) { string text = new string(charList.ToArray()); this.Text = text; this.SelectionStart = selectionStart; } int newValue; if (!int.TryParse(this.Text, out newValue)) { this.Text = value.ToString(); this.SelectionStart = this.Text.Length; } else { value = newValue; } } private bool IsValidChar(char c, int index) { return ((c == '-' && index == 0) || c == '0' || c == '1' || c == '2' || c == '3' || c == '4' || c == '5' || c == '6' || c == '7' || c == '8' || c == '9'); } private void HandleKeyEvent(KeyEventArgs e) { e.Handled = true; if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control) { e.Handled = false; } if (e.Key == Key.Back || e.Key == Key.Delete || e.Key == Key.Left || e.Key == Key.Right || e.Key == Key.D0 || e.Key == Key.D1 || e.Key == Key.D2 || e.Key == Key.D3 || e.Key == Key.D4 || e.Key == Key.D5 || e.Key == Key.D6 || e.Key == Key.D7 || e.Key == Key.D8 || e.Key == Key.D9 || e.Key == Key.NumPad0 || e.Key == Key.NumPad1 || e.Key == Key.NumPad2 || e.Key == Key.NumPad3 || e.Key == Key.NumPad4 || e.Key == Key.NumPad5 || e.Key == Key.NumPad6 || e.Key == Key.NumPad7 || e.Key == Key.NumPad8 || e.Key == Key.NumPad9) { e.Handled = false; } else if ((e.Key == Key.Subtract || (e.Key == Key.Unknown && e.PlatformKeyCode == 189)) && base.SelectionStart == 0 && (base.Text.Length == 0 || base.Text[0] != '-')) { e.Handled = false; } } protected override void OnKeyDown(KeyEventArgs e) { HandleKeyEvent(e); base.OnKeyDown(e); } protected override void OnKeyUp(KeyEventArgs e) { HandleKeyEvent(e); base.OnKeyUp(e); } } 
+2
source

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; } /// <summary> /// Determines whether the specified text is valid. /// </summary> /// <param name="text">The text.</param> /// <param name="inputType">Type of the input.</param> /// <returns> /// <c>true</c> if the specified text is valid; otherwise, <c>false</c>. /// </returns> private static bool IsValid(string text, InputType inputType) { switch (inputType) { case InputType.PositiveInteger: int i; return int.TryParse(text, out i); case InputType.PositiveDecimal: decimal d; return decimal.TryParse(text, out d) && d >= 0; case InputType.PositiveNullableInteger: return text.IsNullOrEmpty() || IsValid(text, InputType.PositiveInteger); case InputType.PositiveNullableDecimal: return text.IsNullOrEmpty() || IsValid(text, InputType.PositiveDecimal); default: throw new ArgumentOutOfRangeException("inputType"); } } private static void OnTextChanged(object sender, TextChangedEventArgs e) { var textBox = (TextBox)sender; var inputType = GetType(textBox); if (IsValid(textBox.Text, inputType)) { SetPreviousTextSelection(textBox, new TextSelection(textBox.Text, textBox.SelectionStart, textBox.SelectionLength)); } else { var textSelection = GetPreviousTextSelection(textBox); if (textSelection == null) { textBox.Text = ""; } else { textBox.Text = textSelection.Text; textBox.SelectionStart = textSelection.SelectionStart; textBox.SelectionLength = textSelection.SelectionLength; } } } private static void OnSelectionChanged(object sender, RoutedEventArgs e) { var textBox = (TextBox)sender; SetPreviousTextSelection(textBox, new TextSelection(textBox.Text, textBox.SelectionStart, textBox.SelectionLength)); } } 

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.

+2
source

Is there a way to block the "alt + number" combination?

Not really. My advice will not bother or see what is happening.

TBH, if you really want to create digital input control, you should not output TextBox . You would have to get from Control and put the TextBox in the default control template of your new control.

In fact, to be honest, I just used NumericUpDown in the Toolkit .

+1
source

Are you just trying to prevent non-numeric text input? Another approach described in this blog post is to create a text field filter that can be added to a regular TextBox as an attached dependency property. In any case, you still have to check the data after entering it, since the user can insert incorrect data.

0
source

I know that they answered me, but I posted more elegant answers here (this may help someone!)

0
source

Short and sweet - the Alt key is processed at a lower level than your program.

This article describes the problem in more detail, while this contains some C ++ code that can help you if you really want to work around this problem.

-one
source

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


All Articles