.NET enum.HasFlag()错误?

时间:2015-08-05 14:37:39

标签: c# .net enums flags enum-flags

我正在使用以下.NET 4.5.2代码:

if (this.ContainsFocus && keyData == (Keys.Tab|Keys.Shift))
{ ... }

当ContainsFocus(bool = true)和keyData(System.Windows.Forms.Keys)是Keys.O时,为什么表达式为true? Keys.Shift?

正如您所看到的那样,断点被击中:

breakpointscreenshot

使用此值:

watchscreenshot

此错误(?!)的解决方法是:

if (this.ContainsFocus && (int)keyData == (int)(Keys.Tab|Keys.Shift))
{ ... }

2 个答案:

答案 0 :(得分:4)

不,HasFlag没有错误。不幸的是,.NET FlagsAttribute是全有或全无,System.Windows.Forms.Keys的定义方式只有Keys.Modifiers可用作标记。

来自https://msdn.microsoft.com/en-us/library/system.windows.forms.keys%28v=vs.110%29.aspx

  

Keys类包含用于处理键盘输入的常量。该   Keys枚举的成员包含一个密钥代码和一组   修饰符组合成一个整数值。在Win32中   应用程序编程接口(API)一个键值有两半,   包含密钥代码的高位比特(与...相同)   一个Windows虚拟密钥代码),以及代表密钥的低位   修饰符,例如SHIFT,CONTROL和ALT键。

因此,您可以使用Keys.Shift检查任何修饰符(Keys.AltKeys.ControlHasFlag),但不能检查其他内容。

答案 1 :(得分:1)

这不是HasFlag的错误,它是如何运作的 假设我们有以下值:

var a = (Keys.Tab | Keys.Shift);
var b = (Keys.O | Keys.Shift);

现在我们分析这些值的位(当我们将它们转换为整数时):

  

a:1000000000100 000 1   b:1000000000100 111 1

如果我们致电a.HasFlag(b),我们会获得false,因为 b 中的每一位都不是 a 中的1位。但是,如果我们调用b.HasFlag(a),我们会得到true,因为 b 中的每个1位 a 也都设置了。

这就是为什么您需要将这些值与a==ba.HasFlag(b) && b.HasFlag(a)进行比较的原因。然后它会正常工作。