Only allow specific characters in textbox

后端 未结 6 720
走了就别回头了
走了就别回头了 2020-12-01 21:17

How can I only allow certain characters in a Visual C# textbox? Users should be able to input the following characters into a text box, and everything else should be blocked

相关标签:
6条回答
  • 2020-12-01 21:23

    As mentioned in a comment (and another answer as I typed) you need to register an event handler to catch the keydown or keypress event on a text box. This is because TextChanged is only fired when the TextBox loses focus

    The below regex lets you match those characters you want to allow

    Regex regex = new Regex(@"[0-9+\-\/\*\(\)]");
    MatchCollection matches = regex.Matches(textValue);
    

    and this does the opposite and catches characters that aren't allowed

    Regex regex = new Regex(@"[^0-9^+^\-^\/^\*^\(^\)]");
    MatchCollection matches = regex.Matches(textValue);
    

    I'm not assuming there'll be a single match as someone could paste text into the textbox. in which case catch textchanged

    textBox1.TextChanged += new TextChangedEventHandler(textBox1_TextChanged);
    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        Regex regex = new Regex(@"[^0-9^+^\-^\/^\*^\(^\)]");
        MatchCollection matches = regex.Matches(textBox1.Text);
        if (matches.Count > 0) {
           //tell the user
        }
    }
    

    and to validate single key presses

    textBox1.KeyPress += new KeyPressEventHandler(textBox1_KeyPress);
    private void textBox1_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
    {
        // Check for a naughty character in the KeyDown event.
        if (System.Text.RegularExpressions.Regex.IsMatch(e.KeyChar.ToString(), @"[^0-9^+^\-^\/^\*^\(^\)]"))
        {
            // Stop the character from being entered into the control since it is illegal.
            e.Handled = true;
        }
    }
    
    0 讨论(0)
  • 2020-12-01 21:29

    For your validation event IMO the easiest method would be to use a character array to validate textbox characters against. True - iterating and validating isn't particularly efficient, but it is straightforward.

    Alternately, use a regular expression of your whitelist characters against the input string. Your events are availalbe at MSDN here: http://msdn.microsoft.com/en-us/library/system.windows.forms.control.lostfocus.aspx

    0 讨论(0)
  • 2020-12-01 21:33
        private void txtuser_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!char.IsLetter(e.KeyChar) && !char.IsWhiteSpace(e.KeyChar) && !char.IsControl(e.KeyChar))
            {
                e.Handled = true;
            }
        }
    
    0 讨论(0)
  • 2020-12-01 21:35

    You need to subscribe to the KeyDown event on the text box. Then something like this:

    private void textBox1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
    {
        if (!char.IsControl(e.KeyChar) 
           && !char.IsDigit(e.KeyChar) 
           && e.KeyChar != '.' && e.KeyChar != '+' && e.KeyChar != '-'
           && e.KeyChar != '(' && e.KeyChar != ')' && e.KeyChar != '*' 
           && e.KeyChar != '/')
        {
            e.Handled = true;
            return;
        }
        e.Handled=false;
        return;
    }
    

    The important thing to know is that if you changed the Handled property to true, it will not process the keystroke. Setting it to false will.

    0 讨论(0)
  • 2020-12-01 21:39

    Intercept the KeyPressed event is in my opinion a good solid solution. Pay attention to trigger code characters (e.KeyChar lower then 32) if you use a RegExp.

    But in this way is still possible to inject characters out of range whenever the user paste text from the clipboard. Unfortunately I did not found correct clipboard events to fix this.

    So a waterproof solution is to intercept TextBox.TextChanged. Here is sometimes the original out of range character visible, for a short time. I recommend to implement both.

    using System.Text.RegularExpressions;

    private void Form1_Shown(object sender, EventArgs e)
    {
        filterTextBoxContent(textBox1);
    }
    
    
    string pattern = @"[^0-9^+^\-^/^*^(^)]";
    
    private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
        if(e.KeyChar >= 32 && Regex.Match(e.KeyChar.ToString(), pattern).Success) { e.Handled = true; }
    }
    
    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        filterTextBoxContent(textBox1);
    }
    
    private bool filterTextBoxContent(TextBox textBox)
    {
        string text = textBox.Text;
    
        MatchCollection matches = Regex.Matches(text, pattern);
        bool matched = false;
    
        int selectionStart = textBox.SelectionStart;
        int selectionLength = textBox.SelectionLength;
    
        int leftShift = 0;
        foreach (Match match in matches)
        {
            if (match.Success && match.Captures.Count > 0)
            {
                matched = true;
                Capture capture = match.Captures[0];
    
                int captureLength = capture.Length;
                int captureStart = capture.Index - leftShift;
                int captureEnd = captureStart + captureLength;
    
                int selectionEnd = selectionStart + selectionLength;
    
                text = text.Substring(0, captureStart) + text.Substring(captureEnd, text.Length - captureEnd);
    
                textBox.Text = text;
    
                int boundSelectionStart = selectionStart < captureStart ? -1 : (selectionStart < captureEnd ? 0 : 1);
                int boundSelectionEnd = selectionEnd < captureStart ? -1 : (selectionEnd < captureEnd ? 0 : 1);
    
                if (boundSelectionStart == -1)
                {
                    if (boundSelectionEnd == 0)
                    {
                        selectionLength -= selectionEnd - captureStart;
                    }
                    else if (boundSelectionEnd == 1)
                    {
                        selectionLength -= captureLength;
                    }
                }
                else if (boundSelectionStart == 0)
                {
                    if (boundSelectionEnd == 0)
                    {
                        selectionStart = captureStart;
                        selectionLength = 0;
                    }
                    else if (boundSelectionEnd == 1)
                    {
                        selectionStart = captureStart;
                        selectionLength -= captureEnd - selectionStart;
                    }
                }
                else if (boundSelectionStart == 1)
                {
                    selectionStart -= captureLength;
                }
    
                leftShift++;
            }
        }
    
        textBox.SelectionStart = selectionStart;
        textBox.SelectionLength = selectionLength;
    
        return matched;
    }
    
    0 讨论(0)
  • 2020-12-01 21:45

    You can probably use the KeyDown event, KeyPress event or KeyUp event. I would first try the KeyDown event I think.

    You can set the Handled property of the event args to stop handling the event.

    0 讨论(0)
提交回复
热议问题