C# Hex Mask for maskedtextbox input
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 fir开发者_JAVA技巧st, 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)
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:
- Form Loads
- ...
- User click on a key.
- TextChanged triggered, changing the text and binding the event.
- User click on a key.
- 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
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
Use a regular expression:
using System.Text.RegularExpressions;
...
if (!(Regex.IsMatch(e.KeyChar.ToString(), "^[0-9a-fA-F]+$"))
e.Handled = true;
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);
Why complicate it?
private void EnterKey(Object sender, System.Windows.Forms.KeyPressEventArgs e)
{
char c = e.KeyChar;
e.Handled = !System.Uri.IsHexDigit(e.KeyChar) && c != 0x2C;
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e) {
/* less than 0 or greater than 9, and
* less than a or greater than f, and
* less than A or greater than F, and
* not backspace, and
* not delete or decimal (which is the same key as delete). */
if (
((e.KeyChar < 48) || (e.KeyChar > 57)) &&
((e.KeyChar < 65) || (e.KeyChar > 70)) &&
((e.KeyChar < 97) || (e.KeyChar > 102)) &&
(e.KeyChar != (char)Keys.Back) &&
((e.KeyChar != (char)Keys.Delete) || (e.KeyChar == '.'))
) e.Handled = true;
}
Based on the answer by Kobi for WPF
private void EnterKey(Object sender, KeyEventArgs e)
{
Key c = e.Key;
if (!((c >= Key.A) && (c <= Key.F)))
{
if (!((c >= Key.D0) && (c <= Key.D9)))
{
if (!((c >= Key.NumPad0) && (c <= Key.NumPad9)))
{
e.Handled = true;
LogText("Handled");
}
}
}
}
Captures letters, numbers and keypad numbers.
精彩评论