2009-12-29 56 views
2

我tryed在這裏創建自己的數字文本框是我的代碼: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 2012-03-26 17:01:12

-1

簡短而親切 - ?Alt鍵在較低的水平,那麼你的程序處理

This文章介紹了pro更詳細的瑕疵,而this鏈接提供了一些C++代碼,可以幫助你,如果你真的想解決這個問題。

+2

你不能真正在SL這個級別的編碼。 – AnthonyWJones 2009-12-29 22:50:41

+0

這就是我的答案。 – Ragepotato 2009-12-30 00:00:25

0

你只是想防止非數字文本輸入? this blog post中描述的另一種方法是創建一個文本框過濾器,該過濾器可以作爲附加的依賴項屬性添加到普通文本框中。無論哪種方式,由於用戶可能粘貼無效數據,因此輸入數據後仍然需要驗證數據。

1

有沒有什麼辦法來阻止一個「ALT +數字的組合?

不是真的。我的建議是不要打擾,看看會發生什麼。

TBH如果你真的想要建立一個數字輸入控件,你不應該從TextBox派生出來,你可以從Control派生出一個TextBox到你的新控件的默認控制模板中。 'd只是使用了Toolkit中的NumericUpDown。

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代碼使用它(「UI」名稱空間要求解決,但是,嘿,你還要做您的家庭作業:)):

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

所以基本上,擴展器會記住最後一個有效狀態(文本+選擇),並在新結果無效時恢復它。 enum InputType當然可以擴展。

+0

我還沒有測試過這個解決方案,但它的聲音好像比我的優越得多,所以+1! – Peter 2012-03-26 17:58:47