C# 如何在 Silverlight 中创建数字文本框?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/268207/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 20:48:49  来源:igfitidea点击:

How to create a numeric textbox in Silverlight?

c#.netsilverlighttextboxsilverlight-2.0

提问by Mark Ingram

As the title says really. I've had a look at inheriting from TextBox, but the only sensible override was "OnKeyDown", but that just gives me a key from the Key enum (with no way to use Char.IsNumeric()).

正如标题所说的那样。我看过从 TextBox 继承,但唯一合理的覆盖是“OnKeyDown”,但这只是从 Key 枚举中给我一个键(无法使用 Char.IsNumeric())。

采纳答案by Tim Heuer

Take a look at NumericUpDown in the Toolkit http://codeplex.com/Silverlightand maybe you can use that or look at the source to implement your own numeric textbox.

看看 Toolkit http://codeplex.com/Silverlight中的 NumericUpDown,也许您可以使用它或查看源代码来实现您自己的数字文本框。

回答by jgarza

Take a look at this one, it uses an attached property over the textbox. I am using it and it does work. http://weblogs.asp.net/manishdalal/archive/2008/09/24/prevention-the-first-line-of-defense-with-attach-property-pixie-dust.aspx

看看这个,它在文本框上使用附加属性。我正在使用它,它确实有效。 http://weblogs.asp.net/manishdalal/archive/2008/09/24/prevention-the-first-line-of-defense-with-attach-property-pixie-dust.aspx

回答by Nidhal

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

回答by amurra

I took Nidhal's suggested answer and edited it a bit to handle the shift case for the characters above the digits (ie. !@#$%^&*()) since that solution will still allow those characters in the textbox.

我接受了 Nidhal 的建议答案并对其进行了一些编辑,以处理数字上方字符的转换大小写(即 !@#$%^&*()),因为该解决方案仍将允许文本框中的这些字符。

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

回答by Emy

It works:

有用:

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

回答by Nauman

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

回答by Ross Brigoli

Extend the normal Silverlight Textbox control. Add this code inside the extended TextBox class:

扩展正常的 Silverlight 文本框控件。在扩展的 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;

}

回答by Sameh Deabes

I know it has been answered, but I found no proper solution that handles all special cases, most answers here swallows some important keys like Home, End, Tab, Shift+ any thing, ..etc.

我知道已经回答了,但我没有找到处理所有特殊情况的正确解决方案,这里的大多数答案都吞下了一些重要的键,如 Home、End、Tab、Shift+ 任何东西等等。

So, I developed my own implementation as it may help somebody!

所以,我开发了自己的实现,因为它可能对某人有所帮助!

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

The above code has a single disadvantage, TextChanged event will be raised frequently, but since we need an integertextbox, then we can rely on ValueChangedinstead!

上面的代码有一个缺点,TextChanged 事件会频繁引发,但是既然我们需要一个integer文本框,那么我们可以依靠ValueChanged

回答by Jerry Nixon

Why is everyone not doing the hard work of just handling them all?

为什么不是每个人都在努力处理它们?

Here (this is perfection):

在这里(这是完美的):

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

}

}

回答by xidius

Visit http://www.dataartist.net/blog/post/Silverlight-Behavior-Modifications-13-NumericOnlyBehavior.aspxor use TextBox behavior as below

访问http://www.dataartist.net/blog/post/Silverlight-Behavior-Modifications-13-NumericOnlyBehavior.aspx或使用如下的 TextBox 行为

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