2009-12-29 2 views
2

я судимый создать свое собственное цифровое текстовое поле вот мой код:Цифровое текстовое поле Silverlight?

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

все работает, как предполагался, но если нажать Alt и несколько номеров создает символ ASCII, соответствующий номеру .. есть ли какой-либо способ блокировать «комбинацию Alt + номер , кажется, что Alt + клавиша просто получает вводится без идя бросил OnKeyUp или OnKeyDown ...

ответ

2

Я получил это работает, используя событие TextChanged вот мой код ...

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); 
    } 
} 
+0

Это опасно, потому что предполагается, что число написано с помощью «-» и цифр между «0» и «9», что неверно для всех культур. Также вам нужно обрабатывать как ключевые, так и текстовые события, поэтому это вдвое меньше минимального задания :) Я размещаю альтернативу ниже. – picrap

-1

Короткий и сладкий -. ключ Alt обрабатывается на более низком уровне, то ваша программа

This статья описывает про более подробно, а ссылка this содержит код C++, который может помочь вам, если вы действительно хотите обойти эту проблему.

+2

Вы не можете получить такой уровень кодирования в SL. – AnthonyWJones

+0

Это был мой ответ. – Ragepotato

0

Вы просто пытаетесь предотвратить ввод нечислового ввода текста? Другой подход, описанный в this blog post, заключается в создании фильтра текстового поля, который может быть добавлен в обычный TextBox в качестве прикрепленного свойства зависимостей. В любом случае вам все равно придется проверять данные после их ввода, поскольку пользователь может вставлять неверные данные.

1

есть ли способ заблокировать «комбинацию Alt + номер?

Не совсем. Мой совет будет не беспокоить и посмотреть, что происходит.

ТВН, если вы действительно хотите для построения цифрового управления вводами вы не должны извлекаться из TextBox. Вы должны были бы получить от Control и поместить TextBox в шаблон управления по умолчанию вашего нового элемента управления.

На самом деле быть честным я 'просто использовал NumericUpDown в Toolkit.

0

Я знаю, что был дан ответ, но я отправил a more elegant answers здесь (это может помочь кому-то!)

2

Вот альтернатива, требующая только прикрепленного свойства и следующего кода. Во-первых, код:

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

Затем используйте его в коде XAML (далее «УИ:» Пространство имен требует, чтобы решить, но эй, вы все еще должны сделать свои домашние задания :)):

<TextBox Text="{Binding MyText, Mode=TwoWay}" ui:Input.Type="PositiveNullableDecimal" /> 

Таким образом, в основном расширитель запоминает последнее действительное состояние (текст + выбор) и возвращает его, если новый результат недействителен. Enum InputType может быть, конечно, расширенным.

+0

Я не тестировал это решение, но его звуки кажутся намного превосходящими мои, так что +1! – Peter

Смежные вопросы