How to create a numeric textbox in Silverlight?

2019-01-23 15:53发布

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()).

11条回答
SAY GOODBYE
2楼-- · 2019-01-23 16:07

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

查看更多
叼着烟拽天下
3楼-- · 2019-01-23 16:12

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.

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 integer textbox, then we can rely on ValueChanged instead!

查看更多
4楼-- · 2019-01-23 16:17
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;
}
查看更多
叼着烟拽天下
5楼-- · 2019-01-23 16:22

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

查看更多
虎瘦雄心在
6楼-- · 2019-01-23 16:23

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

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;

}
查看更多
Fickle 薄情
7楼-- · 2019-01-23 16:24

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;
            }
        }
    }       
}
查看更多
登录 后发表回答