简体   繁体   English

如何设置TextBox只接受数字?

[英]How to set TextBox to only accept numbers?

I have already checked other questions here but the answers are not related to my issue. 我已经在这里检查了其他问题,但答案与我的问题无关。 the following code allows textbox1 to only accept numbers if the physical keyboard (laptop) is pressed: 以下代码允许textbox1仅在按下物理键盘(笔记本电脑)时接受数字:

private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
        char ch = e.KeyChar;
        if ( !char.IsDigit(ch))
        {

            e.Handled = true;
        }
    }

but this is not what I wanted (I dont use physical laptop keyboard). 但这不是我想要的(我不使用物理笔记本电脑键盘)。

屏幕截图

As shown in screenshot, I have windows form with buttons and a textbox. 如屏幕截图所示,我具有带有按钮和文本框的Windows窗体。 I designed this keyboard and it works well but I want textbox1 to only accept numbers and the ".". 我设计了此键盘,它工作良好,但我希望textbox1只接受数字和“。”。

There are only two lines of code inside each button (and only code in the project) which is: 每个按钮(并且项目中只有代码)内只有两行代码,它们是:

private void buttonName_Click(object sender, EventArgs e)
    {    
         // each button only has this code.

         textBox1.Focus();
         SendKeys.Send(buttonName.Text);  
    }

I know how to set txtbox to accept numbers if the physical (laptop ) keys are pressed but here in this case I have control buttons in windwos form and I want to set textBox1 to only accept numbers and the ".". 我知道如何在按下物理(笔记本电脑)键的情况下将txtbox设置为接受数字,但是在这种情况下,我以windwos形式具有控制按钮,并且我希望将textBox1设置为仅接受数字和“。”。 Please help in how to achieve this. 请帮助如何实现这一目标。 Thank you 谢谢

Declare a string variable at form level, use it to store the last valid text and to restore it when an invalid text is entered on the TextChanged event of your textbox. 在表单级别声明一个字符串变量,使用它存储最后一个有效文本,并在文本框的TextChanged事件上输入无效文本时将其还原。

string previousText;

public Form1()
{
    InitializeComponent();
    previousText = String.Empty;
}

private void textBox1_TextChanged(object sender, EventArgs e)
{
    int dummy, changeLenght, position;
    if (!String.IsNullOrWhiteSpace(textBox1.Text) && !int.TryParse(textBox1.Text, out dummy))
    {
        position = textBox1.SelectionStart;
        changeLenght = textBox1.TextLength - previousText.Length;
        textBox1.Text = previousText;
        textBox1.SelectionStart = position - changeLenght;
    }
    else
    {
        previousText = textBox1.Text;
    }
}

position and changeLenght are used to keep the cursor where it was before restoring the text. positionchangeLenght用于将光标保留在还原文本之前的位置。

In case you want to accept numbers with decimals or something bigger than 2147483647, just change dummy to double and use double.TryParse instead of int.TryParse . 如果您想接受带小数或大于2147483647的数字,只需将dummy更改为double并使用double.TryParse而不是int.TryParse

private void textBox1_TextChanged(object sender, EventArgs e)
{
    int changeLenght, position;
    double dummy;
    if (!String.IsNullOrWhiteSpace(textBox1.Text) && !double.TryParse(textBox1.Text, out dummy))
    {
        ...
    }
}

Suppose button1 is your button control, you could do this: 假设button1是您的按钮控件,则可以执行以下操作:

private void allButtons_Click(object sender, EventArgs e)
{  
    Button btn = sender as Button;
    char c = btn.Text[0]; //assuming all buttons have exactly 1 character
    if(Char.IsDigit(c) || c == '.')
    {
        //process
        textBox1.Focus();
        SendKeys.Send(btn.Text);
    }
    //otherwise don't
}

I'm assuming you put this in a common handler, to which you already wired all your buttons (ie allButtons_Click ). 我假设您将其放在一个通用处理程序中,您已经将所有按钮(即allButtons_Click )连接到该处理程序。

Problem with this approach, it allows you to type values like 0.0.1 , which are most likely invalid in your context. 这种方法存在问题,它允许您键入0.0.1类的值,这些值很可能在您的上下文中无效。 Another way to handle this is to process TextChanged event, store previous value, and if new value is invalid, restore the old one. 解决此问题的另一种方法是处理TextChanged事件,存储先前的值,如果新值无效,则还原旧值。 Unfortunately, TextBox class does not have TextChanging event, which could be a cleaner option. 不幸的是,TextBox类没有TextChanging事件,这可能是一个更干净的选择。

The benefit of you determining the invalid value is modularity. 确定无效值的好处是模块化。 For example, if you later decide your user can enter any value, but only numbers can pass validation, you could move your check from TextChanged to Validate button click or similar. 例如,如果您以后决定用户可以输入任何值,但是只有数字可以通过验证,则可以将检查从TextChanged移到Validate按钮单击或类似操作。

Why users may want that - suppose one of the options for input is copy/paste - they want to paste invalid data and edit it to become valid, for example abc123.5 . 为什么用户可能想要这样做-假设输入的选项之一是复制/粘贴-他们想粘贴无效的数据并对其进行编辑以变得有效,例如abc123.5 If you limit them at the entry, this value will not be there at all, so they now need to manually paste into Notepad, cut out in the invalid characters, and paste again, which goes against productivity. 如果将它们限制在条目中,则此值将根本不存在,因此,现在需要将它们手动粘贴到记事本中,切出无效字符,然后再次粘贴,这会影响生产率。

Generally, before implementing any user interface limitation, read "I won't allow my user to...", think well, whether it's justified enough. 通常,在实施任何用户界面限制之前,请阅读“我不会允许我的用户...”,请仔细考虑一下是否足够。 More often than not, you don't need to limit the user, even for the good purpose of keeping your DB valid etc. If possible, never put a concrete wall in front of them, you just need to guide them correctly through your workflow. 通常,即使出于保持数据库有效的良好目的,也不需要限制用户。如果可能的话,永远不要在其前面放一堵混凝土墙,您只需要在工作流程中正确地指导他们即可。 You want users on your side, not against you. 您希望用户站在您一边,而不是反对您。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM