需要一个仅限数字的 Windows 控件 TextBox

发布于 2024-09-26 12:49:44 字数 102 浏览 8 评论 0原文

我正在使用 System.Windows.Controls.TextBox 在 c# 中创建一个老式对话框。 有没有一种简单的方法可以将此框中的文本输入限制为仅数字?

谢谢!

I am creating an old-school dialog in c# using a System.Windows.Controls.TextBox .
Is there an easy way of limiting text input in this box to numeric only?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

绮烟 2024-10-03 12:49:44

只需实现 onkeyup 事件处理程序,如果按下的键不是 Character.IsDigit 则清除它。

http://msdn。 microsoft.com/en-us/library/system.windows.controls.textbox.onkeyup(VS.95).aspx

Just implement the onkeyup event handler and if the key pressed is not a Character.IsDigit then clear it.

http://msdn.microsoft.com/en-us/library/system.windows.controls.textbox.onkeyup(VS.95).aspx

孤独陪着我 2024-10-03 12:49:44

您可以考虑使用 MaskedTextBox,设置相应地 屏蔽 属性。

You could consider using a MaskedTextBox, setting the Mask property accordingly.

沧笙踏歌 2024-10-03 12:49:44

这是摘自 我对之前问题的回答


将此类添加到您的项目中

using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
public class TextBoxFilter
{
    [Flags()]
    public enum Filters
    {
        None = 0,
        Text = 1,
        Numbers = 2,
        AlphaNumeric = Filters.Text | Filters.Numbers,
        Currency = 4,
        All = Filters.Text | Filters.Numbers | Filters.Currency
    }

    Dictionary<TextBox, Filters> _keyFilter;
    Dictionary<TextBox, string> _allowedKeys;
    Dictionary<TextBox, string> _invalidKeys;

    Dictionary<TextBox, Windows.Forms.KeyEventArgs> keyEventArgs;
    private static string DecimalMark = Application.CurrentCulture.NumberFormat.NumberDecimalSeparator;
    private static string NegativeMark = Application.CurrentCulture.NumberFormat.NegativeSign;
    private static string CurrencySymb = Application.CurrentCulture.NumberFormat.CurrencySymbol;

    private static string CurrencyDecimal = Application.CurrentCulture.NumberFormat.CurrencyDecimalSeparator;

    public TextBoxFilter()
    {
        _keyFilter = new Dictionary<TextBox, Filters>();
        _allowedKeys = new Dictionary<TextBox, string>();
        _invalidKeys = new Dictionary<TextBox, string>();
        keyEventArgs = new Dictionary<TextBox, KeyEventArgs>();
    }

//set & remove filter

    public void SetTextBoxFilter(TextBox textBox, Filters filter)
    {
        SetTextBoxFilter(textBox, filter, AllowedKeys(textBox), InvalidKeys(textBox));
    }

    public void SetTextBoxFilter(TextBox textBox, string allowedKeys)
    {
        SetTextBoxFilter(textBox, Strings.Filter(textBox), allowedKeys, InvalidKeys(textBox));
    }


    public void SetTextBoxFilter(TextBox textBox, string allowedKeys, string invalidKeys)
    {
        SetTextBoxFilter(textBox, Strings.Filter(textBox), allowedKeys, invalidKeys);
    }


    public void SetTextBoxFilter(TextBox textBox, Filters filter, string allowedKeys, string invalidKeys)
    {
        if (!_keyFilter.ContainsKey(textBox)) {
            //add the textbox and its filter if it does not exist in 
            //the collection of registered textboxes
            _keyFilter.Add(textBox, filter);
            _allowedKeys.Add(textBox, allowedKeys);
            _invalidKeys.Add(textBox, invalidKeys);
            keyEventArgs.Add(textBox, new System.Windows.Forms.KeyEventArgs(Keys.None));

            //add the event handlers
            textBox.KeyDown += KeyDownUp;
            textBox.KeyUp += KeyDownUp;
            textBox.KeyPress += KeyPress;
            textBox.Validating += Validating;
            textBox.Disposed += Disposed;

        } else {
            //change the filter of the textbox if it exists in
            //the collection of registered textboxes
            _keyFilter(textBox) = filter;
            _allowedKeys(textBox) = allowedKeys;
            _invalidKeys(textBox) = invalidKeys;
        }
    }

    public void RemoveTextBoxFilter(TextBox textBox)
    {
        if (_keyFilter.ContainsKey(textBox)) {
            _keyFilter.Remove(textBox);
            _allowedKeys.Remove(textBox);
            _invalidKeys.Remove(textBox);
            keyEventArgs.Remove(textBox);

            textBox.KeyDown -= KeyDownUp;
            textBox.KeyUp -= KeyDownUp;
            textBox.KeyPress -= KeyPress;
            textBox.Validating -= Validating;
            textBox.Disposed -= Disposed;
        }
    }

    public bool ContainsTextBox(TextBox textBox)
    {
        return _keyFilter.ContainsKey(textBox);
    }

//properties

    public Filters Filter {
        get {
            if (ContainsTextBox(textBox)) {
                return _keyFilter.Item[textBox];
            } else {
                return Filters.None;
            }
        }
        set { SetTextBoxFilter(textBox, value); }
    }

    public string AllowedKeys {
        get {
            if (ContainsTextBox(textBox)) {
                return _allowedKeys(textBox);
            } else {
                return "";
            }
        }
        set { SetTextBoxFilter(textBox, this.Filter(textBox), value, this.InvalidKeys(textBox)); }
    }

    public string InvalidKeys {
        get {
            if (ContainsTextBox(textBox)) {
                return _invalidKeys(textBox);
            } else {
                return "";
            }
        }
        set { SetTextBoxFilter(textBox, this.Filter(textBox), this.AllowedKeys(textBox), value); }
    }

//event handlers

    private void Disposed(object sender, System.EventArgs e)
    {
        RemoveTextBoxFilter((TextBox)sender);
    }

    private void KeyDownUp(object sender, System.Windows.Forms.KeyEventArgs e)
    {
        //assign the modifiers
        keyEventArgs((TextBox)sender) = e;
    }

    private void KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
    {
        //ensure key pressed is in the allowed keys

        object txt = (TextBox)sender;
        object c = e.KeyChar;
        bool allowKey = IsValidChar(txt, c, txt.SelectionStart);


        //check for backspace & Ctrl combinations if the allowKey is still false
        if (allowKey == false) {
            if (keyEventArgs(txt).Control) {
                //control modifier goes with A, X, C, V and Z for 
                //Select All, Cut, Copy, Paste and Undo respectively
                object key = keyEventArgs(txt).KeyCode;
                allowKey = (key == Keys.A || key == Keys.X || key == Keys.C || key == Keys.V || key == Keys.Z);

            } else if (keyEventArgs(txt).KeyCode == Keys.Back) {
                //allow the backspace key
                allowKey = true;
            }
        }


        //disable the key if it was not valid
        if (!allowKey) {
            e.Handled = true;
            Interaction.Beep();
        }
    }

    private void Validating(object sender, System.ComponentModel.CancelEventArgs e)
    {
        object box = (TextBox)sender;
        object boxFlags = _keyFilter(box);

        //skip validation if the textbox allows all entries or there is no text
        if (boxFlags == Filters.All | string.IsNullOrEmpty(box.Text))
            return;

        //otherwise check the characters entered
        object txtChars = box.Text.ToCharArray;

        bool isValidEntry = false;

        //check each caracter for an invalid entry
        for (i = 0; i <= txtChars.Length - 1; i++) {
            object c = txtChars(i);
            isValidEntry = IsValidChar(box, txtChars(i), i);

            if (!isValidEntry) {
                box.Select(i, 1);
                break; // TODO: might not be correct. Was : Exit For
            }
        }

        if (!isValidEntry)
            e.Cancel = true;

        if (!isValidEntry) {
            Interaction.MsgBox("The text entered is invalid for the format " + boxFlags.ToString + "." + !string.IsNullOrEmpty(_allowedKeys(box)) ? Constants.vbCrLf + "Additional Allowed Keys: " + _allowedKeys(box) : "" + !string.IsNullOrEmpty(_invalidKeys(box)) ? Constants.vbCrLf + "Additional Invalid Keys: " + _invalidKeys(box) : "", MsgBoxStyle.Critical, "Invalid Entry");
        }
    }

    private bool IsValidChar(TextBox textBox, char c, int charIndex)
    {
        //ensure key pressed is in the allowed keys

        object pF = _keyFilter(textBox);
        object aK = _allowedKeys(textBox);
        object iK = _invalidKeys(textBox);
        bool shouldAllow = false;


        //if filter is set to all, return true unconditionally
        if (pF == Filters.All)
            return true;


        //check preset filters

        //check for text
        if (EnumHasFlag(pF, Filters.Text)) {
            if (!char.IsDigit(c)) {
                shouldAllow = true;
            } else {
                //if the character is a digit, check for the number flag (AlphaNumerics)
                if (EnumHasFlag(pF, Filters.Numbers)) {
                    shouldAllow = true;
                }
            }

        }

        //check for nubers
        if (shouldAllow == false && EnumHasFlag(pF, Filters.Numbers)) {
            if (char.IsDigit(c)) {
                shouldAllow = true;
            } else if (DecimalMark.Contains(c)) {
                //allow the decimal if there is no decimal in the textbox's
                //text or the selected text contains the mark
                if (!textBox.Text.Substring(0, charIndex).Contains(c) || textBox.SelectedText.Contains(c)) {
                    shouldAllow = true;
                }
            } else if (NegativeMark.Contains(c) && (charIndex <= NegativeMark.IndexOf(c))) {
                //allow the negative mark if we are at the start of the
                //textbox
                shouldAllow = true;
            }

        }

        //check for currency
        if (shouldAllow == false && EnumHasFlag(pF, Filters.Currency)) {
            if (char.IsDigit(c)) {
                shouldAllow = true;
            } else if (CurrencyDecimal.Contains(c)) {
                //allow the currency decimal mark if it does not exist in the
                //textbox's text or the selected text contains the mark
                if (!textBox.Text.Substring(0, charIndex).Contains(c) || textBox.SelectedText.Contains(c)) {
                    shouldAllow = true;
                }
            } else if (CurrencySymb.Contains(c) && (charIndex <= CurrencySymb.IndexOf(c))) {
                //allow the currency symbol if we are in a valid position
                shouldAllow = true;
            }

        }



        //now check for extra allowed keys
        if (!shouldAllow) {
            shouldAllow = aK.Contains(c);
        }

        //and then check for extra invalid keys
        if (shouldAllow && iK.Contains(c)) {
            shouldAllow = false;
        }


        return shouldAllow;
    }

    [System.Diagnostics.DebuggerStepThrough()]
    private bool EnumHasFlag(Enum value, Enum flag)
    {
        return (Convert.ToInt64(value) & Convert.ToInt64(flag)) == Convert.ToInt64(flag);
    }
}

,然后在您的表单中使用它,如下所示

public class Form1
{


    TextBoxFilter filter = new TextBoxFilter();
    private void Form1_Load(object sender, System.EventArgs e)
    {
        filter.SetTextBoxFilter(TextBox1, TextBoxFilter.Filters.Numbers);
    }
    public Form1()
    {
        Load += Form1_Load;
    }
}

This is an extract from my answer to an earlier question.


Add this class to your project

using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
public class TextBoxFilter
{
    [Flags()]
    public enum Filters
    {
        None = 0,
        Text = 1,
        Numbers = 2,
        AlphaNumeric = Filters.Text | Filters.Numbers,
        Currency = 4,
        All = Filters.Text | Filters.Numbers | Filters.Currency
    }

    Dictionary<TextBox, Filters> _keyFilter;
    Dictionary<TextBox, string> _allowedKeys;
    Dictionary<TextBox, string> _invalidKeys;

    Dictionary<TextBox, Windows.Forms.KeyEventArgs> keyEventArgs;
    private static string DecimalMark = Application.CurrentCulture.NumberFormat.NumberDecimalSeparator;
    private static string NegativeMark = Application.CurrentCulture.NumberFormat.NegativeSign;
    private static string CurrencySymb = Application.CurrentCulture.NumberFormat.CurrencySymbol;

    private static string CurrencyDecimal = Application.CurrentCulture.NumberFormat.CurrencyDecimalSeparator;

    public TextBoxFilter()
    {
        _keyFilter = new Dictionary<TextBox, Filters>();
        _allowedKeys = new Dictionary<TextBox, string>();
        _invalidKeys = new Dictionary<TextBox, string>();
        keyEventArgs = new Dictionary<TextBox, KeyEventArgs>();
    }

//set & remove filter

    public void SetTextBoxFilter(TextBox textBox, Filters filter)
    {
        SetTextBoxFilter(textBox, filter, AllowedKeys(textBox), InvalidKeys(textBox));
    }

    public void SetTextBoxFilter(TextBox textBox, string allowedKeys)
    {
        SetTextBoxFilter(textBox, Strings.Filter(textBox), allowedKeys, InvalidKeys(textBox));
    }


    public void SetTextBoxFilter(TextBox textBox, string allowedKeys, string invalidKeys)
    {
        SetTextBoxFilter(textBox, Strings.Filter(textBox), allowedKeys, invalidKeys);
    }


    public void SetTextBoxFilter(TextBox textBox, Filters filter, string allowedKeys, string invalidKeys)
    {
        if (!_keyFilter.ContainsKey(textBox)) {
            //add the textbox and its filter if it does not exist in 
            //the collection of registered textboxes
            _keyFilter.Add(textBox, filter);
            _allowedKeys.Add(textBox, allowedKeys);
            _invalidKeys.Add(textBox, invalidKeys);
            keyEventArgs.Add(textBox, new System.Windows.Forms.KeyEventArgs(Keys.None));

            //add the event handlers
            textBox.KeyDown += KeyDownUp;
            textBox.KeyUp += KeyDownUp;
            textBox.KeyPress += KeyPress;
            textBox.Validating += Validating;
            textBox.Disposed += Disposed;

        } else {
            //change the filter of the textbox if it exists in
            //the collection of registered textboxes
            _keyFilter(textBox) = filter;
            _allowedKeys(textBox) = allowedKeys;
            _invalidKeys(textBox) = invalidKeys;
        }
    }

    public void RemoveTextBoxFilter(TextBox textBox)
    {
        if (_keyFilter.ContainsKey(textBox)) {
            _keyFilter.Remove(textBox);
            _allowedKeys.Remove(textBox);
            _invalidKeys.Remove(textBox);
            keyEventArgs.Remove(textBox);

            textBox.KeyDown -= KeyDownUp;
            textBox.KeyUp -= KeyDownUp;
            textBox.KeyPress -= KeyPress;
            textBox.Validating -= Validating;
            textBox.Disposed -= Disposed;
        }
    }

    public bool ContainsTextBox(TextBox textBox)
    {
        return _keyFilter.ContainsKey(textBox);
    }

//properties

    public Filters Filter {
        get {
            if (ContainsTextBox(textBox)) {
                return _keyFilter.Item[textBox];
            } else {
                return Filters.None;
            }
        }
        set { SetTextBoxFilter(textBox, value); }
    }

    public string AllowedKeys {
        get {
            if (ContainsTextBox(textBox)) {
                return _allowedKeys(textBox);
            } else {
                return "";
            }
        }
        set { SetTextBoxFilter(textBox, this.Filter(textBox), value, this.InvalidKeys(textBox)); }
    }

    public string InvalidKeys {
        get {
            if (ContainsTextBox(textBox)) {
                return _invalidKeys(textBox);
            } else {
                return "";
            }
        }
        set { SetTextBoxFilter(textBox, this.Filter(textBox), this.AllowedKeys(textBox), value); }
    }

//event handlers

    private void Disposed(object sender, System.EventArgs e)
    {
        RemoveTextBoxFilter((TextBox)sender);
    }

    private void KeyDownUp(object sender, System.Windows.Forms.KeyEventArgs e)
    {
        //assign the modifiers
        keyEventArgs((TextBox)sender) = e;
    }

    private void KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
    {
        //ensure key pressed is in the allowed keys

        object txt = (TextBox)sender;
        object c = e.KeyChar;
        bool allowKey = IsValidChar(txt, c, txt.SelectionStart);


        //check for backspace & Ctrl combinations if the allowKey is still false
        if (allowKey == false) {
            if (keyEventArgs(txt).Control) {
                //control modifier goes with A, X, C, V and Z for 
                //Select All, Cut, Copy, Paste and Undo respectively
                object key = keyEventArgs(txt).KeyCode;
                allowKey = (key == Keys.A || key == Keys.X || key == Keys.C || key == Keys.V || key == Keys.Z);

            } else if (keyEventArgs(txt).KeyCode == Keys.Back) {
                //allow the backspace key
                allowKey = true;
            }
        }


        //disable the key if it was not valid
        if (!allowKey) {
            e.Handled = true;
            Interaction.Beep();
        }
    }

    private void Validating(object sender, System.ComponentModel.CancelEventArgs e)
    {
        object box = (TextBox)sender;
        object boxFlags = _keyFilter(box);

        //skip validation if the textbox allows all entries or there is no text
        if (boxFlags == Filters.All | string.IsNullOrEmpty(box.Text))
            return;

        //otherwise check the characters entered
        object txtChars = box.Text.ToCharArray;

        bool isValidEntry = false;

        //check each caracter for an invalid entry
        for (i = 0; i <= txtChars.Length - 1; i++) {
            object c = txtChars(i);
            isValidEntry = IsValidChar(box, txtChars(i), i);

            if (!isValidEntry) {
                box.Select(i, 1);
                break; // TODO: might not be correct. Was : Exit For
            }
        }

        if (!isValidEntry)
            e.Cancel = true;

        if (!isValidEntry) {
            Interaction.MsgBox("The text entered is invalid for the format " + boxFlags.ToString + "." + !string.IsNullOrEmpty(_allowedKeys(box)) ? Constants.vbCrLf + "Additional Allowed Keys: " + _allowedKeys(box) : "" + !string.IsNullOrEmpty(_invalidKeys(box)) ? Constants.vbCrLf + "Additional Invalid Keys: " + _invalidKeys(box) : "", MsgBoxStyle.Critical, "Invalid Entry");
        }
    }

    private bool IsValidChar(TextBox textBox, char c, int charIndex)
    {
        //ensure key pressed is in the allowed keys

        object pF = _keyFilter(textBox);
        object aK = _allowedKeys(textBox);
        object iK = _invalidKeys(textBox);
        bool shouldAllow = false;


        //if filter is set to all, return true unconditionally
        if (pF == Filters.All)
            return true;


        //check preset filters

        //check for text
        if (EnumHasFlag(pF, Filters.Text)) {
            if (!char.IsDigit(c)) {
                shouldAllow = true;
            } else {
                //if the character is a digit, check for the number flag (AlphaNumerics)
                if (EnumHasFlag(pF, Filters.Numbers)) {
                    shouldAllow = true;
                }
            }

        }

        //check for nubers
        if (shouldAllow == false && EnumHasFlag(pF, Filters.Numbers)) {
            if (char.IsDigit(c)) {
                shouldAllow = true;
            } else if (DecimalMark.Contains(c)) {
                //allow the decimal if there is no decimal in the textbox's
                //text or the selected text contains the mark
                if (!textBox.Text.Substring(0, charIndex).Contains(c) || textBox.SelectedText.Contains(c)) {
                    shouldAllow = true;
                }
            } else if (NegativeMark.Contains(c) && (charIndex <= NegativeMark.IndexOf(c))) {
                //allow the negative mark if we are at the start of the
                //textbox
                shouldAllow = true;
            }

        }

        //check for currency
        if (shouldAllow == false && EnumHasFlag(pF, Filters.Currency)) {
            if (char.IsDigit(c)) {
                shouldAllow = true;
            } else if (CurrencyDecimal.Contains(c)) {
                //allow the currency decimal mark if it does not exist in the
                //textbox's text or the selected text contains the mark
                if (!textBox.Text.Substring(0, charIndex).Contains(c) || textBox.SelectedText.Contains(c)) {
                    shouldAllow = true;
                }
            } else if (CurrencySymb.Contains(c) && (charIndex <= CurrencySymb.IndexOf(c))) {
                //allow the currency symbol if we are in a valid position
                shouldAllow = true;
            }

        }



        //now check for extra allowed keys
        if (!shouldAllow) {
            shouldAllow = aK.Contains(c);
        }

        //and then check for extra invalid keys
        if (shouldAllow && iK.Contains(c)) {
            shouldAllow = false;
        }


        return shouldAllow;
    }

    [System.Diagnostics.DebuggerStepThrough()]
    private bool EnumHasFlag(Enum value, Enum flag)
    {
        return (Convert.ToInt64(value) & Convert.ToInt64(flag)) == Convert.ToInt64(flag);
    }
}

and then use it in your form as follows

public class Form1
{


    TextBoxFilter filter = new TextBoxFilter();
    private void Form1_Load(object sender, System.EventArgs e)
    {
        filter.SetTextBoxFilter(TextBox1, TextBoxFilter.Filters.Numbers);
    }
    public Form1()
    {
        Load += Form1_Load;
    }
}
转瞬即逝 2024-10-03 12:49:44

还要考虑您的设计是否需要在键入/粘贴时限制用户输入,或者是否可以在用户离开文本框时将用户输入简单地转换为数字。

通常,限制性方法更难做到(处理逗号、句点、货币符号、空格等......可能是一个巨大的痛苦),

然后这种方法变得简单如下:

private void textBox1_Leave(object sender, EventArgs e)
{
    textBox1.Text = VerifyNumeric(textBox1.Text);
}

private string VerifyNumeric(string text)
{
    double value = 0;
    double.TryParse(text, out value);
    return value.ToString(); // could format here too.
}

Also consider whether your design needs to restrict user input when typed/pasted or if it's OK to simply convert the user input to a number when he leaves the textbox.

Often the restrictive approach is harder to do (dealing with commas, periods, currency symbols, spaces, etc... can be a huge pain)

This method then becomes as simple as:

private void textBox1_Leave(object sender, EventArgs e)
{
    textBox1.Text = VerifyNumeric(textBox1.Text);
}

private string VerifyNumeric(string text)
{
    double value = 0;
    double.TryParse(text, out value);
    return value.ToString(); // could format here too.
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文