ModifierKeys 按位与
ModifierKeys Bitwise AND
我正在向图表控件上的滚轮事件添加一些功能,我很好奇大多数文档中在确定按下哪个修改键时出现的按位 AND(例如 https://msdn.microsoft.com/en-us/library/yazd4ct6(v=vs.110).aspx)
void Chart_MouseWheel(object sender, MouseEventArgs e)
{
//if ((ModifierKeys & (Keys.Shift | Keys.Control)) == (Keys.Shift | Keys.Control))
if(ModifierKeys == (Keys.Shift | Keys.Control))
{
//+/- 5 chart threshold with control and shift held
Threshold += (decimal)(e.Delta / 24m / 100m);
}
//else if ((ModifierKeys & Keys.Shift) == Keys.Shift)
else if(ModifierKeys == Keys.Shift)
{
//+/- 1 chart threshold change with shift held
Threshold += (decimal)(e.Delta / 120m / 100m);
}
//else if ((ModifierKeys & Keys.Control) == Keys.Control)
else if(ModifierKeys == Keys.Control)
{
var selectedIndex = styledComboBox1.SelectedIndex;
selectedIndex += -1*(e.Delta / 120);
if (selectedIndex < 0) selectedIndex = 0;
if (selectedIndex > (styledComboBox1.Items.Count - 1)) selectedIndex = styledComboBox1.Items.Count - 1;
styledComboBox1.SelectedIndex = selectedIndex;
}
else
{
AxisMax += 0.02 * e.Delta / 120;
}
}
注释和未注释的 if/else if 行产生相同的结果,三种组合(Shift+Control、Shift、Control)中的每一种都产生了所需的效果,所以我只是想知道为什么它在未评论的场景。
此外,当我没有检查 Shift+Control 作为第一个条件时,它只会落入 Shift 块 - 这是为什么?
注释代码的工作方式与未注释代码相同,只要您不按任何其他修改键:尝试同时按 ALT,您应该注意区别。
如果您跳过第一次检查,第二次检查未注释的代码会说 "if only shift is pressed",而注释的代码会说 "if shift is pressed, no matter if other modifiers are pressed"
因此,跳过第一个检查,按 CTRL + SHIFT 不匹配您未注释的检查,但匹配注释检查
这个问题我玩得很开心,问得好!
TL;DR 按位 AND 从枚举中删除任何其他标志,以防您想要忽略它们并仅查看是否按下了您指定的键。
下面是一个控制台应用程序,它向您展示了每个操作的位,以及为什么在按 CTRL + SHIFT 时使用和不使用按位 AND 时它的工作原理相同。按位 AND 用于过滤掉任何其他修饰符:无论是否按下 ALT 或 WINDOWS,它都会将检查与 CTRL + SHIFT 进行比较。每个都有用例(您可能只想忽略 alt 键,这很好,您会在哪里使用它,或者您可能想确保它没有被按下,只有 CTRL 和 SHIFT)。
中得到的 ModifierKeys
定义
public class Program
{
[Flags]
private enum ModifierKeys
{
None = 0,
Alt = 1,
Control = 2,
Shift = 4,
Windows = 8
}
static void Main(string[] args)
{
ModifierKeys none = ModifierKeys.None;
ModifierKeys alt = ModifierKeys.Alt;
ModifierKeys control = ModifierKeys.Control;
ModifierKeys shift = ModifierKeys.Shift;
ModifierKeys windows = ModifierKeys.Windows;
ShowEnums(none, alt, control, shift, windows);
ShowAddingFlags(control, shift);
ShowBitwiseAnd(none, alt, control, shift, windows);
CompareWithShiftAndControl(alt, control, shift);
Console.ReadKey();
}
private static void ShowBitwiseAnd(params ModifierKeys[] ms)
{
List<ModifierKeys> mods = new List<ModifierKeys>();
mods.AddRange(ms);
ModifierKeys c = ModifierKeys.None;
Console.WriteLine("Adding all...");
foreach (var m in mods)
{
Console.WriteLine(GetBinaryString(m));
c = c | m;
}
Console.WriteLine(GetBinaryString(c));
Console.WriteLine(c);
Console.WriteLine();
}
private static void CompareWithShiftAndControl(params ModifierKeys[] ms)
{
var withAlt = ModifierKeys.Alt | ModifierKeys.Control | ModifierKeys.Shift;
var withoutAlt = ModifierKeys.Control | ModifierKeys.Shift;
Console.WriteLine("Using bitwise And:" );
var formatter = "{0} & {1} = {2}";
Console.WriteLine(formatter, GetBinaryString(withAlt), GetBinaryString(withoutAlt), GetBinaryString(withAlt & withoutAlt));
Console.WriteLine(formatter, withAlt, withoutAlt, withAlt & withoutAlt);
}
private static void ShowAddingFlags(params ModifierKeys[] ms)
{
List<ModifierKeys> mods = new List<ModifierKeys>();
mods.AddRange(ms);
ModifierKeys c = ModifierKeys.None;
Console.WriteLine("Adding Control and Shift...");
foreach (var m in mods)
{
Console.WriteLine(GetBinaryString(m));
c = c | m;
}
Console.WriteLine(GetBinaryString(c));
Console.WriteLine(c);
Console.WriteLine();
}
private static string GetBinaryString(ModifierKeys modifierKeys)
{
return Convert.ToString((int)modifierKeys, 2).PadLeft(8, '0');
}
private static void ShowEnums(params ModifierKeys[] ms)
{
List<ModifierKeys> mods = new List<ModifierKeys>();
mods.AddRange(ms);
foreach (var m in mods)
{
Console.WriteLine(m);
Console.WriteLine(GetBinaryString(m));
}
Console.WriteLine();
}
}
我正在向图表控件上的滚轮事件添加一些功能,我很好奇大多数文档中在确定按下哪个修改键时出现的按位 AND(例如 https://msdn.microsoft.com/en-us/library/yazd4ct6(v=vs.110).aspx)
void Chart_MouseWheel(object sender, MouseEventArgs e)
{
//if ((ModifierKeys & (Keys.Shift | Keys.Control)) == (Keys.Shift | Keys.Control))
if(ModifierKeys == (Keys.Shift | Keys.Control))
{
//+/- 5 chart threshold with control and shift held
Threshold += (decimal)(e.Delta / 24m / 100m);
}
//else if ((ModifierKeys & Keys.Shift) == Keys.Shift)
else if(ModifierKeys == Keys.Shift)
{
//+/- 1 chart threshold change with shift held
Threshold += (decimal)(e.Delta / 120m / 100m);
}
//else if ((ModifierKeys & Keys.Control) == Keys.Control)
else if(ModifierKeys == Keys.Control)
{
var selectedIndex = styledComboBox1.SelectedIndex;
selectedIndex += -1*(e.Delta / 120);
if (selectedIndex < 0) selectedIndex = 0;
if (selectedIndex > (styledComboBox1.Items.Count - 1)) selectedIndex = styledComboBox1.Items.Count - 1;
styledComboBox1.SelectedIndex = selectedIndex;
}
else
{
AxisMax += 0.02 * e.Delta / 120;
}
}
注释和未注释的 if/else if 行产生相同的结果,三种组合(Shift+Control、Shift、Control)中的每一种都产生了所需的效果,所以我只是想知道为什么它在未评论的场景。
此外,当我没有检查 Shift+Control 作为第一个条件时,它只会落入 Shift 块 - 这是为什么?
注释代码的工作方式与未注释代码相同,只要您不按任何其他修改键:尝试同时按 ALT,您应该注意区别。
如果您跳过第一次检查,第二次检查未注释的代码会说 "if only shift is pressed",而注释的代码会说 "if shift is pressed, no matter if other modifiers are pressed"
因此,跳过第一个检查,按 CTRL + SHIFT 不匹配您未注释的检查,但匹配注释检查
这个问题我玩得很开心,问得好!
TL;DR 按位 AND 从枚举中删除任何其他标志,以防您想要忽略它们并仅查看是否按下了您指定的键。
下面是一个控制台应用程序,它向您展示了每个操作的位,以及为什么在按 CTRL + SHIFT 时使用和不使用按位 AND 时它的工作原理相同。按位 AND 用于过滤掉任何其他修饰符:无论是否按下 ALT 或 WINDOWS,它都会将检查与 CTRL + SHIFT 进行比较。每个都有用例(您可能只想忽略 alt 键,这很好,您会在哪里使用它,或者您可能想确保它没有被按下,只有 CTRL 和 SHIFT)。
中得到的ModifierKeys
定义
public class Program
{
[Flags]
private enum ModifierKeys
{
None = 0,
Alt = 1,
Control = 2,
Shift = 4,
Windows = 8
}
static void Main(string[] args)
{
ModifierKeys none = ModifierKeys.None;
ModifierKeys alt = ModifierKeys.Alt;
ModifierKeys control = ModifierKeys.Control;
ModifierKeys shift = ModifierKeys.Shift;
ModifierKeys windows = ModifierKeys.Windows;
ShowEnums(none, alt, control, shift, windows);
ShowAddingFlags(control, shift);
ShowBitwiseAnd(none, alt, control, shift, windows);
CompareWithShiftAndControl(alt, control, shift);
Console.ReadKey();
}
private static void ShowBitwiseAnd(params ModifierKeys[] ms)
{
List<ModifierKeys> mods = new List<ModifierKeys>();
mods.AddRange(ms);
ModifierKeys c = ModifierKeys.None;
Console.WriteLine("Adding all...");
foreach (var m in mods)
{
Console.WriteLine(GetBinaryString(m));
c = c | m;
}
Console.WriteLine(GetBinaryString(c));
Console.WriteLine(c);
Console.WriteLine();
}
private static void CompareWithShiftAndControl(params ModifierKeys[] ms)
{
var withAlt = ModifierKeys.Alt | ModifierKeys.Control | ModifierKeys.Shift;
var withoutAlt = ModifierKeys.Control | ModifierKeys.Shift;
Console.WriteLine("Using bitwise And:" );
var formatter = "{0} & {1} = {2}";
Console.WriteLine(formatter, GetBinaryString(withAlt), GetBinaryString(withoutAlt), GetBinaryString(withAlt & withoutAlt));
Console.WriteLine(formatter, withAlt, withoutAlt, withAlt & withoutAlt);
}
private static void ShowAddingFlags(params ModifierKeys[] ms)
{
List<ModifierKeys> mods = new List<ModifierKeys>();
mods.AddRange(ms);
ModifierKeys c = ModifierKeys.None;
Console.WriteLine("Adding Control and Shift...");
foreach (var m in mods)
{
Console.WriteLine(GetBinaryString(m));
c = c | m;
}
Console.WriteLine(GetBinaryString(c));
Console.WriteLine(c);
Console.WriteLine();
}
private static string GetBinaryString(ModifierKeys modifierKeys)
{
return Convert.ToString((int)modifierKeys, 2).PadLeft(8, '0');
}
private static void ShowEnums(params ModifierKeys[] ms)
{
List<ModifierKeys> mods = new List<ModifierKeys>();
mods.AddRange(ms);
foreach (var m in mods)
{
Console.WriteLine(m);
Console.WriteLine(GetBinaryString(m));
}
Console.WriteLine();
}
}