0

I have a Textbox elements that I want to accept only byte values. Note that I'm pretty new to c#, so sorry if I'm missing something obvious.

so I have this piece of code

  if (!byte.TryParse(last, out num) && last.Length > 1)
        {

            System.Media.SystemSounds.Asterisk.Play();
            zBox.Text = zBox.Text.Remove(last.Length - 1);

        }

So, what I want is for users to enter only byte values there, and anything else than numbers to be ignored (deleted and sound played indicating wrong input). The piece of code that is there achieves that with the problem of the first entered value which can be a letter. If I don't use .length > 1 than I get an expection.

What would be the best way to validate if the entered value is a byte type?

Nikola L.
  • 346
  • 1
  • 4
  • 14
  • Would this be something of your help: https://stackoverflow.com/questions/5386434/gettype-and-typeof-in-c-sharp – khmub Oct 09 '17 at 08:38
  • Also somewhat related: https://stackoverflow.com/questions/1268552/how-do-i-get-a-textbox-to-only-accept-numeric-input-in-wpf – Ian H. Oct 09 '17 at 08:39
  • You require deleting an already entered character - you should consider moving your validation to happen before the value is actually changed. – user6144226 Oct 09 '17 at 09:48
  • @user6144226 I was trying to achieve that, but I was not sure how to. Any pointers? – Nikola L. Oct 09 '17 at 09:59
  • See my answer. The pointer is to handle the PreviewTextInput event and set the Cancel property of the TextCompositionEventArgs. – mm8 Oct 09 '17 at 10:14

2 Answers2

2

The problem is that you check for both conditions in your if statement, thus regardless of whether the first letter is byte or not, the checking will NOT succeed. Try something like:

byte num;
if (!byte.TryParse(last, out num))
{
    System.Media.SystemSounds.Asterisk.Play();
    if (last.Length > 1)
        zBox.Text = zBox.Text.Remove(last.Length - 1);
    else if (last.Length == 1)
        zBox.Text = "";
}

EDIT after reading comment: added else if statement

Keyur PATEL
  • 2,299
  • 1
  • 15
  • 41
  • The problem here is that if the first value entered is a letter it won't delete it. I can add somethign like zBox.Text = "" prior to the second if statements. This works with teh first letter, but entering second value and typing a letter (s for example) throws an System.ArgumentOutOfRangeException. Trying to figure out why right now. – Nikola L. Oct 09 '17 at 09:06
  • @NikolaL.Try the edited code. If entering more than 1 (incorrect) letters still gives an exception, it may be due to difference between `last` and `zBox.Text`. Lack of code before this means I cannot help you correct that. – Keyur PATEL Oct 09 '17 at 09:44
  • Well in the meantime, thinking about the different if clauses I found a solution that seems to work flawlessly. Here's the final code: https://dotnetfiddle.net/OuUGN2. Do you think it's okay? – Nikola L. Oct 09 '17 at 09:55
  • @NikolaL. Your code should work fine, but I don't understand why you need to fiddle with `SelectionStart` and `SelectionLength`, since `zBox.Text = zBox.Text.Remove(zBox.Text.Length - 1);` automatically moves the Caret when it removes the last letter/number. – Keyur PATEL Oct 10 '17 at 02:31
  • Because Remove puts the cursor at the beginning of the entry for some reason. I didn't investigate further why does it do this, Therefore I did the SelectionStart and SelectionLength to get the cursor at the end. – Nikola L. Oct 10 '17 at 08:53
  • @NikolaL. Try replacing those 2 lines with `zBox.CaretIndex = zBox.Text.Length;` and check if it works. – Keyur PATEL Oct 10 '17 at 08:58
  • this works well. Sorry I'm pretty lacking in the reading of different properties of different objects. So, CaretIndex sets the blinking text cursor to the number representing the string count from 0 to x? Thanks :-) – Nikola L. Oct 10 '17 at 09:04
  • Yes, x being the length. – Keyur PATEL Oct 10 '17 at 10:18
1

You could handle the PreviewTextInput event:

private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
    TextBox tb = sender as TextBox;
    string s = tb.Text + e.Text;
    byte b;
    if (!byte.TryParse(s, out b))
    {
        e.Handled = true;
        //play sound
        System.Media.SystemSounds.Asterisk.Play();
    }
}

You may also want to handle the paste command:

Paste Event in a WPF TextBox

mm8
  • 163,881
  • 10
  • 57
  • 88
  • Hi. Sorry I just got to check this. This works great. I understand that this is better practice, so I fully accept this solution. It was not a direct solution to the problem, but rather an improvement and therefore I find it. In the answer below Keyur Patel solution is what I originally wanted, so both solutions are good. – Nikola L. Oct 11 '17 at 14:19