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

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

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

HasFlags()inheritance自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键。

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

MSDN还说HasFlag函数返回这样的结果: thisInstance And flag = flag ,所以你可以设置一个断点并查看进来的实际二进制代码,看看那个操作是否会给你一组密钥你列出了。

最后,您更新的代码是执行您想要执行的操作的正确方法。

HasFlag用于标志 – 这意味着是否设置了位

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

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

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

在这里使用“HasFlag”是有意义的