'How to limit textbox to accept only specific characters

I wanted to know How to limit number of specific character of a textbox in c# form application. for example i want to limit the user to enter - (minus) only one time and then if he try to input again I want the program to restrict inputing that again.

Examples: -123 or 123- or 123-123 (only one -).

If user remove - then should have permission to input one - again and of course no more!

I want to prevent user to enter ----1234 or 1234--, or 123-4--21 or what more you think!!

Here is what I'm trying:

private void txtStopAfterXTimes_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.OemMinus || e.KeyCode == Keys.Subtract)
    {
        if (txtStopAfterXTimes.Text.Count((char)'-', 1))
        {
            e.SuppressKeyPress = true;
        }
        else if (txtStopAfterXTimes.Text.Count((char)'-', 0))
        {
            e.SuppressKeyPress = false;
        }
    }
}

i know it's wrong but please help! thank you...



Solution 1:[1]

I'd avoid using TextChanged because it will be raised after the text has changed and it may be a bit late.

This is the solution which I will use, because you also need to care about paste.

  • On keyPress I check if the character is not the first "-", then I'll ignore it, otherwise I'll accept it.
  • On WndProc I catch WM_PASTE and sanitize the clipboard text, by removing all occurrences of "-" but the first one. You can also easily decide to stop pasting if the input is not acceptable.

Here is the implementation:

using System.Runtime.InteropServices;
using System.Windows.Forms;
public class MyTextBox : TextBox
{
    private const int WM_PASTE = 0x0302;
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern bool MessageBeep(int type);
    protected override void WndProc(ref Message m)
    {
        if (m.Msg != WM_PASTE) { base.WndProc(ref m); }
        else {
            //You can sanitize the input or even stop pasting the input
            var text = SanitizeText(Clipboard.GetText());
            SelectedText = text;
        }
    }
    protected virtual string SanitizeText(string value)
    {
        if (Text.IndexOf('-') >= 0) { return value.Replace("-", ""); }
        else {
            var str = value.Substring(0, value.IndexOf("-") + 1);
            return str + value.Substring(str.Length).Replace("-", "");
        }
    }
    protected override void OnKeyPress(KeyPressEventArgs e)
    {
        if (e.KeyChar == '-' && this.Text.IndexOf('-') >= 0) {
            e.Handled = true;
            MessageBeep(0);
        }
        else {
            base.OnKeyPress(e);
        }
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1