1

I have 4 text boxes at a Windows form. I would like to change it to only accept letters the letters a to z and nothing else, even when content is pasted in. If the user pastes in a mix of letters and unwanted characters, only the letters should show up in the textbox.

The last thing that I would like to have is the numlock pad. Those numbers are the same as the number row at a top of a keyboard, but I want to them to block them too!

Laurel
  • 5,965
  • 14
  • 31
  • 57
Donovan
  • 81
  • 10
  • http://stackoverflow.com/questions/1036870/filter-input-from-keyboard-in-textbox-c-sharp – theB Jun 05 '16 at 19:06
  • You only can filter data going into textbox when inputting from keyboard. You can't stop somebody from pasting data into the textbox. – jdweng Jun 05 '16 at 19:08
  • 1
    You can use a `MaskedTextBox` and set the [`Mask`](https://msdn.microsoft.com/en-us/library/system.windows.forms.maskedtextbox.mask(v=vs.110).aspx#Anchor_2) property to a suitable mask. – Reza Aghaei Jun 05 '16 at 20:15

4 Answers4

0

I am pretty sure there should be some syntax that looks like; var isAlpha = char.IsLetter('text'); All you need to do is implement the syntax to your textbox, as shown; var isAlpha = textbox.char.IsLetter('text');

0

In the ASCII table a-z is form 97 to 122:

string str = "a string with some CAP letters and 123numbers";
void Start(){
    string result = KeepaToz(str);
    Debug.Log(result); // print "astringwithsomelettersandnumbers"
}
string KeepaToz(string input){
   StringBuilder sb = new StringBuilder();
   foreach(char c in str){
       if(c >= 97 && c<= 122){ sb.Append(c); }
   }
   return sb.ToString();
}
Everts
  • 10,408
  • 2
  • 34
  • 45
  • I realize that I assumed it was for Unity...but the method should work just the same for any purpose. – Everts Jun 05 '16 at 19:13
0

I'd suppose to introduce a custom control derived from TextBox, by analogy with this post:

public class LettersTextBox : TextBox
{
    protected override void OnKeyPress(KeyPressEventArgs e)
    {
        base.OnKeyPress(e);

        string c = e.KeyChar.ToString();

        if (e.KeyChar >= 'a' && e.KeyChar <= 'z' || char.IsControl(e.KeyChar))
            return;

        e.Handled = true;
    }

    protected override void WndProc(ref System.Windows.Forms.Message m)
    {
        const int WM_PASTE = 0x0302;
        if (m.Msg == WM_PASTE)
        {
            string text = Clipboard.GetText();
            if (string.IsNullOrEmpty(text))
                return;

            if (text.Any(c => c < 'a' || c > 'z'))
            {
                if (text.Any(c => c >= 'a' || c <= 'z'))
                    SelectedText = new string(text.Where(c => c >= 'a' && c <= 'z').ToArray());
                return;
            }
        }
        base.WndProc(ref m);
    }
}
Community
  • 1
  • 1
stop-cran
  • 4,229
  • 2
  • 30
  • 47
  • The name 'SelectedText' does not exist in the current context? – Donovan Jun 12 '16 at 16:40
  • @Donovan that's strange. It's a property of WinForms' TextBox. – stop-cran Jun 12 '16 at 16:50
  • Idk, This is what VS says. – Donovan Jun 12 '16 at 16:59
  • @Donovan did you inherited exactly `System.Windows.Forms.TextBox`? It should have this property - https://msdn.microsoft.com/ru-ru/library/system.windows.forms.textboxbase.selectedtext(v=vs.110).aspx – stop-cran Jun 12 '16 at 17:24
  • Uhm.. where should I add this? – Donovan Jun 13 '16 at 19:30
  • @Donovan add this class into your project, build it and then you should be able to add this control from the designer toolbar on your form. – stop-cran Jun 14 '16 at 03:32
  • So, if I'm understanding this: I have to add a new class to this project, (right clikck project, add -> class. Name it and then add the line System.Windows.Forms.TextBox and paste the other code part under? – Donovan Jun 14 '16 at 09:55
  • @Donovan Yes. My code misses namespaces - this is usual. You should prepend it with all necessary `using` statements. I've asked about TextBox since it can be confused with classes from other libraries, e.g. ASP.Net. You need Windows.Forms here. – stop-cran Jun 14 '16 at 10:17
  • @Donovan remove `class Letterbox`. `LettersTextBox` class should be standalone, not nested. And it should be inherited from `System.Windows.Forms.TextBox`, not Letterbox. – stop-cran Jun 14 '16 at 13:03
  • Program does not contain a static 'Main' method suitable for an entry point when I want to run it – Donovan Jun 14 '16 at 17:54
0

Use the TextChanged event. Something like:

// Set which characters you allow here
private bool IsCharAllowed(char c)
{
    return (c >= 'a' && c <= 'z')
}    

private bool _parsingText = false;
private void textBox1_TextChanged(object sender, EventArgs e)
{
    // if we changed the text from within this event, don't do anything
    if(_parsingText) return;

    var textBox = sender as TextBox;
    if(textBox == null) return;

    // if the string contains any not allowed characters
    if(textBox.Text.Any(x => !IsCharAllowed(x))
    {        
      // make sure we don't reenter this when changing the textbox's text
      _parsingText = true;
      // create a new string with only the allowed chars
      textBox.Text = new string(textBox.Text.Where(IsCharAllowed).ToArray());         
      _parsingText = false;
    }
}

You can assign this method to each of the textboxes TextChanged events, and they will only allow them to enter what is in IsCharAllowed() (doesn't matter if via pasting, via typing, touchscreen or whatever)

Jcl
  • 27,696
  • 5
  • 61
  • 92