Вопрос по .net, c# – System.Windows.Forms.Keys.HasFlag ведет себя странно

1

У меня есть следующий код, предназначенный для запрета пользователю писать новые строки в текстовом редакторе заметок:

private void m_commentMemoEdit_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyData.HasFlag(Keys.Enter))
    {
        e.SuppressKeyPress = true;
    }
}

Это действительно препятствует тому, чтобы Enter был вставлен, но как ни странно, это препятствует тому, чтобы другие ключи были также вставлены. До сих пор мы обнаружили, что ключи: «O», «M», «/»; и '-' также "поймали".

Обновление: следующий код делает то, что мне нужно:

private void m_commentMemoEdit_KeyDown(object sender, KeyEventArgs e)
{
  if (e.KeyValue == (int)Keys.Return)
  {
    e.SuppressKeyPress = true;
  }
}

Но я все еще не понимаю, что предыдущий код не работает, и это работает.

Я посмотрел наSystem.Windows.Forms.Keys enum, но не нашел никаких подсказок (хотя я должен сказать, что это один странно сконструированный enum). Кто-нибудь может объяснить, почему это происходит?

Ваш Ответ

3   ответа
3

ний, которые объявлены с атрибутом [Flags]. Он использует оператор & для проверки значений битов. Проблема в том, что Keys.Enter не является значением флага. Его значение 0x0d, установлены 3 бита. Таклюболавиша @, у которой есть значение с включенными битами 0, 2 или 3, вернет true. Как и Keys.O, он имеет значение 0x4f. 0x4f & 0x0d = 0x0d, поэтому HasFlags () возвращает true.

Вы должны использовать его только со значениями ключей, которые фактически представляют значения флагов. Это Keys.Alt, Keys.Control и Keys.Shift. Обратите внимание, что этомодификато ключи. Таким образом, вы можете использовать HasFlags, чтобы увидеть разницу между, скажем, F и Ctrl + F.

Чтобы обнаружить ключи. Введите простое сравнение. Как вы узнали. Обратите внимание, что ваше утверждение if () также верно для Alt + Enter и т. Д., Это может быть не то, что вам нужно. Вместо этого используйте

if (e.KeyData == Keys.Return) e.SuppressKeyPress = true;

Который подавляет клавишу Enter, только если ни одна из клавиш-модификаторов не нажата.

0

System.Windows.Forms.Keys enum отображается непосредственно на коды клавиатуры, которые не всегда являются взаимоисключающими. Документация говорит, что вы не должны использовать какие-либо побитовые операции над ними, и приводит пример, почему нет Остерегайтесь FlagsAttribute в перечислении!).

MSDN также говорит, чтоHasFlagункция @ возвращает результат этого:thisInstance And flag = flag, так что вы могли бы потенциально установить точку останова и посмотреть фактические входящие двоичные коды и посмотреть, даст ли эта операция истинное значение для набора ключей, которые вы перечислили.

В конце концов, ваш обновленный код - верный способ делать то, что вы хотите.

0

keyvalue - порядковое значение, поэтому в отличие от флагов используется оператор сравнения, и все должно быть в порядке.

Некоторые поля перечисления определяются как флаги, например,

enum SomeFlag
{
   BitOne = 1, 
   BitTwo = 2, 
   Bitthree = 4
};

здесь имеет смысл использовать "HasFlag"

Похожие вопросы