2008-11-06 15 views

Odpowiedz

5

Spójrz na NumericUpDown w Toolkit http://codeplex.com/Silverlight, a może możesz go użyć lub spojrzeć na źródło, aby zaimplementować własny numeryczny tekst.

+1

Jest tylko jeden problem z NumericUpDown. Na przykład masz wartość 999 i używasz Backspace do wyczyszczenia danych wejściowych, następnie tracisz fokus i ustawia ponownie 999 zamiast ustawiania go na 0. – Rumplin

+0

Dlaczego uważasz, że to jest problem? =)) –

6
private void Numclient_KeyDown(object sender, KeyEventArgs e) 
{ 
    if (e.Key < Key.D0 || e.Key > Key.D9) 
    { 
     if (e.Key < Key.NumPad0 || e.Key > Key.NumPad9) 
     { 
      if (e.Key != Key.Back && e.Key != Key.Shift) 
      { 
       e.Handled = true; 
      } 
     } 
    } 
} 
+0

Edycja amurry jest ulepszeniem tego, nas zamiast tego: http://stackoverflow.com/questions/268207/how-to-create-a-numeric-textbox-in-silverlight/1469073 # 1469073 –

9

Wziąłem Nidhal za sugerowaną odpowiedź i edytować go nieco do obsługi sprawy shift dla postaci powyżej cyfr (np.! @ # $%^& *()), ponieważ takie rozwiązanie będzie nadal pozwalają te znaki w polu tekstowym.

private void NumClient_KeyDown(object sender, KeyEventArgs e) 
{  
    // Handle Shift case 
    if (Keyboard.Modifiers == ModifierKeys.Shift) 
    { 
     e.Handled = true; 
    } 

    // Handle all other cases 
    if (!e.Handled && (e.Key < Key.D0 || e.Key > Key.D9)) 
    { 
     if (e.Key < Key.NumPad0 || e.Key > Key.NumPad9) 
     { 
      if (e.Key != Key.Back) 
      { 
       e.Handled = true; 
      } 
     } 
    }   
} 
+2

Połknie to również klawisz TAB i klawisz Shift-Tab. –

+0

jak to zrobić w MVVM? – user20358

+0

Czy to działa na klawiaturze AZERTY? – Koen

1

Działa:

static bool AltGrIsPressed; 

void Numclient_KeyUp(object sender, KeyEventArgs e) 
{ 
    if (e.Key == Key.Alt) 
    { 
     AltGrIsPressed = false; 
    } 
} 

void Numclient_KeyDown(object sender, KeyEventArgs e) 
{ 
    if (e.Key == Key.Alt) 
    { 
     AltGrIsPressed = true; 
    } 

    if (Keyboard.Modifiers == ModifierKeys.Shift || AltGrIsPressed == true) 
    { 
     e.Handled = true; 
    } 

    if (e.Handled == false && (e.Key < Key.D0 || e.Key > Key.D9)) 
    { 
     if (e.Key < Key.NumPad0 || e.Key > Key.NumPad9) 
     { 
      if (e.Key != Key.Back) 
      { 
       e.Handled = true; 
      } 
     } 
    }  
} 
1
private void txtbox_KeyDown(object sender, KeyEventArgs e) 
{ 
    if (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 
     e.Handled = true; 
} 
0

Extend normalną kontrolę Silverlight tekstowym. Dodaj ten kod wewnątrz rozszerzonego klasy TextBox:

string nums = "1234567890"; 
string lastText = ""; 
int lastSelStart = 0; 

protected override void TextChanged(object sender, TextChangedEventArgs e) 
{ 
    if(!nums.Contains(this.Text.Substring(this.Text.Length -1))) 
    { 
     this.Text = lastText; 
     this.SelectionStart = lastSelStart; 
     return; 
    } 

    lastText = this.Text; 
    lastSelStart = this.SelectionStart; 

} 
1

wiem, że zostało odebrane, ale nie znalazłem odpowiedniego rozwiązania, które obsługuje wszystkie przypadki szczególne, większość z pytaniami i odpowiedziami tutaj połyka kilka ważnych kluczy, takich jak Home, End, Tab, Shift + jakakolwiek rzecz, ..etc.

Opracowałem więc własną implementację, która może pomóc komuś!

public class IntegerTextBox : TextBox 
    { 
     /// <summary> 
     /// To be raised whenever integer value changed 
     /// </summary> 
     public event EventHandler ValueChanged; 

     /// <summary> 
     /// To restore if the user entered invalid characters 
     /// </summary> 
     private int lastSavedValue = 0; 

     private int lastSelectionStart = 0; 
     private int lastSelectionLength = 0; 


     public int IntegerValue 
     { 
      get 
      { 
       //the default value is 0 if there is no text in the textbox 
       int value = 0; 
       int.TryParse(Text, out value); 
       return value; 
      } 
      set 
      { 
       if (this.Text.Trim() != value.ToString()) 
       { 
        Text = value.ToString(); 
       } 
      } 
     } 

     public IntegerTextBox() 
      : base() 
     { 
      this.LostFocus += (sender, e) => 
       { 
        //if the user clears the text the text box and leaves it, set it to default value 
        if (string.IsNullOrWhiteSpace(this.Text)) 
         IntegerValue = 0; 
       }; 
      this.Loaded += (sender, e) => 
       { 
        //populate the textbox with Initial IntegerValue (default = 0) 
        this.Text = this.IntegerValue.ToString(); 
       }; 

      this.TextChanged += (sender, e) => 
       { 
        int newValue = 0; 
        if (int.TryParse(this.Text, out newValue)) //this will handle most cases like number exceeds the int max limits, negative numbers, ...etc. 
        { 
         if (string.IsNullOrWhiteSpace(Text) || lastSavedValue != newValue) 
         { 
          lastSavedValue = newValue; 
          //raise the event 
          EventHandler handler = ValueChanged; 
          if (handler != null) 
           handler(this, EventArgs.Empty); 

         } 
        } 
        else 
        { 
         //restore previous number 
         this.Text = lastSavedValue.ToString(); 
         //restore selected text 
         this.SelectionStart = lastSelectionStart; 
         this.SelectionLength = lastSelectionLength; 
        } 
       }; 

      this.KeyDown += (sender, e) => 
       { 
        //before every key press, save selection start and length to handle overwriting selected numbers 
        lastSelectionStart = this.SelectionStart; 
        lastSelectionLength = this.SelectionLength; 
       }; 
     } 
    } 

Powyższy kod ma pojedynczą wadę, wydarzenie TextChanged będą często podnoszone, ale ponieważ potrzebujemy integer tekstowe, to możemy liczyć na ValueChanged zamiast!

-1

Dlaczego wszyscy nie wykonują ciężkiej pracy polegającej na obsługiwaniu ich wszystkich?

Oto (jest to doskonałość):

<TextBox KeyDown="TextBox_KeyDown" /> 

private void TextBox_KeyDown(object sender, KeyEventArgs e) 
{ 
    var _Letter = string.Empty; 
    switch (e.Key) 
    { 
     case Key.A: _Letter = "A"; break; 
     case Key.Add: _Letter = "+"; break; 
     case Key.Alt: break; 
     case Key.B: _Letter = "B"; break; 
     case Key.Back: break; 
     case Key.C: _Letter = "C"; break; 
     case Key.CapsLock: break; 
     case Key.Ctrl: break; 
     case Key.D: _Letter = "D"; break; 
     case Key.D0: _Letter = "0"; break; 
     case Key.D1: _Letter = "1"; break; 
     case Key.D2: _Letter = "2"; break; 
     case Key.D3: _Letter = "3"; break; 
     case Key.D4: _Letter = "4"; break; 
     case Key.D5: _Letter = "5"; break; 
     case Key.D6: _Letter = "6"; break; 
     case Key.D7: _Letter = "7"; break; 
     case Key.D8: _Letter = "8"; break; 
     case Key.D9: _Letter = "9"; break; 
     case Key.Decimal: _Letter = "."; break; 
     case Key.Delete: break; 
     case Key.Divide: _Letter = "/"; break; 
     case Key.Down: break; 
     case Key.E: _Letter = "E"; break; 
     case Key.End: break; 
     case Key.Enter: break; 
     case Key.Escape: break; 
     case Key.F: _Letter = "F"; break; 
     case Key.F1: break; 
     case Key.F10: break; 
     case Key.F11: break; 
     case Key.F12: break; 
     case Key.F2: break; 
     case Key.F3: break; 
     case Key.F4: break; 
     case Key.F5: break; 
     case Key.F6: break; 
     case Key.F7: break; 
     case Key.F8: break; 
     case Key.F9: break; 
     case Key.G: _Letter = "G"; break; 
     case Key.H: _Letter = "H"; break; 
     case Key.Home: break; 
     case Key.I: _Letter = "I"; break; 
     case Key.Insert: break; 
     case Key.J: _Letter = "J"; break; 
     case Key.K: _Letter = "K"; break; 
     case Key.L: _Letter = "L"; break; 
     case Key.Left: break; 
     case Key.M: _Letter = "M"; break; 
     case Key.Multiply: _Letter = "*"; break; 
     case Key.N: _Letter = "N"; break; 
     case Key.None: break; 
     case Key.NumPad0: _Letter = "0"; break; 
     case Key.NumPad1: _Letter = "1"; break; 
     case Key.NumPad2: _Letter = "2"; break; 
     case Key.NumPad3: _Letter = "3"; break; 
     case Key.NumPad4: _Letter = "4"; break; 
     case Key.NumPad5: _Letter = "5"; break; 
     case Key.NumPad6: _Letter = "6"; break; 
     case Key.NumPad7: _Letter = "7"; break; 
     case Key.NumPad8: _Letter = "8"; break; 
     case Key.NumPad9: _Letter = "9"; break; 
     case Key.O: _Letter = "O"; break; 
     case Key.P: _Letter = "P"; break; 
     case Key.PageDown: break; 
     case Key.PageUp: break; 
     case Key.Q: _Letter = "Q"; break; 
     case Key.R: _Letter = "R"; break; 
     case Key.Right: break; 
     case Key.S: _Letter = "S"; break; 
     case Key.Shift: break; 
     case Key.Space: _Letter = " "; break; 
     case Key.Subtract: _Letter = "-"; break; 
     case Key.T: _Letter = "T"; break; 
     case Key.Tab: break; 
     case Key.U: _Letter = "U"; break; 
     case Key.Unknown: break; 
     case Key.Up: break; 
     case Key.V: _Letter = "V"; break; 
     case Key.W: _Letter = "W"; break; 
     case Key.X: _Letter = "X"; break; 
     case Key.Y: _Letter = "Y"; break; 
     case Key.Z: _Letter = "Z"; break; 
     default: break; 
    } 
    var _Text = (sender as TextBox).Text + _Letter; 
    double _Double; 
    e.Handled = !double.TryParse(_Text, out _Double); 
} 

}

+1

Klucz.D0 do Key.D9 nie reprezentuje liczb w AZERTY, np. (tylko w połączeniu z przesunięciem).To dopiero początek naprawy tego kodu. Tyle dla doskonałości ... – Koen

+1

Dang my confidence! –

7

Odwiedź http://www.dataartist.net/blog/post/Silverlight-Behavior-Modifications-13-NumericOnlyBehavior.aspx użycie lub zachowanie TextBox jak poniżej

using System; 
    using System.Windows; 
    using System.Windows.Controls; 
    using System.Windows.Input; 
    using System.Windows.Interactivity; 

    namespace DataArtist 
    { 
public class NumericOnly : Behavior<TextBox> 
{ 
    private string Text { get; set; } 
    private bool shiftKey; 
    public bool StripOnExit { get; set; } 

    public NumericOnly() 
    { 
     StripOnExit = false; 
    } 

    protected override void OnAttached() 
    { 
     base.OnAttached(); 
     AssociatedObject.KeyDown += KeyDown; 
     AssociatedObject.KeyUp += KeyUp; 
     AssociatedObject.GotFocus += GotFocus; 
     AssociatedObject.LostFocus += LostFocus; 
    } 

    void KeyUp(object sender, KeyEventArgs e) 
    { 
     if (e.Key == Key.Shift) 
     { 
      shiftKey = false; 
     } 
    } 

    void KeyDown(object sender, KeyEventArgs e) 
    { 
     if (StripOnExit != false || e.Key == Key.Tab || e.Key == Key.Enter) 
     { 
      return; 
     } 

     if (e.Key == Key.Shift) 
     { 
      shiftKey = true; 
     } 
     else 
     { 
      if (IsNumericKey(e.Key) == false) 
      { 
       e.Handled = true; 
      } 
     } 
    } 

    void GotFocus(object sender, RoutedEventArgs e) 
    { 
     Text = AssociatedObject.Text; 
    } 

    private void LostFocus(object sender, RoutedEventArgs e) 
    { 
     if (AssociatedObject.Text == Text) 
     { 
      return; 
     } 

     string content = string.Empty; 

     foreach (var c in AssociatedObject.Text) 
     { 
      if (Char.IsNumber(c) == true) 
      { 
       content += c; 
      } 
     } 

     AssociatedObject.Text = content; 
    } 

    public bool IsNumericKey(Key key) 
    { 
     if (shiftKey == true) 
     { 
      return false; 
     } 

     string code = key.ToString().Replace("NumPad", "D"); 

     if (code[0] == 'D' && code.Length > 1) 
     { 
      return (Char.IsNumber(code[1])); 
     } 

     return false; 
    } 

    protected override void OnDetaching() 
    { 
     base.OnDetaching(); 
     AssociatedObject.KeyDown -= KeyDown; 
     AssociatedObject.LostFocus -= LostFocus; 
     AssociatedObject.GotFocus -= GotFocus; 
    } 
} 
    } 
+0

Zachowanie to zdecydowanie droga. Łatwiejsze jest również wyzerowanie niż dołączone właściwości. (Załączone właściwości, które są podłączone do uchwytów KeyUp i KeyDown, mają duże szanse na utworzenie korzenia GC i zapobiegają zbędnemu gromadzeniu danych.Może to zostać zmodyfikowane, tak aby wszystkie procedury obsługi zdarzeń zostały dodane w załadowanym zdarzeniu, a następnie odłączone w zdarzeniu Unloaded.) –

+0

Strona wydaje się być wyłączona, dziękuję za kopię. – Caramiriel

2
private void TextBox_KeyDown(object sender, KeyEventArgs e) 
    { 
     bool isDigit = e.Key >= Key.D0 && 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.Key == Key.Back || e.Key == Key.Delete || e.Key == Key.Left || e.Key == Key.Right; 

     if (isDigit) { } 
     else 
      e.Handled = true; 
    }