System.Windows.Forms.Keys.HasFlag行为奇怪

时间:2012-04-15 12:42:57

标签: c# .net

我有以下代码,旨在防止用户在备忘录文本编辑器中编写新行:

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枚举,但没有找到任何线索(虽然我必须说这是一个奇怪的构造枚举)。谁能解释为什么会这样呢?

3 个答案:

答案 0 :(得分:3)

HasFlags()继承自Enum.HasFlags()。它对使用[Flags]属性声明的枚举很有用。它使用&运算符对位值进行测试。麻烦的是,Keys.Enter不是标志值。其值为0x0d,设置为3位。因此,任何键具有打开位0,2或3的值将返回true。与Keys.O一样,它的值为0x4f。 0x4f& 0x0d = 0x0d因此HasFlags()返回true。

您只应将其与实际代表标志值的Keys值一起使用。它们是Keys.Alt,Keys.Control和Keys.Shift。请注意,这些是修饰符键。因此,您可以使用HasFlags来查看F和Ctrl + F之间的区别。

要检测Keys.Enter,您应该进行简单的比较。你发现了。请注意,对于Alt + Enter等,您的if()语句也是如此,这可能不是您想要的。而是使用

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

仅当没有按下任何修改键时,才会禁止Enter键。

答案 1 :(得分:0)

我怀疑它与System.Windows.Forms.Keys枚举的基础值直接映射到键盘代码有关,这些代码并不总是互斥的。文档说你不应该对它们使用任何类型的按位操作,并举例说明为什么不(Beware the FlagsAttribute on the enum!)。

MSDN还表示HasFlag函数返回此结果:thisInstance And flag = flag,因此您可以设置断点并查看进入的实际二进制代码,看看是否存在对于你列出的一组键,操作会给你一个真实的。

最后,您更新的代码是您做您想做的事情的正确方法。

答案 2 :(得分:0)

HasFlag用于标志 - 这意味着是否设置了一个位

keyvalue是一个序数值,与flags完全不同 使用比较运算符,一切都应该没问题。

某些枚举字段定义为标志,例如

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

这里使用“HasFlag”

是有意义的