tags:

views:

269

answers:

4

I'm trying to set a hex mask for a textbox. So that only valid hex numbers can be entered. (And ',' and 'ENTER')

It almost works. So far it will only allow small letters from a-f and numbers 0-9, but I can still enter capital letters GHIJKLM. (At first, when program is started it seems to accept one char ex k, but after it has excepted k once it wont be shown after that, until next time you start the program. That's weird.)

Here is a part of code:

private void EnterKey(Object sender, System.Windows.Forms.KeyPressEventArgs e)
{
    // if keychar == 13 is the same as check for if <ENTER> was pressed
    if (e.KeyChar == (char)13)
    {
        // is <ENTER> pressed, send button_click
        button1_Click(sender, e);
    }
    {
        // this will only allow valid hex values [0-9][a-f][A-F] to be entered. See ASCII table
        char c = e.KeyChar;
        if (c != '\b' && !((c <= 0x66 && c >= 61) || (c <= 0x46 && c >= 0x41) || (c >= 0x30 && c <= 0x39) || (c == 0x2c)))
        {
            e.Handled = true;
        }
    }
}

This is how I bind the event:

private void textBox1_TextChanged(object sender, EventArgs e)
{
    this.textBox1.KeyPress += new KeyPressEventHandler(textBox1_KeyDown);
}

Could anyone of you wise guys, see what I'm doing wrong?

It's my first small program, so go easy on me :o)

+3  A: 

This:

c <= 0x66 && c >= 61 

Should be:

c <= 0x66 && c >= 0x61 //hex literal

Note that you're wasting valuable time by looking up hex codes, you can easily compare characters:

if ((c >= 'a') && (c <= 'f'))

As for the first character: you shouldn't bind the KeyPress at the TextChanged event - it is too late! Here's the sequence of events:

  1. Form Loads
  2. ...
  3. User click on a key.
  4. TextChanged triggered, changing the text and binding the event.
  5. User click on a key.
  6. KeyPress triggered.

What you want to do is to bind the event right from the start. The best place is the Form_Load event.
You can also use the Properties window to bind the event at design time:

alt text

Kobi
Great. Now it works perfectly.Thank you for the help
+3  A: 

If you had not used magic numbers, you would never have run into this problem. Rewrite your if like this:

if (!(c == '\b' || ('0' <= c && c <= '9') || ('A' <= c && c <= 'F') // et cetera
Matti Virkkunen
A: 

What type of program is this an ASP.NET website or some type of winforms/wpf thick client? The reason I ask is that you may be testing on stale code. Otherwise on change can be to just flip the checking logic to be more aligned with what you want. Ensuring that the entered character is one element in the allowed set. A refactoring is below.

e.Handled = (c >= 0x61 && c <=0x66) || (c >=0x41 && c<= 0x46) || (c >= 0x30 && c <= 0x39);

As an alternative approach if you just want to validate the whole textbox at one time instead of after each key press you can just parse the value to see if it is a number. The following code fragment will generate parse the value 11486525 from AF453d. If the number is not a valid hex value then the result of isHex will be false;

int i;
string s = "AF453d";
bool isHex;
isHex = int.TryParse(s, System.Globalization.NumberStyles.AllowHexSpecifier, null, out i);
Console.WriteLine(isHex);
Console.WriteLine(i);
Tedford
The code says `System.Windows.Forms`.
Matti Virkkunen
Good point. I just glossed over that.
Tedford
+1  A: 

Use a regular expression:

if !(System.Text.RegularExpressions.Regex.IsMatch(e.KeyChar, "^[0-9a-fA-F]+$"))
     e.Handled = true;
Marcelo de Aguiar
Honestly, a Regex is too much for this problem, and suggesting a regex to a new programmer is a border-line crime `:)`
Kobi
This looks like a much better solution than the one I had.But I still have the problem when entering the first character, after the program is started. It seems to accept olmost anything, but only the first character. I thought that the problem was in my old solution due to the wasting valuable time by looking up hex codes.But when using regular expression I also see this problem.Any ideas?
I'm almost sure that this problem is not related to this solution... maybe we need a little more info to see what's happening.
Marcelo de Aguiar