Шестнадцатеричная Маска C# для ввода maskedtextbox

Я пытаюсь установить шестнадцатеричную маску для текстового поля. Таким образом, можно ввести только допустимые шестнадцатеричные числа. (И", " и "войдите")

Это почти работает. Пока это позволит только маленькие буквы от a-f и цифры 0-9, но я все еще могу ввести заглавные буквы GHIJKLM. (Сначала, когда программа запускается, кажется, что она принимает один символ ex k, но после того, как она исключила k, после этого она не будет показана до следующего запуска программы. Это странно.)

вот часть код:

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;
        }
    }
}

вот как я связываю событие:

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

может кто-нибудь из вас умников, посмотреть, что я делаю неправильно?

Это моя первая небольшая программа, так что полегче со мной: o)

7 ответов


это:

c <= 0x66 && c >= 61 

должно быть:

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

обратите внимание, что вы тратите драгоценное время на поиск шестнадцатеричных кодов, вы можете легко сравнить символы:

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

что касается первого символа: вы не должны связывать KeyPress на TextChanged событие - слишком поздно! Вот последовательность событий:

  1. Загрузка Формы
  2. ...
  3. пользователь нажимает на клавишу.
  4. textchanged срабатывает, изменяя текст и связывает событие.
  5. пользователь нажимает на клавишу.
  6. нажатие срабатывает.

то, что вы хотите сделать, это связать событие с самого начала. Лучшее место -Form_Load событие.
Вы также можете использовать окно Свойства для привязки события во время разработки


Если бы вы не использовали магические числа, вы бы никогда не столкнулись с этой проблемой. Перепишите if такой:

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

использовать регулярное выражение:

using System.Text.RegularExpressions;

...

if (!(Regex.IsMatch(e.KeyChar.ToString(), "^[0-9a-fA-F]+$"))
     e.Handled = true;

какой тип программы это ASP.NET веб-сайт или какой-то тип WinForms / WPF толстый клиент? Причина, по которой я спрашиваю, заключается в том, что вы можете тестировать устаревший код. В противном случае при изменении можно просто перевернуть логику проверки, чтобы быть более согласованной с тем, что вы хотите. Убедитесь,что введенный символ является одним из элементов допустимого набора. Рефакторинг находится ниже.

e.Обработано = (c >= 0x61 && c =0x41 && c= 0x30 && c

Как альтернативный подход если вы просто хотите проверить все текстовое поле за один раз, а не после каждого нажатия клавиши, вы можете просто проанализировать значение, чтобы увидеть, является ли оно числом. Следующий фрагмент кода генерирует синтаксический анализ значения 11486525 из AF453d. Если число не является допустимым шестнадцатеричным значением, то результат isHex будет 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);

зачем усложнять?

    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;
}

на основе ответа Kobi для 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");
                }
            }
        }
    }

захватывает буквы, цифры и номера клавиатуры.